1. 项目概述与核心思路
在容器化部署场景中,Nginx作为反向代理与Tomcat应用服务器的组合非常常见。传统部署方式需要手动配置网络连接,而Docker的网络特性可以让这个流程变得更加优雅。这个方案的核心价值在于:
- 网络稳定性:通过自定义Docker网络解决默认bridge网络IP变动导致的代理失效问题
- 配置可维护性:使用容器名称代替IP地址,配置文件更具可读性
- 环境一致性:所有组件运行在容器中,避免宿主机环境差异带来的问题
我最近在为客户部署Java Web应用时,就采用了这种架构。相比之前直接使用宿主机网络的方式,容器化方案在后续的扩展和维护上节省了大量时间。特别是在需要部署多套测试环境时,这种方案的复用性优势非常明显。
2. 环境准备与网络配置
2.1 Docker环境检查
在开始之前,建议先确认Docker环境状态:
bash复制# 检查Docker版本(需要1.13+)
docker version
# 检查Docker服务状态
docker info
注意:Windows系统需要确保已启用WSL2后端,并在Docker Desktop设置中分配至少4GB内存
2.2 创建自定义网络
创建名为nginx-tomcat-net的自定义网络:
bash复制docker network create --driver bridge nginx-tomcat-net
参数说明:
--driver bridge:指定网络驱动类型(默认就是bridge,可省略)- 网络创建后会自动启用DNS解析功能,这是实现容器名访问的关键
验证网络创建成功:
bash复制docker network inspect nginx-tomcat-net | grep "Subnet"
应该能看到类似输出:
code复制"Subnet": "172.19.0.0/16"
3. Tomcat容器部署
3.1 启动Tomcat容器
bash复制docker run -d \
--name tomcat-server \
--network nginx-tomcat-net \
-p 8081:8080 \
tomcat:9.0
关键参数解析:
-p 8081:8080:将容器8080端口映射到宿主机8081端口--network:指定刚创建的自定义网络- 建议使用特定版本标签(如tomcat:9.0)而非latest,保证环境一致性
3.2 解决Tomcat默认404问题
官方Tomcat镜像的webapps目录是空的,需要复制示例应用:
bash复制docker exec tomcat-server cp -r /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/
验证Tomcat是否正常运行:
code复制curl http://localhost:8081
应该能看到Tomcat默认页面HTML源码
4. Nginx配置与部署
4.1 准备Nginx配置文件
创建default.conf配置文件:
nginx复制upstream tomcat {
server tomcat-server:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcat;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 以下为性能调优参数
proxy_connect_timeout 60s;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffering off;
}
}
配置亮点:
- 使用upstream模块实现负载均衡(虽然当前只有一个节点)
- 添加了连接超时等生产环境实用参数
- 保留了完整的请求头信息
4.2 启动Nginx容器
bash复制docker run -d \
--name nginx-proxy \
--network nginx-tomcat-net \
-p 80:80 \
-v $(pwd)/nginx-conf:/etc/nginx/conf.d \
nginx:1.21
目录挂载说明:
- Linux/Mac使用
$(pwd)获取当前路径 - Windows需要改为绝对路径,如
D:/nginx-conf
检查Nginx配置是否正确:
bash复制docker exec nginx-proxy nginx -t
5. 验证与测试
5.1 基础功能验证
访问http://localhost应该能看到Tomcat默认页面。还可以通过以下命令测试:
bash复制curl -I http://localhost
应返回类似响应:
code复制HTTP/1.1 200 OK
Server: nginx/1.21.6
5.2 网络连通性测试
进入Nginx容器测试到Tomcat的连接:
bash复制docker exec -it nginx-proxy bash
curl http://tomcat-server:8080
这个测试验证了:
- 自定义网络的DNS解析功能正常
- 容器间通信无阻碍
6. 生产环境进阶配置
6.1 日志收集配置
修改Nginx配置增加日志格式:
nginx复制http {
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
}
启动容器时需要额外挂载日志目录:
bash复制-v $(pwd)/nginx-logs:/var/log/nginx
6.2 健康检查配置
在docker-compose.yml中添加健康检查:
yaml复制services:
tomcat:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 30s
timeout: 10s
retries: 3
7. 常见问题排查
7.1 502 Bad Gateway错误
可能原因及解决方案:
-
Tomcat容器未运行
docker ps检查容器状态docker logs tomcat-server查看日志
-
网络配置错误
docker network inspect nginx-tomcat-net检查容器是否在同一网络docker exec nginx-proxy ping tomcat-server测试连通性
7.2 静态资源加载异常
解决方案:
- 在Nginx配置中添加静态资源处理规则:
nginx复制location ~* \.(js|css|png|jpg)$ {
proxy_pass http://tomcat;
expires 30d;
}
- 检查Tomcat应用是否配置了正确的context path
8. 性能优化建议
- 连接池配置:
nginx复制upstream tomcat {
server tomcat-server:8080;
keepalive 32; # 保持长连接
}
- 缓存策略优化:
nginx复制location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_use_stale error timeout updating;
}
- Gzip压缩:
nginx复制gzip on;
gzip_types text/plain text/css application/json application/javascript;
我在实际项目中发现,这些优化措施能够将平均响应时间降低40%左右,特别是在高并发场景下效果更为明显。