Docker Compose部署Spring Cloud微服务项目
背景:使用Docker Compose部署一套Spring Cloud微服务项目,要求只对外暴露网关服务的端口,通过网关服务通过容器内部网络访问其它的微服务
- mina-gateway:网关服务,8080端口(外部可以访问)
- mina-cloud-system:后台管理服务,9090端口
- mina-cloud-infra:基础设施服务,9080端口
思路:每个服务都打包成一个镜像,再用Docker Compose定义并启用多个容器
环境:
- JDK 17
- SpringBoot 3
- Gradle 7.6.1
- IntelliJ IDEA 2023.2.3
- 外部依赖:MySQL、Redis、Nacos
一、编写各个服务的Dockerfile
下面以mina-gateway为例
# 使用一个基础镜像作为起点,通常是包含Java运行时环境的镜像
FROM springci/graalvm-ce:java17-0.12.x
# 设置工作目录
WORKDIR /app
# 复制编译后的Spring Boot JAR文件到容器中
COPY mina-gateway-0.0.1-SNAPSHOT.jar /app/app.jar
# 复制配置文件到容器中
COPY config /app/
# 暴露应用程序运行的端口
EXPOSE 8080
# 启动Spring Boot应用程序
CMD ["java", "-jar", "app.jar"]
二、打包各个服务为JAR包
下面以mina-gateway为例
使用gradle
./gradlew clean bootJar
使用maven
mvn clean package
三、配置各个服务的Docker目录结构
这一步只是为了方便管理,才把所有与docker部署相关的东西放在了同一个地方
下面以mina-gateway为例
将Dockerfile、打包好的jar包、以及配置文件都放在服务根目录的docker目录下,其中,配置文件放在config目录下(根据自己项目的配置来决定)
这里的配置文件用的是bootstrap.yml是因为本项目用了配置中心,如果没有使用配置中心,就是application.yml
四、编写docker-compose.yml
version: '1'
services:
# mina-gateway:后台管理服务
mina-gateway:
build:
# 这里配置Dockerfile所在的目录,也就是步骤三中准备的docker目录,等同于docker build中的 ./mina-gateway/docker
context: ./mina-gateway/docker
# 配置镜像名称,等同于docker build中的 -t mina-gateway:latest
image: mina-gateway
# 配置容器名称,等同于docker run中的 --name mina-gateway
container_name: mina-gateway
# 配置容器对外暴露的端口,等同于docker run中的 -p 8080:8080
ports:
- "8080:8080"
# 配置网络,等同与docker run中的 --network mina-cloud-network
networks:
- mina-cloud-network
# mina-cloud-system:后台管理服务
mina-cloud-system:
build:
context: ./mina-cloud-system/docker
image: mina-cloud-system
container_name: mina-cloud-system
networks:
- mina-cloud-network
# mina-cloud-infra:基础设施服务
mina-cloud-infra:
build:
context: ./mina-cloud-infra/docker
image: mina-cloud-infra
container_name: mina-cloud-infra
networks:
- mina-cloud-network
# 定义网络
networks:
mina-cloud-network:
driver: bridge
并且把docker-compose.yml放在最外层目录,如下
五、启动容器
在docker-compose.yaml文件所在的目录下,执行容器启动命令
docker-compose up -d
启动成功
总结及注意事项
- 之所以采取只暴露一个网关端口的方法是为了模拟内网隔离,也就是说业务服务不暴露在公网,所有服务都需要走网关访问
- 使用docker-compose只是为了部署简化,不用docker-compose只用docker run也是能达到同样效果的
- 是否可以用 spring navtive + graalvm 简化上述步骤还在研究中,目前实践下来发现,spring navtive + graalvm 似乎没有什么优势
- 本文没有细说的一些东西,比如build.gradle配置、nacos注册中心、nacos配置中心等,可以私信笔者交流