Docker + Nginx 部署 Java 项目(JAR 包 + WAR 包)实战笔记

一、核心场景与环境准备

1. 部署目标

通过 Docker 容器化 Nginx 作为反向代理服务器,转发请求到 Java 项目(SpringBoot JAR 包 或 传统 WAR 包),实现"静态资源代理 + 接口转发 + 端口统一管理",适配开发/生产环境部署。

2. 前置环境

  • 本地/服务器安装 Docker(Docker Desktop 或 Linux 版 Docker)、Docker Compose(Docker Desktop 自带,Linux 需单独安装);
  • Java 项目已打包完成(JAR 包 或 WAR 包);
  • 了解基础 Docker 命令(镜像构建、容器启停)和 Nginx 反向代理配置。

3. 核心架构

复制代码
用户请求 → Nginx(80/443 端口)→ 反向代理 → Java 项目容器(8080/8081 端口)
  • Nginx 作用:统一入口端口、处理静态资源、转发接口请求、配置 HTTPS;
  • Java 容器:独立运行 JAR/WAR 包,与 Nginx 通过 Docker 网络通信。

二、部署 SpringBoot JAR 包(推荐,内置 Tomcat)

1. 项目准备

  • 本地 SpringBoot 项目打包为可执行 JAR 包(如 dramamini.jar),确保打包命令正确:

    复制代码
    mvn clean package -Dmaven.test.skip=true
  • 打包后在 target/ 目录获取 JAR 包,复制到部署目录(如 docker-java-demo/)。

2. 部署目录结构

复制代码
docker-java-demo/
├── java/                # Java 项目目录
│   └── dramamini.jar    # SpringBoot JAR 包
├── nginx/               # Nginx 配置目录
│   ├── nginx.conf       # Nginx 核心配置
│   └── html/            # 静态资源(可选,如前端页面)
└── docker-compose.yml   # 多容器管理配置

3. 关键配置文件

(1)Nginx 配置(nginx/nginx.conf)

核心实现"接口反向代理",转发请求到 Java 容器:

复制代码
worker_processes 1;
events { worker_connections 1024; }

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent"';
    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;

    # 反向代理 Java 项目
    server {
        listen 80;
        server_name localhost;

        # 静态资源代理(如前端页面,可选)
        location / {
            root /usr/share/nginx/html;
            index index.html;
        }

        # 接口请求转发到 Java 容器(/api 前缀可自定义)
        location /api/ {
            proxy_pass http://java-app:8080/;  # java-app 是 Docker 容器名,8080 是 Java 项目端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
(2)Docker Compose 配置(docker-compose.yml)

统一管理 Nginx 和 Java 容器,确保网络互通:

复制代码
version: '3.8'
services:
  # Nginx 容器(反向代理)
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"  # 宿主机 80 端口映射到 Nginx 80 端口
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf  # 挂载 Nginx 配置
      - ./nginx/html:/usr/share/nginx/html        # 挂载静态资源
      - ./nginx/logs:/var/log/nginx              # 挂载日志(可选)
    restart: always
    networks:
      - java-network
    depends_on:
      - java-app  # 确保 Java 容器先启动

  # Java 项目容器(JAR 包)
  java-app:
    image: openjdk:8-jdk-alpine  # 基础 Java 镜像(匹配项目 JDK 版本)
    container_name: java-app
    volumes:
      - ./java/dramamini.jar:/app/dramamini.jar  # 挂载 JAR 包
      - ./java/logs:/app/logs                  # 挂载 Java 日志(可选)
    working_dir: /app
    command: java -jar dramamini.jar --spring.profiles.active=test  # 启动命令(可加 JVM 参数)
    restart: always
    networks:
      - java-network
    expose:
      - "8080"  # 暴露容器内端口(无需映射到宿主机,Nginx 内部访问)

networks:
  java-network:
    driver: bridge  # 自定义桥接网络,确保容器互通

4. 部署步骤

(1)启动容器

进入 docker-java-demo/ 目录,执行:

复制代码
# 后台启动所有容器
docker compose up -d
# 查看容器状态(确保 both 状态为 Up)
docker compose ps
(2)验证部署
  • 访问静态资源(若有):http://localhost → 显示 Nginx 挂载的静态页面;

  • 访问 Java 接口:http://localhost/api/xxx → Nginx 转发到 Java 容器,返回接口响应;

  • 查看日志(排查问题):

    复制代码
    # 查看 Nginx 日志
    docker compose logs -f nginx
    # 查看 Java 项目日志
    docker compose logs -f java-app
(3)更新项目(如 JAR 包迭代)
复制代码
# 1. 替换 ./java/ 目录下的旧 JAR 包为新包
# 2. 重启 Java 容器(无需重启 Nginx)
docker compose restart java-app

三、部署传统 WAR 包(需外部 Tomcat)

1. 项目准备

  • 传统 Java Web 项目(如 SSM)打包为 WAR 包(如 demo.war);
  • 确保 WAR 包兼容 Tomcat 版本(推荐 Tomcat 8.5/9.0)。

2. 部署目录结构

复制代码
docker-war-demo/
├── tomcat/              # Tomcat 相关目录
│   ├── webapps/         # WAR 包存放目录
│   │   └── demo.war     # Java WAR 包
│   └── conf/            # Tomcat 配置(可选,如需修改端口)
├── nginx/               # 同 JAR 包部署的 Nginx 目录(复用配置)
│   ├── nginx.conf
│   └── html/
└── docker-compose.yml

3. 关键配置文件

(1)Nginx 配置(复用 JAR 包部署的 nginx.conf

无需修改,核心转发逻辑一致(proxy_pass http://tomcat-app:8080/)。

(2)Docker Compose 配置(docker-compose.yml)

替换 Java 容器为 Tomcat 容器,挂载 WAR 包到 Tomcat 的 webapps/ 目录:

复制代码
version: '3.8'
services:
  nginx:
    # 同 JAR 包部署的 Nginx 配置,无需修改
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/html:/usr/share/nginx/html
    restart: always
    networks:
      - java-network
    depends_on:
      - tomcat-app

  # Tomcat 容器(运行 WAR 包)
  tomcat-app:
    image: tomcat:8.5-alpine  # 选择对应版本的 Tomcat 镜像
    container_name: tomcat-app
    volumes:
      - ./tomcat/webapps:/usr/local/tomcat/webapps  # 挂载 WAR 包到 Tomcat
      - ./tomcat/logs:/usr/local/tomcat/logs      # 挂载 Tomcat 日志(可选)
      # 如需修改 Tomcat 端口,挂载 server.xml(可选)
      # - ./tomcat/conf/server.xml:/usr/local/tomcat/conf/server.xml
    restart: always
    networks:
      - java-network
    expose:
      - "8080"  # Tomcat 默认端口

networks:
  java-network:
    driver: bridge

4. 部署步骤

(1)启动容器
复制代码
cd docker-war-demo/
docker compose up -d
  • Tomcat 会自动解压 webapps/ 下的 WAR 包(如 demo.wardemo/ 目录);
  • 访问路径:若 WAR 包名为 demo.war,则接口路径为 http://localhost/api/demo/xxx(需同步修改 Nginx 配置中的 proxy_passhttp://tomcat-app:8080/demo/)。
(2)验证部署
  • 访问接口:http://localhost/api/xxx → Nginx 转发到 Tomcat 容器,返回 WAR 包接口响应;

  • 查看 Tomcat 日志(确认 WAR 包部署成功):

    复制代码
    docker compose logs -f tomcat-app
(3)更新 WAR 包
复制代码
# 1. 替换 ./tomcat/webapps/ 下的旧 WAR 包为新包
# 2. 重启 Tomcat 容器(Tomcat 自动重新解压 WAR 包)
docker compose restart tomcat-app

四、生产环境优化(可选)

1. HTTPS 配置(Nginx 层面)

  • 生成 Let's Encrypt 免费证书(生产环境)或自签名证书(测试);
  • 修改 Nginx 配置,添加 443 端口监听和证书挂载(参考前文 HTTPS 配置);
  • docker-compose.yml 中给 Nginx 新增 443 端口映射:- "443:443"

2. 容器优化

  • Java 容器添加 JVM 参数(如限制内存):

    复制代码
    # JAR 包容器 command 示例
    command: java -Xms512m -Xmx1024m -jar dramamini.jar
  • Tomcat 容器修改连接数(挂载 server.xml 配置)。

3. 日志与监控

  • 挂载日志目录到宿主机,便于持久化存储;
  • 集成 ELK 栈收集日志,或 Prometheus + Grafana 监控容器状态。

4. 高可用(多实例)

  • 启动多个 Java/Tomcat 容器,在 Nginx 配置中添加负载均衡:

    复制代码
    http {
      # 负载均衡配置
      upstream java-servers {
        server java-app1:8080;
        server java-app2:8080;
      }
      # 转发时使用 upstream 名称
      location /api/ {
        proxy_pass http://java-servers/;
      }
    }

五、常见问题排查

1. Nginx 无法连接 Java 容器

  • 检查容器是否在同一网络:docker network inspect java-network,确认两个容器都在该网络;
  • 确认 Java/Tomcat 容器已启动(docker compose ps 状态为 Up);
  • 检查 proxy_pass 配置:容器名是否正确(如 java-app 而非 IP),端口是否暴露。

2. Java 项目启动失败

  • 查看容器日志:docker compose logs -f java-apptomcat-app,定位报错(如端口占用、依赖缺失);
  • 确认 JDK/Tomcat 版本与项目兼容(如 SpringBoot 2.x 不兼容 JDK 17+)。

3. WAR 包未自动解压

  • 检查 WAR 包权限:确保宿主机 ./tomcat/webapps/ 目录有读写权限;
  • 重启 Tomcat 容器:docker compose restart tomcat-app

六、核心总结

部署方式 适用场景 优势 关键注意点
JAR 包 SpringBoot 项目(内置 Tomcat) 配置简单、无需额外 Tomcat 确保 JAR 包可独立运行,暴露正确端口
WAR 包 传统 Java Web 项目(SSM 等) 兼容旧项目、可自定义 Tomcat 注意 Tomcat 版本与 WAR 包兼容

核心优势:容器化部署隔离环境、Nginx 统一入口便于管理,通过 Docker Compose 简化多容器启停,适配开发/生产全场景。

相关推荐
带刺的坐椅1 小时前
Solon AI 开发学习 - 1导引
java·ai·openai·solon·mcp
sg_knight1 小时前
RabbitMQ 中的预取值(prefetch)详解:如何真正提升消费端性能?
java·spring boot·spring·spring cloud·消息队列·rabbitmq·预取值
Dxxyyyy2 小时前
零基础学JAVA--Day34(Map接口+HashTable+HashMap+TreeSet+TreeMap+开发中如何选择集合实现类?(重要))
java·开发语言
spencer_tseng2 小时前
Tomcat Source Code Distributions
java·tomcat
烤麻辣烫2 小时前
23种设计模式(新手)-5里氏替换原则
java·学习·设计模式·intellij-idea·里氏替换原则
喵手2 小时前
网络编程:Java中的TCP与UDP通信!
java·udp·网络编程·tcp
u***1372 小时前
【SpringBoot】【log】 自定义logback日志配置
java·spring boot·logback
小坏讲微服务3 小时前
Spring Cloud Alibaba整合SkyWalking的监控完整使用
java·微服务·架构·springcloud·监控·skywalking·java微服务
chxii3 小时前
第六章:MySQL DQL 表之间的关系 自连接 一对一、一对多、多对一、多对多
java·前端·mysql