springboot 项目jar 如何部署到docker

5 阅读3分钟

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