Spring Boot JAR 部署到 Docker 完整指南
一、基础 Dockerfile 方式
1. 准备 Spring Boot 项目
确保 pom.xml中打包方式为 jar:
<packaging>jar</packaging>
2. 创建 Dockerfile
在项目根目录创建 Dockerfile(无后缀):
# 第一阶段:构建应用
FROM maven:3.8.6-openjdk-11 AS builder
WORKDIR /app
# 复制 pom.xml 并下载依赖(利用缓存)
COPY pom.xml .
RUN mvn dependency:go-offline
# 复制源代码并打包
COPY src ./src
RUN mvn package -DskipTests
# 第二阶段:运行环境
FROM openjdk:11-jre-slim
WORKDIR /app
# 从构建阶段复制 jar 文件
COPY --from=builder /app/target/*.jar app.jar
# 暴露端口(Spring Boot 默认 8080)
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]
3. 构建和运行
# 构建镜像
docker build -t my-spring-app .
# 运行容器
docker run -d -p 8080:8080 --name spring-app my-spring-app
# 查看日志
docker logs -f spring-app
二、优化版 Dockerfile(生产推荐)
# 使用更小的基础镜像
FROM eclipse-temurin:17-jre-alpine AS runtime
# 设置环境变量
ENV SPRING_PROFILES_ACTIVE=prod \
JAVA_OPTS="-Xms512m -Xmx1024m"
# 创建非 root 用户(安全最佳实践)
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
# 设置工作目录
WORKDIR /app
# 只复制 jar 文件(减少层大小)
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
EXPOSE 8080
ENTRYPOINT exec java $JAVA_OPTS -jar app.jar
三、使用 Docker Compose 部署
docker-compose.yml
version: '3.8'
services:
spring-app:
build: .
container_name: spring-boot-app
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- JAVA_OPTS=-Xms512m -Xmx1024m
volumes:
# 日志持久化
- ./logs:/app/logs
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
# 可选:添加数据库
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
restart: unless-stopped
volumes:
mysql-data:
常用命令
# 构建并启动
docker-compose up -d --build
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f spring-app
# 停止服务
docker-compose down
# 停止并删除数据卷
docker-compose down -v
四、使用 Jib 插件(无需 Dockerfile)
Maven 配置 (pom.xml)
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<from>
<image>eclipse-temurin:17-jre-alpine</image>
</from>
<to>
<image>my-registry/my-spring-app:${project.version}</image>
</to>
<container>
<mainClass>com.example.demo.DemoApplication</mainClass>
<ports>
<port>8080</port>
</ports>
<environment>
<SPRING_PROFILES_ACTIVE>prod</SPRING_PROFILES_ACTIVE>
</environment>
</container>
</configuration>
</plugin>
构建命令
# 构建并推送到远程仓库
mvn compile jib:build
# 构建本地 Docker 镜像
mvn compile jib:dockerBuild
五、Kubernetes 部署示例
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-app
spec:
replicas: 2
selector:
matchLabels:
app: spring-app
template:
metadata:
labels:
app: spring-app
spec:
containers:
- name: spring-app
image: my-registry/my-spring-app:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "k8s"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: spring-app-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: spring-app
六、常见问题解决
| 问题 | 解决方案 |
|---|---|
| 时区不正确 | 在 Dockerfile 中添加 ENV TZ=Asia/Shanghai并安装 tzdata |
| 中文乱码 | 添加 JVM 参数 -Dfile.encoding=UTF-8 |
| 配置文件不生效 | 使用 docker cp复制配置文件或挂载 volume |
| 内存占用过高 | 调整 JAVA_OPTS,使用 -XX:+UseContainerSupport |