springboot 项目jar 如何部署到docker

Spring Boot JAR 部署到 Docker 完整指南

一、基础 Dockerfile 方式

1. 准备 Spring Boot 项目

确保 pom.xml中打包方式为 jar:

xml 复制代码
<packaging>jar</packaging>

2. 创建 Dockerfile

在项目根目录创建 Dockerfile(无后缀):

bash 复制代码
# 第一阶段:构建应用
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. 构建和运行

perl 复制代码
# 构建镜像
docker build -t my-spring-app .

# 运行容器
docker run -d -p 8080:8080 --name spring-app my-spring-app

# 查看日志
docker logs -f spring-app

二、优化版 Dockerfile(生产推荐)

ini 复制代码
# 使用更小的基础镜像
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

yaml 复制代码
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:

常用命令

bash 复制代码
# 构建并启动
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)

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>

构建命令

python 复制代码
# 构建并推送到远程仓库
mvn compile jib:build

# 构建本地 Docker 镜像
mvn compile jib:dockerBuild

五、Kubernetes 部署示例

deployment.yaml

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
相关推荐
韩立学长2 小时前
基于Springboot的商品库存管理系统369jr3t9(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
java·数据库·spring boot·后端
y = xⁿ2 小时前
【Java八股锁机制的认识】synchronized和reentrantlock区分,锁升级机制
java·开发语言·后端
在屏幕前出油3 小时前
00. FastAPI——了解FastAPI
后端·python·pycharm·fastapi
iPadiPhone3 小时前
Spring Boot 自动装配原理与 Starter 开发实战
java·spring boot·后端·spring·面试
程序员爱钓鱼3 小时前
Go字符串与数值转换核心库:strconv深度解析
后端·面试·go
码匠君3 小时前
首个基于 Spring Boot 4 的正式版发布!Dante Cloud 4.X 新特性全解析
java·spring boot·后端
Rust语言中文社区3 小时前
【Rust日报】 CEL与Rust实现接近原生速度的解释执行
开发语言·后端·rust
武子康3 小时前
大数据-247 离线数仓 - 电商分析 Hive 拉链表实战:订单历史状态增量刷新、闭链逻辑与错误排查
大数据·后端·apache hive