如何实现每次运行docker compose时自动打包Maven jar并构建镜像?
解决方案
1. 重构Dockerfile,内置Maven打包逻辑(多阶段构建)
通过多阶段构建可以将手动执行Maven打包的步骤集成到镜像构建流程中,同时优化镜像层缓存提升构建速度。两个模块的Dockerfile可以统一使用如下模板,仅需对应修改MODULE_NAME参数即可:
# 第一阶段:Maven构建阶段,负责打包应用 FROM maven:3.8-openjdk-11 AS builder ARG MODULE_NAME # 工作目录设为项目根目录 WORKDIR /app # 先拷贝父pom和所有模块的pom文件,缓存依赖层 COPY pom.xml . COPY ${MODULE_NAME}/pom.xml ./${MODULE_NAME}/ # 预下载依赖,只要pom文件无变更就不会重复执行该步骤 RUN mvn dependency:go-offline -pl ${MODULE_NAME} -am # 拷贝全量源代码 COPY . . # 打包指定模块,可根据需求决定是否保留跳过测试参数 RUN mvn package -pl ${MODULE_NAME} -am -DskipTests # 第二阶段:运行时镜像,保留你原有配置逻辑 FROM adoptopenjdk:11-jre-hotspot MAINTAINER my name here lol ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait RUN chmod +x /wait ARG MODULE_NAME # 从构建阶段拷贝生成的jar包,统一命名避免写死版本号 COPY --from=builder /app/${MODULE_NAME}/target/*-jar-with-dependencies.jar /app.jar # 调整启动命令,保留wait工具逻辑,修复原配置中ENTRYPOINT和CMD冲突问题 CMD ["/bin/sh", "-c", "/wait && java -jar /app.jar"]
2. 调整docker-compose.yml配置
核心优化点为统一网络、通过构建参数传递模块名、删除冗余配置,调整后配置如下:
version: '2.1' services: application1: container_name: app1 build: # context设为多模块项目根目录,确保可以读取父pom和所有模块代码 context: ./ # 指定对应模块的Dockerfile路径 dockerfile: ./app1/Dockerfile args: MODULE_NAME: app1 image: docker.io/myname/app1:latest hostname: app1 ports: - "8080:8080" # 两个服务共用同一网络,无需额外配置links即可通过服务名通信 networks: - spring-cloud-network application2: container_name: app2 build: context: ./ dockerfile: ./app2/Dockerfile args: MODULE_NAME: app2 depends_on: application1: condition: service_started image: docker.io/myname/app2:latest environment: WAIT_HOSTS: application1:8080 ports: - "8070:8070" networks: - spring-cloud-network networks: spring-cloud-network: driver: bridge
注意:请根据你实际的项目目录结构调整context和dockerfile的路径,上述配置默认docker-compose.yml存放在多模块项目根目录下。
3. 最终使用流程
调整完成后,每次修改代码后仅需执行以下一条命令即可完成全部构建、部署流程:
docker-compose up --build
无需再手动执行mvn package、单独docker build的冗余步骤,docker compose会自动触发镜像构建,镜像构建过程中会自动完成代码打包的全部操作。
内容的提问来源于stack exchange,提问作者AlexKL
相关产品推荐
相关产品推荐

