最近在帮客户部署一套Java Web应用时,遇到了一个典型场景:需要将Nginx作为前端反向代理,将请求转发到后端的Tomcat容器。这种架构在Web服务部署中非常常见,既能利用Nginx的高性能静态资源处理能力,又能发挥Tomcat的Java应用执行优势。
传统部署方式需要在物理机或虚拟机上分别安装配置Nginx和Tomcat,不仅过程繁琐,还容易产生环境依赖问题。而通过Docker容器化部署,可以实现:
整个方案包含两个核心容器:
两者通过Docker网络互联,Nginx将动态请求转发到Tomcat。网络拓扑如下:
code复制客户端 → Nginx:80 → Tomcat:8080
对于生产环境,推荐使用官方镜像的alpine版本,体积更小、安全性更高:
nginx:alpine(约20MB)tomcat:jre8-alpine(约100MB)如果需要特定JDK版本,可考虑:
tomcat:9.0-jdk11-openjdk-slim(约450MB)首先确保宿主机已安装Docker:
bash复制# Ubuntu示例
sudo apt update
sudo apt install docker.io
sudo systemctl enable --now docker
验证安装:
bash复制docker --version
# 应输出类似:Docker version 20.10.12, build e91ed57
为容器创建独立的桥接网络:
bash复制docker network create webnet
查看网络:
bash复制docker network inspect webnet
启动Tomcat容器并加入网络:
bash复制docker run -d \
--name mytomcat \
--network webnet \
-v /path/to/webapps:/usr/local/tomcat/webapps \
-e TZ=Asia/Shanghai \
tomcat:9.0-jre8-alpine
关键参数说明:
-v:挂载Web应用目录-e TZ:设置容器时区--network:加入自定义网络验证Tomcat:
bash复制curl http://localhost:8080
先创建Nginx配置文件nginx.conf:
nginx复制worker_processes auto;
events {
worker_connections 1024;
}
http {
upstream tomcat {
server mytomcat:8080;
}
server {
listen 80;
location / {
proxy_pass http://tomcat;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location ~* \.(jpg|png|css|js)$ {
root /static;
expires 30d;
}
}
}
启动Nginx容器:
bash复制docker run -d \
--name mynginx \
--network webnet \
-p 80:80 \
-v ./nginx.conf:/etc/nginx/nginx.conf \
-v ./static:/static \
nginx:alpine
关键配置说明:
upstream:定义Tomcat服务地址proxy_pass:请求转发规则修改Nginx容器启动命令,添加日志挂载:
bash复制-v ./logs/nginx:/var/log/nginx
建议的logrotate配置:
code复制/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
在Nginx配置中添加:
nginx复制proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
Tomcat启动可添加JVM参数:
bash复制-e JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
Docker健康检查示例:
bash复制--health-cmd="curl -f http://localhost:8080/ || exit 1" \
--health-interval=30s \
--health-timeout=3s \
--health-retries=3
可能原因及解决方案:
bash复制docker logs mytomcat
bash复制docker exec -it mynginx ping mytomcat
bash复制docker inspect mytomcat | grep IPAddress
检查步骤:
bash复制ls -ld /static
bash复制docker exec mynginx nginx -t
nginx复制types {
text/css css;
application/javascript js;
}
解决方案:
bash复制-e TZ=Asia/Shanghai
dockerfile复制RUN apk add --no-cache tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
bash复制--memory=1g --cpus=2
dockerfile复制USER nobody
bash复制docker pull nginx:alpine
推荐组合:
基础监控命令:
bash复制docker stats mynginx mytomcat
关键数据备份:
bash复制docker cp mynginx:/etc/nginx ./nginx-backup
bash复制docker cp mytomcat:/usr/local/tomcat/webapps ./webapps-backup
建议的备份脚本:
bash复制#!/bin/bash
BACKUP_DIR=/backups/$(date +%Y%m%d)
mkdir -p $BACKUP_DIR
docker exec mynginx tar czf - /etc/nginx > $BACKUP_DIR/nginx-$(date +%H%M).tar.gz
修改Nginx配置:
nginx复制upstream tomcat {
server mytomcat1:8080;
server mytomcat2:8080;
server mytomcat3:8080;
least_conn; # 使用最少连接算法
}
启动多个Tomcat实例:
bash复制for i in {1..3}; do
docker run -d --name mytomcat$i --network webnet tomcat:alpine
done
生成自签名证书:
bash复制openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ./ssl/nginx.key -out ./ssl/nginx.crt
Nginx配置调整:
nginx复制server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
# 其他配置...
}
启动命令添加:
bash复制-v ./ssl:/etc/nginx/ssl
创建docker-compose.yml:
yaml复制version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./static:/static
- ./ssl:/etc/nginx/ssl
networks:
- webnet
depends_on:
- tomcat
tomcat:
image: tomcat:alpine
volumes:
- ./webapps:/usr/local/tomcat/webapps
networks:
- webnet
environment:
- TZ=Asia/Shanghai
networks:
webnet:
driver: bridge
启动命令:
bash复制docker-compose up -d