Springboot打包docker的多種方法實(shí)現(xiàn)
一、Spring Boot 打包 Docker 鏡像的常用方法
方法一:傳統(tǒng) Dockerfile 構(gòu)建
1. 先打包 jar
mvn clean package -DskipTests
會(huì)生成 target/demo-0.0.1-SNAPSHOT.jar。
2. 編寫 Dockerfile
在項(xiàng)目根目錄新建 Dockerfile,內(nèi)容如下:
# 選擇基礎(chǔ)鏡像 FROM openjdk:17-jdk-alpine # 設(shè)置工作目錄 WORKDIR /app # 復(fù)制 jar 包到容器 COPY target/demo-0.0.1-SNAPSHOT.jar app.jar # 暴露端口 EXPOSE 8080 # 啟動(dòng)應(yīng)用 ENTRYPOINT ["java", "-jar", "app.jar"]
3. 構(gòu)建鏡像
docker build -t my-springboot-app:1.0 .
4. 運(yùn)行容器
docker run -d -p 8080:8080 my-springboot-app:1.0
方法二:使用 Spring Boot 2.3+ 內(nèi)置的 buildpack
Spring Boot 2.3+ 內(nèi)置了 Cloud Native Buildpacks 支持,無需寫 Dockerfile。
1. 直接打鏡像
./mvnw spring-boot:build-image -DskipTests # 或 mvn spring-boot:build-image -DskipTests
2. 運(yùn)行鏡像
docker run -d -p 8080:8080 demo:0.0.1-SNAPSHOT
優(yōu)點(diǎn): 自動(dòng)選擇合適的基礎(chǔ)鏡像、JDK 版本,鏡像安全、體積優(yōu)化。
方法三:多階段構(gòu)建(推薦生產(chǎn))
多階段構(gòu)建可極大減少鏡像體積,提升安全性。
# 第一階段:構(gòu)建 jar FROM maven:3.9.6-eclipse-temurin-17 AS build WORKDIR /app COPY . . RUN mvn clean package -DskipTests # 第二階段:運(yùn)行 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"]
構(gòu)建命令同上。
二、常用 Dockerfile 優(yōu)化建議
- 指定 JVM 參數(shù):生產(chǎn)環(huán)境可加 -Xms512m -Xmx1024m 控制內(nèi)存。
- 時(shí)區(qū)設(shè)置:
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 用戶運(yùn)行(安全):
RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring
三、常見問題與排查
| 問題 | 解決辦法 |
|---|---|
| 容器起不來/端口訪問不到 | 檢查 Dockerfile 的 EXPOSE 和 docker run -p 配置 |
| jar 路徑不對(duì) | COPY 路徑與 jar 包名需對(duì)應(yīng) |
| 時(shí)區(qū)不對(duì) | ENV TZ=Asia/Shanghai |
| 配置文件未生效 | 掛載配置目錄或用 -Dspring.config.location |
| 日志丟失 | 用 docker logs 查看,或配置日志輸出到控制臺(tái) |
四、最佳實(shí)踐
- 鏡像小巧:用 openjdk:17-jdk-alpine,避免用大體積的基礎(chǔ)鏡像。
- 多階段構(gòu)建:生產(chǎn)環(huán)境推薦,減少最終鏡像體積。
- 配置分離:用掛載、環(huán)境變量、K8s ConfigMap 管理配置。
- 安全運(yùn)行:非 root 用戶啟動(dòng),減少安全風(fēng)險(xiǎn)。
- 自動(dòng)化構(gòu)建:結(jié)合 CI/CD(如 GitHub Actions、Jenkins、GitLab CI)自動(dòng)構(gòu)建和推送鏡像。
五、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構(gòu)建命令:
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 鏡像高級(jí)技巧
1. 環(huán)境變量與配置掛載
- 環(huán)境變量注入:Spring Boot 支持通過環(huán)境變量覆蓋配置項(xiàng)。
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 ...
- 掛載日志目錄(推薦將日志輸出到掛載目錄,便于宿主機(jī)收集):
docker run -v /host/logs:/app/logs ...
2. 健康檢查與自恢復(fù)
- Dockerfile 中配置健康檢查,結(jié)合 Spring Boot Actuator:
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \ CMD curl -f http://localhost:8080/actuator/health || exit 1
- 容器編排平臺(tái)(如 K8s)可自動(dòng)重啟 unhealthy 容器。
3. JVM 參數(shù)優(yōu)化
- 在 Dockerfile 或啟動(dòng)命令中注入 JVM 參數(shù),控制內(nèi)存、GC 等:
ENV JAVA_OPTS="-Xms256m -Xmx512m" ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
- 推薦用 -XX:MaxRAMPercentage=75.0 讓 JVM 動(dòng)態(tài)感知容器分配的內(nèi)存。
4. 非 root 用戶運(yùn)行
- 提高安全性,防止容器越權(quán)操作主機(jī)資源。
RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring
5. 多端口暴露
- Spring Boot 默認(rèn)只用一個(gè)端口,但如有 actuator 或管理端口,可在 Dockerfile 中暴露多個(gè)端口:
EXPOSE 8080 8081
七、多環(huán)境(開發(fā)/測(cè)試/生產(chǎn))鏡像管理
- 多 profile 支持:通過環(huán)境變量或掛載配置文件切換環(huán)境。
- 多標(biāo)簽管理:鏡像構(gòu)建時(shí)用不同 tag 區(qū)分環(huán)境。
docker build -t my-app:dev . docker build -t my-app:prod .
- CI/CD 自動(dòng)化:流水線自動(dòng)根據(jù)分支或 tag 構(gòu)建不同環(huán)境鏡像并推送到鏡像倉庫(如 Harbor、Docker Hub)。
八、與微服務(wù)、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 做統(tǒng)一路由。
2. 服務(wù)發(fā)現(xiàn)與配置中心
- Spring Cloud 微服務(wù)場(chǎng)景推薦結(jié)合 Nacos、Eureka、Consul 做服務(wù)發(fā)現(xiàn)。
- 配置中心可用 Spring Cloud Config、Nacos 配置,避免鏡像內(nèi)硬編碼。
3. 日志與監(jiān)控
- 推薦日志輸出到標(biāo)準(zhǔn)輸出(stdout),K8s 可自動(dòng)收集。
- 集成 Prometheus、Grafana、ELK/SkyWalking 做性能監(jiān)控和鏈路追蹤。
九、常見容器化部署問題深度解析
| 問題 | 原因與解決辦法 |
|---|---|
| 容器內(nèi)時(shí)區(qū)不對(duì) | Dockerfile 設(shè)置 ENV TZ=Asia/Shanghai 或掛載宿主機(jī)時(shí)區(qū)文件 |
| 配置未生效/被覆蓋 | 優(yōu)先級(jí):命令行參數(shù) > 環(huán)境變量 > 掛載文件 > 鏡像內(nèi)配置,建議用環(huán)境變量或掛載 |
| 內(nèi)存溢出/OOM | JVM 參數(shù)未限制,建議用 -Xmx 或 MaxRAMPercentage |
| 日志丟失/查不到 | 日志輸出到容器內(nèi)文件,建議輸出到控制臺(tái)或掛載日志目錄 |
| 容器重啟后數(shù)據(jù)丟失 | 容器無狀態(tài),需掛載數(shù)據(jù)卷或用外部存儲(chǔ)(如數(shù)據(jù)庫、對(duì)象存儲(chǔ)) |
| 端口沖突/無法訪問 | 檢查 Dockerfile 的 EXPOSE 與 docker run -p 參數(shù)是否一致 |
十、完整多階段 Dockerfile 高級(jí)示例
# 構(gòu)建階段 FROM maven:3.9.6-eclipse-temurin-17 AS build WORKDIR /app COPY . . RUN mvn clean package -DskipTests # 運(yùn)行階段 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"]
十一、參考與擴(kuò)展閱讀
到此這篇關(guān)于Springboot打包docker的多種方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Springboot打包docker內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot服務(wù)docker打包分層的實(shí)現(xiàn)
- 將Java(SpringBoot)項(xiàng)目打包為Docker鏡像的三種方法
- 淺析如何將多個(gè)SpringBoot項(xiàng)目打包到一個(gè)Docker容器中
- Docker打包SpringBoot鏡像的實(shí)現(xiàn)方式
- SpringBoot打包成Docker鏡像的項(xiàng)目實(shí)踐
- SpringBoot打包成Docker鏡像的幾種實(shí)現(xiàn)方式
- SpringBoot多模塊打包部署Docker的項(xiàng)目實(shí)戰(zhàn)
- 一步步教你把SpringBoot項(xiàng)目打包成Docker鏡像
- SpringBoot打包docker鏡像發(fā)布的詳細(xì)步驟
- Springboot打包為Docker鏡像并部署的實(shí)現(xiàn)
- SpringBoot3.x打包Docker容器的實(shí)現(xiàn)
- Springboot微服務(wù)打包Docker鏡像流程解析
相關(guān)文章
docker容器中布置靜態(tài)網(wǎng)站的實(shí)現(xiàn)
這篇文章主要介紹了docker容器中布置靜態(tài)網(wǎng)站的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Docker創(chuàng)建容器時(shí)目錄權(quán)限踩坑
這篇文章主要介紹了Docker創(chuàng)建容器時(shí)目錄權(quán)限踩坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
使用Docker命令查看容器最后300行實(shí)時(shí)日志
在日常的容器化應(yīng)用管理中,日志是排查問題、監(jiān)控運(yùn)行狀態(tài)的重要工具,Docker 提供了簡(jiǎn)便的命令來查看容器日志,幫助開發(fā)者和運(yùn)維人員快速定位問題,本篇博客將詳細(xì)介紹如何使用 Docker 命令查看指定容器的最后 300 行實(shí)時(shí)日志,需要的朋友可以參考下2025-03-03
替換docker容器中的一個(gè)文件的實(shí)現(xiàn)
在某些情況下,我們可能確實(shí)需要更新容器內(nèi)的文件,本文主要介紹了替換docker容器中的一個(gè)文件的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06

