Springboot打包docker的多种方法实现

 更新时间:2025年12月09日 09:47:39   作者:猩火燎猿  
本文介绍了SpringBoot项目打包为Docker镜像的多种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、Spring Boot 打包 Docker 镜像的常用方法

方法一:传统 Dockerfile 构建

1. 先打包 jar

mvn clean package -DskipTests

会生成 target/demo-0.0.1-SNAPSHOT.jar

2. 编写 Dockerfile

在项目根目录新建 Dockerfile,内容如下:

# 选择基础镜像
FROM openjdk:17-jdk-alpine
# 设置工作目录
WORKDIR /app
# 复制 jar 包到容器
COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]

3. 构建镜像

docker build -t my-springboot-app:1.0 .

4. 运行容器

docker run -d -p 8080:8080 my-springboot-app:1.0

方法二:使用 Spring Boot 2.3+ 内置的 buildpack

Spring Boot 2.3+ 内置了 Cloud Native Buildpacks 支持,无需写 Dockerfile。

1. 直接打镜像

./mvnw spring-boot:build-image -DskipTests
# 或
mvn spring-boot:build-image -DskipTests

2. 运行镜像

docker run -d -p 8080:8080 demo:0.0.1-SNAPSHOT

优点: 自动选择合适的基础镜像、JDK 版本,镜像安全、体积优化。

方法三:多阶段构建(推荐生产)

多阶段构建可极大减少镜像体积,提升安全性。

# 第一阶段:构建 jar
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests

# 第二阶段:运行 jar
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY --from=build /app/target/demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

构建命令同上。

二、常用 Dockerfile 优化建议

  • 指定 JVM 参数:生产环境可加 -Xms512m -Xmx1024m 控制内存。
  • 时区设置
    ENV TZ=Asia/Shanghai
  • 健康检查(Docker 17+ 支持):
    HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
      CMD curl -f http://localhost:8080/actuator/health || exit 1
  • 非 root 用户运行(安全):
    RUN addgroup -S spring && adduser -S spring -G spring
    USER spring:spring

三、常见问题与排查

问题解决办法
容器起不来/端口访问不到检查 Dockerfile 的 EXPOSE 和 docker run -p 配置
jar 路径不对COPY 路径与 jar 包名需对应
时区不对ENV TZ=Asia/Shanghai
配置文件未生效挂载配置目录或用 -Dspring.config.location
日志丢失用 docker logs 查看,或配置日志输出到控制台

四、最佳实践

  • 镜像小巧:用 openjdk:17-jdk-alpine,避免用大体积的基础镜像。
  • 多阶段构建:生产环境推荐,减少最终镜像体积。
  • 配置分离:用挂载、环境变量、K8s ConfigMap 管理配置。
  • 安全运行:非 root 用户启动,减少安全风险。
  • 自动化构建:结合 CI/CD(如 GitHub Actions、Jenkins、GitLab CI)自动构建和推送镜像。

五、Spring Boot + Dockerfile 完整示例

Dockerfile:

FROM openjdk:17-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENV JAVA_OPTS=""
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
EXPOSE 8080

构建命令:

mvn clean package -DskipTests
docker build -t my-springboot-app:1.0 .
docker run -d -p 8080:8080 my-springboot-app:1.0

六、Spring Boot Docker 镜像高级技巧

1. 环境变量与配置挂载

  • 环境变量注入:Spring Boot 支持通过环境变量覆盖配置项。
    docker run -e SPRING_PROFILES_ACTIVE=prod -e SERVER_PORT=8081 ...
  • 挂载外部配置文件
    docker run -v /host/config/application-prod.yml:/app/application-prod.yml \
      -e SPRING_CONFIG_LOCATION=/app/application-prod.yml ...
  • 挂载日志目录(推荐将日志输出到挂载目录,便于宿主机收集):
    docker run -v /host/logs:/app/logs ...

2. 健康检查与自恢复

  • Dockerfile 中配置健康检查,结合 Spring Boot Actuator:
    HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
      CMD curl -f http://localhost:8080/actuator/health || exit 1
  • 容器编排平台(如 K8s)可自动重启 unhealthy 容器。

3. JVM 参数优化

  • 在 Dockerfile 或启动命令中注入 JVM 参数,控制内存、GC 等:
    ENV JAVA_OPTS="-Xms256m -Xmx512m"
    ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
  • 推荐用 -XX:MaxRAMPercentage=75.0 让 JVM 动态感知容器分配的内存。

4. 非 root 用户运行

  • 提高安全性,防止容器越权操作主机资源。
    RUN addgroup -S spring && adduser -S spring -G spring
    USER spring:spring

5. 多端口暴露

  • Spring Boot 默认只用一个端口,但如有 actuator 或管理端口,可在 Dockerfile 中暴露多个端口:
    EXPOSE 8080 8081

七、多环境(开发/测试/生产)镜像管理

  • 多 profile 支持:通过环境变量或挂载配置文件切换环境。
  • 多标签管理:镜像构建时用不同 tag 区分环境。
    docker build -t my-app:dev .
    docker build -t my-app:prod .
  • CI/CD 自动化:流水线自动根据分支或 tag 构建不同环境镜像并推送到镜像仓库(如 Harbor、Docker Hub)。

八、与微服务、K8s 的集成建议

1. Kubernetes 部署 Spring Boot

  • 推荐用 Deployment/StatefulSet 管理 Spring Boot 容器。

  • 配置健康检查(readiness/liveness probe):

    livenessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
  • 用 ConfigMap/Secret 管理配置和敏感信息。

  • 用 Service 暴露端口,Ingress 做统一路由。

2. 服务发现与配置中心

  • Spring Cloud 微服务场景推荐结合 Nacos、Eureka、Consul 做服务发现。
  • 配置中心可用 Spring Cloud Config、Nacos 配置,避免镜像内硬编码。

3. 日志与监控

  • 推荐日志输出到标准输出(stdout),K8s 可自动收集。
  • 集成 Prometheus、Grafana、ELK/SkyWalking 做性能监控和链路追踪。

九、常见容器化部署问题深度解析

问题原因与解决办法
容器内时区不对Dockerfile 设置 ENV TZ=Asia/Shanghai 或挂载宿主机时区文件
配置未生效/被覆盖优先级:命令行参数 > 环境变量 > 挂载文件 > 镜像内配置,建议用环境变量或挂载
内存溢出/OOMJVM 参数未限制,建议用 -Xmx 或 MaxRAMPercentage
日志丢失/查不到日志输出到容器内文件,建议输出到控制台或挂载日志目录
容器重启后数据丢失容器无状态,需挂载数据卷或用外部存储(如数据库、对象存储)
端口冲突/无法访问检查 Dockerfile 的 EXPOSE 与 docker run -p 参数是否一致

十、完整多阶段 Dockerfile 高级示例

# 构建阶段
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests

# 运行阶段
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Xms256m -Xmx512m"
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

十一、参考与扩展阅读

到此这篇关于Springboot打包docker的多种方法实现的文章就介绍到这了,更多相关Springboot打包docker内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Docker 容器连接的具体实现

    Docker 容器连接的具体实现

    本文主要介绍了Docker 容器连接的具体实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • docker compose如何读取.env文件的变量

    docker compose如何读取.env文件的变量

    这篇文章主要介绍了docker compose如何读取.env文件的变量的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • docker容器中布置静态网站的实现

    docker容器中布置静态网站的实现

    这篇文章主要介绍了docker容器中布置静态网站的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Docker部署多种容器的详细过程

    Docker部署多种容器的详细过程

    本文介绍了在Windows和Linux系统上使用Docker部署MySQL和RabbitMQ容器的方法,对于MySQL使用docker run命令,配置了端口映射、权限、时区和数据持久化等选项,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-01-01
  • Docker创建容器时目录权限踩坑

    Docker创建容器时目录权限踩坑

    这篇文章主要介绍了Docker创建容器时目录权限踩坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • docker 安装solr8.6.2 配置中文分词器的方法

    docker 安装solr8.6.2 配置中文分词器的方法

    这篇文章主要介绍了docker 安装solr8.6.2 配置中文分词器的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 使用Docker命令查看容器最后300行实时日志

    使用Docker命令查看容器最后300行实时日志

    在日常的容器化应用管理中,日志是排查问题、监控运行状态的重要工具,Docker 提供了简便的命令来查看容器日志,帮助开发者和运维人员快速定位问题,本篇博客将详细介绍如何使用 Docker 命令查看指定容器的最后 300 行实时日志,需要的朋友可以参考下
    2025-03-03
  • 替换docker容器中的一个文件的实现

    替换docker容器中的一个文件的实现

    在某些情况下,我们可能确实需要更新容器内的文件,本文主要介绍了替换docker容器中的一个文件的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • 使用docker搭建redis主从的方法步骤

    使用docker搭建redis主从的方法步骤

    这篇文章主要介绍了使用docker搭建redis主从的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • IDEA 配置Docker的过程

    IDEA 配置Docker的过程

    这篇文章主要介绍了IDEA 配置Docker的过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02

最新评论