系列:
spring-boot使用maven构建docker镜像(单服务)
spring-boot使用maven构建docker镜像(单服务+MySQL)
spring-boot使用maven构建docker镜像(多服务)
文章目录
多服务 构建docker镜像 + 运行
使用Dockerfile构建镜像,使用docker-compose.yml定义多个容器的启动参数
前提:
- 开启docker远程管理端口(此案例演示暂不考虑安全问题,直接开启2375端口)
参考链接:[…]
示例项目
项目模拟一般的分布式项目,有多个服务(用户服务、订单服务)还有数据库(MySQL)。
项目结构
实现方式
分别构建每个服务的镜像,通过统一管理模块(或父模块)编写docker-compose.yml管理多个服务容器的启停。
正文
1. 编写每个服务的 Dockerfile(基本相同)
Dockerfile官方文档:https://docs.docker.com/engine/reference/builder/
FROM openjdk:8-jdk-alpine
ADD *.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Duser.timezone=GMT+08", "-jar", "/app.jar"]
2. 每个服务的 pom.xml 引入 io.fabric8/docker-maven-plugin 插件(基本相同)
io.fabric8/docker-maven-plugin官方文档:http://dmp.fabric8.io/
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.33.0</version>
<configuration>
<verbose>true</verbose>
<!-- docker远程管理url -->
<dockerHost>tcp://192.168.121.129:2375</dockerHost>
<images>
<image>
<!-- 镜像名称 -->
<name>${project.artifactId}:${project.version}</name>
<build>
<!-- 使用Dockerfile定义镜像构建流程 -->
<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
<assembly>
<name>/</name>
<!-- artifact是预定义的值,表示将项目打包后的jar拷贝到编译上下文中,便于Dockerfile ADD指令 -->
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
</plugin>
3. 新增一个模块(或用父模块)用来统一管理容器启停,编写 docker-compose.yml
Compose file官方文档:https://docs.docker.com/compose/compose-file/
version: "2"
services:
database:
image: mysql:5.7
ports:
- 3306:3306
volumes:
- /home/mysqldata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test-db #默认创建数据库名
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] #指定MySQL的编码(覆盖CMD指令)
networks:
my-custom-network:
aliases:
- mysql-server #在同个网络的其他服务可以通过此别名访问此服务
user-service:
image: user-service:1.0.0
ports:
- 8081:8080
environment:
MYSQL_SERVER: mysql-server:3306 #在同个网络,可以通过服务名/别名访问
depends_on:
- database
networks:
my-custom-network:
aliases:
- user-service
order-service:
image: order-service:1.0.0
ports:
- 8082:8080
environment:
MYSQL_SERVER: mysql-server:3306 #在同个网络,可以通过服务名/别名访问
USER_SERVICE: user-service:8081 #在同个网络,可以通过服务名/别名访问
depends_on:
- database
- user-service
networks:
my-custom-network:
aliases:
- order-service
networks:
my-custom-network:
driver: overlay
4. maven 命令
- 构建镜像
mvn clean package docker:build
- 删除镜像
mvn docker:remove
- 启动容器
mvn docker:run
- 停止容器(自动删除容器)
mvn docker:stop
4.1 一般流程
- 在每个服务中执行构建镜像命令
mvn clean package docker:build
- 在同一管理模块启动所有服务:
mvn docker:run
- 在同一管理模块停止所有服务:
mvn docker:stop
要点说明
- 数据库是由MySQL容器拉起时自动创建的。(MYSQL_DATABASE环境变量)
- 数据库初始化是由Spring框架自动执行SQL脚本功能完成的。(spring.datasource.initialization-mode属性)
后期维护需求
当项目第一次构建镜像运行时,按照上面的流程基本没什么问题。但是,当第二次构建镜像时,可能会有以下需求。
更新项目时,不想销毁MySQL容器,使用已有历史数据
默认情况下,docker:stop,docker:run会操作所有在docker-compose.yml定义的服务。
所以,我们只需要将docker-compose.yml里关于MySQL服务的配置注释掉,这样就不会重新拉起或关闭MySQL容器。(可能还需要将其他服务的 depends_on 注释掉)
version: "2"
services:
# database:
# image: mysql:5.7
# ports:
# - 3306:3306
# volumes:
# - /home/mysqldata:/var/lib/mysql
# environment:
# MYSQL_ROOT_PASSWORD: root
# MYSQL_DATABASE: test-db #默认创建数据库名
# command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] #指定MySQL的编码(覆盖CMD指令)
# networks:
# my-custom-network:
# aliases:
# - mysql-server #在同个网络的其他服务可以通过此别名访问此服务
省略...
还有一点要注意,上文’关键要点’提到,数据库初始化是由Spring框架完成的,所以如果想保留MySQL的历史数据,则要把自动初始化SQL脚本功能关闭。
(设置spring.datasource.initialization-mode = never)
常见问题
2375 端口不通问题排查
- 是否开启docker远程访问(lsof -i 2375)
- 是否关闭防火墙(systemctl status firewalld)
- systemct stop firewalld && systemct disable firewalld //关闭&禁用防火墙
注
使用插件引用docker-compose.yml文件启动容器的方式和直接使用命令引用docker-compose.yml启动容器是不一样的。
docker swarm init
docker stack deploy -c docker-compose.yml stack-demo
reference:
Docker Compose是什么?
Docker Compose https://docs.docker.com/compose/
Docker Swarm https://docs.docker.com/engine/swarm/