如何将带spring-boot-docker-compose的Spring Boot应用部署到生产环境
优雅容器化Spring Boot应用环境的解决方案
问题场景
开发Spring Boot 3.2.1应用时,借助spring-boot-docker-compose能快速拉起MongoDB等依赖服务,开发体验流畅。但要实现生产环境一键部署(用户拉取源码后用docker-compose构建运行整个环境)时,遇到了核心问题:容器内运行的Spring Boot会尝试启动Docker,导致逻辑冲突。
核心原因
spring-boot-docker-compose依赖默认会在应用启动时自动检测并管理Docker容器,当应用本身运行在Docker容器内部时,这个逻辑会触发容器内尝试启动Docker的不合理行为。
优雅解决方案
不需要引入Maven Profile,通过外部化配置+Docker多阶段构建就能解决问题:
1. 禁用容器内的spring-boot-docker-compose自动启动
通过环境变量在生产容器中动态关闭该功能,完全符合Spring Boot外部化配置的设计原则,无需修改代码或pom.xml:
在full-compose.yaml的app服务中添加环境变量:
environment: # ... 原有配置保留 SPRING_DOCKER_COMPOSE_ENABLED: "false"
2. 优化Dockerfile为多阶段构建
原Dockerfile使用Maven镜像直接运行应用,不仅镜像体积大,还携带了不必要的构建环境。改用多阶段构建,先在Maven镜像中构建可执行Jar,再用轻量的JRE镜像运行:
# 第一阶段:构建Jar包 FROM maven:3.8.5-openjdk-17 AS builder WORKDIR /callback-mock COPY . . COPY .mvn/settings.xml /usr/share/maven/conf/ # 跳过测试加快构建,生产环境可根据需要调整 RUN mvn clean package -DskipTests # 第二阶段:运行应用 FROM openjdk:17-jdk-slim WORKDIR /app # 从构建阶段复制Jar包 COPY --from=builder /callback-mock/target/*.jar app.jar # 启动应用 CMD ["java", "-jar", "app.jar"]
3. 修正docker-compose配置细节
- 移除
app服务中不必要的.m2卷挂载(多阶段构建已在builder阶段完成依赖下载,运行阶段无需本地Maven仓库) - 修正
mongo-express的数据库连接URL:容器间通信应使用Docker内部端口${MONGODB_DOCKER_PORT},而非宿主映射端口${MONGODB_LOCAL_PORT}
调整后的full-compose.yaml关键片段:
services: mongo: # ... 原有配置不变 mongo-express: # ... 原有配置不变 environment: ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGODB_USER} ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGODB_PASSWORD} # 修正为容器内部端口 ME_CONFIG_MONGODB_URL: mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@mongo:${MONGODB_DOCKER_PORT}/ app: depends_on: - mongo build: ./ restart: on-failure env_file: ./.env ports: - ${SPRING_LOCAL_PORT}:${SPRING_DOCKER_PORT} environment: SPRING_APPLICATION_JSON: '{ "spring.data.mongodb.uri" : "mongodb://$MONGODB_USER:$MONGODB_PASSWORD@mongo:$MONGODB_DOCKER_PORT/", "spring.data.mongodb.database" : "kcm" }' SPRING_DOCKER_COMPOSE_ENABLED: "false" stdin_open: true tty: true
方案优势
- 零代码侵入:无需修改pom.xml或添加Profile,通过环境变量实现开发/生产环境的配置隔离
- 镜像轻量化:多阶段构建大幅减少生产镜像体积,提升运行效率
- 配置规范:遵循Docker容器间通信的最佳实践,避免端口映射错误
内容的提问来源于stack exchange,提问作者hizr
相关产品推荐
相关产品推荐

