Skip to content

Spring Boot 生产环境部署实践:从 Jar 到 Docker

这是一篇测试文章,记录了我将 Spring Boot 应用从裸机 nohup 迁移到 Docker Compose + Nginx 生产环境的完整过程。

背景

最早部署 Spring Boot 应用时,用的是最原始的方式:

bash
nohup java -jar app.jar --server.port=8866 > app.log 2>&1 &

简单粗暴,但问题一堆:

  • 进程挂了不会自动重启
  • 更新版本要手动 kill + 启动
  • 日志文件没人管,越积越大
  • 服务器重启后要手动爬起来

演进路线

第一阶段:Docker 化

dockerfile
FROM amazoncorretto:8-alpine

WORKDIR /app
COPY target/app.jar app.jar

ENTRYPOINT ["java", "-Xms1g", "-Xmx2g", "-jar", "app.jar"]

第二阶段:Docker Compose 编排

yaml
services:
  backend:
    build: ./backend
    container_name: smart-shop-backend
    restart: always
    ports:
      - "127.0.0.1:8866:8866"
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8866/admin/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  nginx:
    image: nginx:1.25-alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

第三阶段:进程守护与健康检查

Docker 的 restart: always 解决了进程崩溃后的自愈问题,但真正的生产环境还需要:

  1. 健康检查 — 让 Nginx 只在应用真正 ready 后才接收流量
  2. 优雅关闭 — 收到停止信号后先停止接收新请求,等存量请求处理完再退出
  3. 日志轮转 — 防止日志打爆磁盘

关键配置

JVM 参数

bash
JAVA_OPTS="-Xms1g -Xmx2g \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=200 \
  -Djava.security.egd=file:/dev/./urandom"

数据库连接池(Druid)

生产环境千万别用默认的 max-active=100,2C4G 的机器跑不了 100 个并发连接:

yaml
spring:
  datasource:
    druid:
      max-active: 30    # 够用了
      initial-size: 5
      min-idle: 5

Nginx 反向代理

注意 WebSocket 支持,漏了这两行前端 WebSocket 会断:

nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

总结

Docker Compose 部署后,更新版本只需要:

bash
docker compose build backend
docker compose up -d --no-deps backend

一条命令完成构建、推送、部署全流程,比 nohup 时代强了不止一个档次。


这是一篇测试文章,部署时间:2026-04-08