一、Dockerfile编写:别让“基础镜像”毁了你的部署
陷阱1:盲目选择最新镜像
话术:“用openjdk:latest,永远保持最新版本!”
真相:latest标签会自动指向最新版本,可能与项目JDK版本冲突(如Spring Boot 2.7要求JDK 11,而latest可能是JDK 17)。
正确姿势
选择固定版本的轻量级镜像:
dockerfile
# 基础镜像:JDK 11 + 精简Linux系统,比openjdk:11体积小50% FROM openjdk:11-jre-slim避免使用
latest,明确指定版本号(如openjdk:11-jre-slim而非openjdk:slim)。
二、镜像构建:多阶段构建让镜像“瘦”下来
陷阱2:把构建环境也打包进镜像
问题:直接在Dockerfile中用mvn package构建项目,会把Maven、源码等无关文件都打包进去,导致镜像体积从200MB膨胀到1.5GB。
解决方案:多阶段构建
dockerfile
# 阶段1:构建JAR包(仅保留编译产物) FROM maven:3.8.5-openjdk-11 AS builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests # 阶段2:运行环境(仅包含JRE和JAR包) FROM openjdk:11-jre-slim WORKDIR /app # 从构建阶段复制JAR包 COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 CMD ["java", "-jar", "app.jar"]
效果对比
| 构建方式 | 镜像体积 | 构建时间 |
|---|---|---|
| 单阶段构建 | 1.5GB | 12分钟 |
| 多阶段构建 | 280MB | 8分钟 |
三、容器运行:端口映射与环境变量的“坑”
陷阱3:端口映射冲突
错误命令:docker run -d -p 8080:8080 myapp
问题:如果宿主机8080端口已被占用,容器会启动失败,但错误日志可能不明显。
正确操作
- 启动前检查端口占用:
netstat -tuln | grep 8080(Linux)或netstat -ano | findstr :8080(Windows); - 映射到随机端口,避免冲突:
bash
docker run -d -p 0:8080 myapp # 宿主机随机分配端口,用docker ps查看实际映射
陷阱4:环境变量配置无效
场景:在Dockerfile中用ENV设置SPRING_PROFILES_ACTIVE=prod,但应用仍加载默认配置。
原因:Spring Boot优先读取运行时环境变量,Dockerfile中的ENV可被docker run -e覆盖。
正确传递环境变量
bash
# 运行时指定环境变量,优先级高于Dockerfile docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=prod" myapp
四、容器健康检查:别让“假活”容器欺骗你
陷阱5:容器启动≠应用可用
问题:docker ps显示容器“Up 5 seconds”,但应用还在初始化(如数据库连接耗时10秒),此时访问会返回503错误。
解决方案:添加健康检查
dockerfile
FROM openjdk:11-jre-slim WORKDIR /app COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 # 健康检查:每10秒访问/actuator/health,3次失败则标记容器不健康 HEALTHCHECK --interval=10s --timeout=3s --retries=3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1 CMD ["java", "-jar", "app.jar"]
配合Spring Boot配置
在application.yml中开启健康检查端点:
yaml
management: endpoints: web: exposure: include: health # 暴露/actuator/health端点 endpoint: health: show-details: always # 显示详细健康信息
五、生产环境部署:别让“数据丢失”毁了你的服务
陷阱6:容器内存储数据
问题:把日志、上传文件保存在容器内,容器重启后数据全部丢失。
正确方案:挂载宿主机目录
bash
# 挂载日志目录和配置文件 docker run -d -p 8080:8080 \ -v /opt/logs:/app/logs \ # 日志持久化到宿主机 -v /opt/config:/app/config \ # 外部配置文件覆盖容器内配置 myapp
六、避坑清单:Spring Boot容器化检查列表
| 检查项 | 正确做法 | 错误案例 |
|---|---|---|
| 基础镜像 | openjdk:11-jre-slim | openjdk:latest、openjdk:11 |
| 镜像构建 | 多阶段构建(builder + runner) | 单阶段包含Maven和源码 |
| 端口映射 | 检查宿主机端口占用,避免冲突 | 直接使用-p 8080:8080,不检查端口 |
| 环境变量 | 运行时用-e传递,覆盖默认配置 | 仅在Dockerfile中用ENV设置 |
| 健康检查 | 添加HEALTHCHECK + Spring Boot Actuator | 无健康检查,依赖容器状态判断应用存活 |
| 数据持久化 | 挂载宿主机目录或使用Docker Volume | 数据存储在容器内 |