微同商城docker部署指南
微同商城docker部署指南
概述
通过docker部署应用和微服务是目前的主流,本教程根据作者部署微同商城的亲身实践进行编写。如果您初次接触docker,可能会觉得这样部署比较麻烦,因为需要了解container(容器)、image(镜像)、dockerfile、docker-compose等概念。可以先放下这些概念,直接按本教程的描述进行部署。通过体验之后,会发docker部署应用的好处很多,再进行docker系统的学习。 注意:本教程是基于albaba cloud linux 3 云服务器环境,centos7 通用。
1. 云服务器安装docker
通过ssh登陆云服务器,推荐终端神器mobaxterm(谁用谁说好)。shell环境直接输入下面的命令进行安装:
# 1、yum 包更新到最新
yum update
# 2、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
# 3、 设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4、 安装docker,出现输入的界面都按 y
yum install -y docker-ce
# 5、 查看docker版本,验证是否验证成功
docker -v
2. 启动docker服务,并设置开机启动
直接复制,shell环境直接输入下面的命令:
systemctl start docker
systemctl enable docker
3. docker镜像加速设置(本步骤可以省略!)
注册一个属于自己的阿里云账户(可复用淘宝账号),用支付宝扫码登陆阿里云。找到“容器镜像服务”->“镜像工具”->“镜像加速器”,然后看到自己独立的镜像加速地址和centos操作文档。根据操作文档,复制到shell进行粘贴就行。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://'你自己的加速地址,不要直接复制'.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
4. 使用docker拉取nginx、Redis、mysql镜像
直接复制,shell环境直接输入下面的命令:
docker pull mysql:5.7 # 5.7 是指定版本号
docker pull redis:5.0 # 5.0 是指定版本号
docker pull nginx # 这里没写版本号,意思是拉取最新的版本
docker images # 查看本机所有镜像
5. 使用docker相关命令操作container(本步骤可以省略!主要是熟悉一下container的相关操作)
5.1. 使用docker run命令命令建立并运行container
由于我们已经获取了mysql的镜像,可以用docker run
命令启动一下服务进行初步的体验。补充一下概念,可以把image(镜像)类比为java的类文件,container(容器)理解为对象,而docker run命令为new关键字。每一个container(容器)都是一个微小的虚拟机,有自己的网络地址和端口。这里以nginx和mysql为例。shell环境直接输入下面的命令:
### 运行nginx
docker run --name c_nginx -p 80:80 -d nginx #用nginx镜像启动名字为 c_nginx 容器实例后台运行(-d),并且把本机(宿主机)的80端口(-p)映射到c_nginx容器的80端口
### 下面来个稍微复杂点的
docker run -d \
-p 3306:3306 \
--name=c_mysql \
-v ~/mysql/conf:/etc/mysql/conf.d \
-v ~/mysql/logs:/logs \
-v ~/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--privileged=true mysql:5.7
上面复杂命令的解释:
docker run -d \
-p 3306:3306 \
--name=c\_mysql \
-~/mysql/conf:/etc/mysql/conf.d \ # 这里的 -v 意思是挂载(共享)宿主机的 ~/mysql/conf 文件夹作为c\_mysql容器的/etc/mysql/conf.d
-~/mysql/logs\:/logs \ # 用以实现文件同步和保存。因为容器如果被删除掉,宿主机还保存着相应的数据
-v ~/mysql/data:/var/lib/mysql \
-e MYSQL\_ROOT\_PASSWORD=123456 \ # 设置root密码
--privileged=true mysql:5.7 # --privileged=true 设置容器的文件权限。注意这里的镜像mysql:5.7和拉取的镜像一致,使用了版本号。
可以通过docker COMMAND --help
命令自行学习,例如:docker run --help
5.2. 使用docker exec命令命令进入container
docker exec -it c_nginx /bin/bash # 进入刚才建立的c_nginx容器
docker exec -it c_mysql /bin/bash # 进入刚才建立的c_mysql容器
可以通过docker exec --help
自行了解-it
的参数作用。
5.3. 其它常用docker操作container的命令
docker ps -a # 查看所有容器。-a 意思是包括已经停止的容器。
docker stop c_nginx # 停止c_nginx容器
docker start c_nginx # 运行c_nginx容器
docker restart c_nginx # 重新运行c_nginx容器
docker logs 4358e2ad63d5 # 4358e2ad63d5 为 c_nginx容器的id。docker ps 命令可以看到。
docker inspect 4358e2ad63d5 # 查看容器的详细信息
docker cp c_nginx:/etc/nginx/ ~/nginx/conf/ # 从c_nginx容器里面复制文件到宿主机
6. 准备 nginx container 的运行环境
nginx需要特别对待一下。这个步骤的主要目的是从一个临时容器里面获取nginx的配置文件。
mkdir ~/mall-app/nginx -p
# 1. 先建立一个临时nginx容器
docker run --name c_nginx -p 80:80 -d nginx
# 2.
#复制临时nginx容器的文件到主机
docker cp c_nginx:/etc/nginx/ ~/mall-app/nginx/conf/
docker cp c_nginx:/usr/share/nginx/html/ ~/mall-app/nginx/html/
docker cp c_nginx:/var/log/nginx/ ~/mall-app/nginx/logs
# 3.
docker rm -f "nginx容器id" # docker ps 命令可以得到nginx容器id
这样操作之后就在~/mall-app/nginx
文件夹里面保存了一个完整的nginx服务相关的文件。为什么多此一举?因为在接下来通过docker-compse批量启动容器的时候,会把nginx container的/etc/nginx
目录挂载为宿主机的~/mall-app/nginx/conf
。这时如果宿主机的~/mall-app/nginx/conf
文件夹是空的,会覆盖掉c_nginx:/etc/nginx
,造成nginx 容器启动失败。当然也有其它解决办法,个人比较喜欢这样做。
7. 修改微同商城的生产环境配置,并进行打包
由于在docker环境下商城的jar包
、nginx
、mysql
、Redis
都是以微服务的方式运行(就是在独立的container里面运行),每个container有独立的ip地址,并且不是固定的,因此在相应的配置文件中用到ip地址的地方就要改成服务名称!这点非常重要!
7.1. 修改platform-admin模块的application.yml和application-prod.yml
application.yml文件按照下面进行修改:
server:
port: 8088 # 原先为8888我改成了8088
redis:
database: 0
# host: 127.0.0.1
host: redis
port: 6379
# 密码(默认为空)
password:
# 连接超时时长(毫秒)
timeout: 6000ms
application-prod.yml文件按照下面进行修改:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
primary: master # 设置默认的数据源或者数据源组,默认值即为 master
datasource:
master:
url: jdbc:mysql://mysql:3306/platform-plus?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driverClassName: com.mysql.cj.jdbc.Driver
second:
url: jdbc:mysql://mysql:3306/platform-plus?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driverClassName: com.mysql.cj.jdbc.Driver
这样修改之后,原来配置文件中的localhost
或者127.0.0.1
就改成了服务名称mysql
和redis
。为什么是这个两个指定的名称?因为在后面的步骤的编写docker-compose
文件时候会对服务名称mysql
和redis
进行定义。
7.2. 修改platform-api模块的application.yml和application-prod.yml
过程和7.2的一样,修改两个配置文件的同样位置。但是在application.yml
文件中我进行了端口修改:server: port: 8089
。
7.3. 打包
在项目根目录执行下面命令: mvn package -Pprod
等待打包完成,找到platform-admin.jar
和platform-api.jar
这两个文件。
8. 编写两个dockerfile文件生成两个镜像
通过dockerfile
可以自定义镜像。在第上面使用docker
拉取nginx
、Redis
、mysql
的步骤中,拉取的镜像都是官方已有的。想要定义自己的微服务镜像,就需要先编写dockerfile
。 先建立一个工作目录:
mkdir ~/mall-docker
把platform-admin.jar
和platform-api.jar
这两个文件上传到云服务的这个目录,然后分别编写platform-admin-dockfile
和platform-api-dockfile
文件。
FROM openjdk:8
ADD platform-admin.jar platform-admin.jar
CMD java -jar platform-admin.jar
EXPOSE 8088
FROM openjdk:8
MAINTAINER tonygee <253106788@qq.com>
ADD platform-api.jar platform-api.jar
CMD java -jar platform-api.jar
EXPOSE 8089
编写完dockerfile
就可以在当前文件夹下用命令docker build -f ./platform-admin-dockfile -t platform-admin_img .
生成自定义镜像了。这里我们直接跳过这一步,因为可以在下面的docker-compose
文件中直接用脚本生成镜像,并直接运行容器。
9. 编写docker-compose文件启动所有服务
本教程的核心就是下面这个docker-compose.yml
文件!在~/mall-docker
的目录下新建docker-compose.yml
文件,并把下面的代码复制并保存。注意,这里文件名必须为docker-compose.yml
。还需注意的是在下面的配置中我们定义了两个服务mall-admin
和mall-api
,千万不要使用下划线这样定义为mall_dmin
和mall_api
。这里有个很大的坑一会再说!
version: "3"
services:
nginx:
image: nginx
container_name: c_nginx
ports:
- 80:80
- 8012:8012
# - 8088:8088
# - 8089:8089
# links:
# - mall_app
volumes:
- ~/mall_app/nginx/conf/:/etc/nginx/
- ~/mall_app/nginx/html/:/usr/share/nginx/html/
- ~/mall_app/nginx/logs:/var/log/nginx/
networks:
- mall_app_net
depends_on:
- mall-admin
- mall-api
mall-admin:
image: mall-admin-img
build:
context: ./
dockerfile: platform-admin-dockfile
container_name: c_mall_admin
ports:
- "8088:8088"
# volumes:
# - ~/mall_app/app/data:/data
networks:
- mall_app_net
depends_on:
- redis
- mysql
mall-api:
image: mall-api-img
build:
context: ./
dockerfile: platform-api-dockfile
container_name: c_mall_api
ports:
- "8089:8089"
# volumes:
# - ~/mall_app/app/data:/data
networks:
- mall_app_net
depends_on:
- redis
- mysql
redis:
image: redis:5.0
container_name: c_redis_app
ports:
- "6379:6379"
volumes:
- ~/mall_app/redis/redis.conf:/etc/redis/redis.conf
- ~/mall_app/redis/data:/data
networks:
- mall_app_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
container_name: c_mysql_5_7_app
environment:
MYSQL_ROOT_PASSWORD: '123456'
ports:
- "3306:3306"
volumes:
- ~/mall_app/mysql/data:/var/lib/mysql
- ~/mall_app/mysql/conf:/etc/mysql/conf.d
- ~/mall_app/mysql/logs:/logs
networks:
- mall_app_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
mall_app_net:
这时~/mall-docker
的目录结构如下:
~/mall-docker
├── docker-compose.yml
├── platform-admin-dockfile
├── platform-admin.jar
├── platform-api-dockfile
└── platform-api.jar
最后cd ~/mall-docker
目录,执行docker-compose up -d
,观察控制台输出的日志。如果没有什么问题,使用docker ps -a
看一下5个服务是否启动。
10. 设置mysql配置文件,并导入sql脚本生成数据库数据
先编写一下mysql
的配置文件。由于在上面的docker-compose.yml
文件中定义mysql
服务的时候有这一行- ~/mall_app/mysql/conf:/etc/mysql/conf.d
,我们只需输入下面命令即可:
cd ~/mall_app/mysql/conf
vi my.cnf # 把下面的配置复制过来就行
[client]
default_character_set=utf8
host = localhost
user = root
password = 123456
#database = test
[mysqld]
character_set_server=utf8
collation_server=utf8_general_ci
#port = 3306
[mysql]
default_character_set=utf8
docker restart 7f13f2cf0821 # 7f13f2cf0821为mysql容器的id。docker ps 命令可以看到。
# docker logs 7f13f2cf0821 # 如果启动失败,通过该命令查看日志
注意:这里的文件名为my.cnf
,不要写成my.ini
;里面的类似default_character_set=utf8
的配置不要写成default-character-set=utf8
,都是踩过的坑和教训,说多了都是泪! 然后通过sftp把微同商城的两个sql脚本platform-mall-MySQL.sql
、platform-mall-MySQL.sql-activiti.sql
也上传到~/mall_app/mysql/conf
目录。继续输入命令:
docker exec -it 7f13f2cf0821 /bin/bash
进入mysql容器后,输入mysql
直接进入数据库的shell。为什么不需要用mysql -uroot -p
输入密码?因为我们在刚才的my.cnf
中已经进行了配置。 然后在mysql的shell环境下执行下面命令:
create database `platform-plus`;
use platform-plus;
source /etc/mysql/conf.d/platform-mall-MySQL.sql;
source /etc/mysql/conf.d/platform-mall-MySQL.sql-activiti.sql;
11. 编写nginx的配置文件,进行端口映射
同样由于在上面的docker-compose.yml
文件中定义nginx
服务的时候有这一行- ~/mall_app/nginx/conf/:/etc/nginx/
, 我们只需在宿主机上面:
cd ~/mall_app/nginx/conf/conf.d/
mv default.conf default.conf_bak
vim mall.conf
把下面的配置内容保存到mall.conf
:
server {
listen 80;
#server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /platform-admin {
proxy_pass http://mall-admin:8088;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /platform-api {
proxy_pass http://mall-api:8089;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
然后用docker restart "nginx容器的id"
命令重启服务,并用curl根据情况进行测试。因为在写本教程的时候,域名还没申请好所以在上面的配置中还没有进行域名的相关配置。特别需要注意的是proxy_pass http://mall-admin:8088
一定不要写成proxy_pass http://mall_admin:8088
,否则nginx代理的时候会出错!这也是在“9 编写docker-compose文件启动所有服务 ”步骤中定义服务名称千万不要用下划线的原因!还是那句话,说多了都是泪。
docker restart e7acb5e9aec8
curl localhost # 现在还没部署管理后台的前端,这里现在应该是打印nginx主页的信息
curl curl localhost/platform-api/doc.html # 正常应该打印微同商城swagger首页的html代码
12. 打包前端,静态部署到nginx
用vscode
打开platform-admin-ui
文件夹,然后进行下面的操作: 修改文件:
/static/config/index-prod.js文件
window.SITE_CONFIG['baseUrl'] = 'http://你的域名/platform-admin' // 后台接口请求地址
//如果使用第三方文件存储,将dist/1907180922 上传至第三方文件存储,然后填写cdn地址
window.SITE_CONFIG['domain'] = '静态资源cdn地址';
执行命令:
npm install
# 构建生产环境
npm run build
先备份一下~/mall_app/nginx/html
目录里面原有的文件,然后把platform-admin-ui
->dist
目录下的所有文件上传到~/mall_app/nginx/html
。~/mall_app/nginx/html
目录最终为下面这个样子:
[root@iZuf63zu4bo54nzzdqs9akZ html]# ls
2210241102 50x.html_bak config index.html index.html_bak
进行测试,看一下是否能访问管理后台的页面
curl localhost # 这里现在应该是打印”微同软件管理平台”信息
自此微同商城服务docker部署基本完成!
13. 服务测试
- 浏览器输入:
http://"你的域名或者ip"/platform-api/doc.html
访问swagger文档 - 浏览器输入:
http://"你的域名或者ip"
访问管理后台首页。默认用户名 admin,密码:888888。