🚀 使用 Docker Compose 部署 Nginx 反向代理服务
🚀 使用 Docker Compose 部署 Nginx 反向代理服务
本文将详细介绍如何使用 Docker Compose 部署 Nginx 作为反向代理服务器,实现多端口、多后端服务的统一管理和负载分发。
📝 项目简介
Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件代理服务器,其特点是占有内存少,并发能力强。通过 Docker 容器化部署,可以快速搭建和管理 Nginx 服务。
核心特点:
- 高性能:采用事件驱动架构,能够处理大量并发连接
- 低资源占用:内存消耗少,适合资源受限环境
- 反向代理:支持负载均衡和请求转发
- 配置灵活:通过配置文件实现复杂路由规则
- 静态文件服务:高效处理静态资源请求
🔧 部署前准备
系统环境要求
- 操作系统:Linux、Windows、macOS
- Docker 引擎:版本 20.10+
- Docker Compose:版本 2.0+
- 硬件资源:
- 内存:至少 512MB
- 存储空间:至少 1GB 可用空间
环境检查
-
检查 Docker 服务状态
bash systemctl status docker确保 Docker 服务处于active (running)状态 -
检查 Docker 版本
bash docker --version -
创建部署目录
mkdir -p /home/compose/nginx && cd /home/compose/nginx
⚙️ 配置 Docker Compose
准备配置文件
创建 docker-compose.yml 文件:
services:
nginx:
restart: always # 容器退出后自动重启(保障代理服务稳定)
container_name: nginx # 容器名称,便于管理(如查看日志、重启)
image: nginx # 官方 Nginx 镜像(默认 latest 版本,稳定可靠)
privileged: true # 特权模式:允许容器修改网络配置、访问宿主机资源(反向代理必需)
ports:
#- 444:444
#- 443:443
#- "81:80"
# 集群1端口:3000-3006(主机端口=容器端口,简化配置)
- 3000:3000
- 3001:3001
- 3002:3002
- 3003:3003
- 3004:3004
- 3005:3005
- 3006:3006
# 集群2端口:5000-5005(跳过 5004)
- 5000:5000
- 5001:5001
- 5002:5002
- 5003:5003
- 5005:5005
# 集群3端口:7000-7001
- 7000:7000
- 7001:7001
#- 9001:9001
#network_mode: 'host' # 注释:默认桥接模式,端口映射更灵活,host 模式无需端口映射但易冲突
volumes:
# 1. 静态文件目录:本地 ./html → 容器 /usr/share/nginx/html(默认静态页)
- "./html:/usr/share/nginx/html"
# 2. 自定义静态文件目录:本地 ./www → 容器 /var/www(可选,存放前端项目)
- ./www:/var/www
# 3. 日志目录:本地 ./logs → 容器 /var/log/nginx(访问日志、错误日志)
- "./logs:/var/log/nginx"
# 4. 主配置文件:本地 ./nginx.conf → 容器 /etc/nginx/nginx.conf(核心配置)
- "./nginx.conf:/etc/nginx/nginx.conf"
# 5. 证书目录:本地 ./cert → 容器 /etc/nginx/cert(启用 HTTPS 时使用)
- ./cert:/etc/nginx/cert
# 6. 虚拟主机配置:本地 ./conf.d → 容器 /etc/nginx/conf.d(反向代理规则)
- ./conf.d:/etc/nginx/conf.d
#/home/compose/nginx "./"当前目录下
#容器内的配置不变动,只需要在容器映射yml文件这里修改一下,指向路径就好了。
#- ./nginx:/etc/nginx
#- /wwwroot:/wwwroot
environment:
#- NGINX_PORT=80
- TZ=Asia/Shanghai # 时区同步(确保日志时间与本地一致)
#下面是搭建桥梁bridge而非host模式在这里不合适用。。。
# 注释:默认使用桥接网络,无需额外定义 networks
#networks:
#- nginx_web
#networks:
#nginx_web:
#driver: bridge
# 注释:volumes 已通过目录挂载实现,无需额外定义
#volumes:
#data:
关键配置说明
- 镜像选择:使用官方
nginx镜像 - 端口映射:将容器内多个端口映射到宿主机,支持不同服务访问
- 数据持久化:
./html:/usr/share/nginx/html:静态网页目录./logs:/var/log/nginx:日志目录./nginx.conf:/etc/nginx/nginx.conf:主配置文件./conf.d:/etc/nginx/conf.d:自定义配置目录- 时区设置:
TZ=Asia/Shanghai确保日志时间正确
🚀 启动与验证
启动服务
docker compose up -d
验证服务状态
-
检查容器运行状态
bash docker ps应该看到 nginx 容器处于Up状态 -
查看服务日志
bash docker compose logs -f -
测试端口连通性
curl http://localhost:3000
🔌 基础配置与使用
Nginx 主配置
创建 nginx.conf 文件:
user nginx;
worker_processes auto; # 自动适配 CPU 核心数,提升并发性能
error_log /var/log/nginx/error.log notice; # 错误日志路径与级别
pid /var/run/nginx.pid; # 进程 ID 存储路径
events {
worker_connections 1024; # 每个 worker 进程最大连接数,可根据需求调整为 51200
}
http {
include /etc/nginx/mime.types; # 加载 MIME 类型映射(如 .html 对应 text/html)
default_type application/octet-stream; # 默认 MIME 类型(未知文件类型)
# 日志格式定义(记录客户端 IP、请求方法、状态码等关键信息)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 访问日志使用 main 格式
sendfile on; # 启用零拷贝技术,提升文件传输效率
#tcp_nopush on; # 开启后会累积数据再发送,适合大文件传输,默认关闭
keepalive_timeout 65; # 客户端连接超时时间(秒),避免连接频繁建立/关闭
#gzip on; # 启用 Gzip 压缩,减少传输流量,需后端服务支持,默认关闭
include /etc/nginx/conf.d/*.conf; # 加载 conf.d 目录下的所有虚拟主机配置(核心!)
}
}
反向代理配置
在 conf.d/1.conf 中配置服务器集群:
示例:
# 集群1 - 指向 192.168.0.2
server {
listen 3000;
listen [::]:3000 ipv6only=on;
charset utf-8;
client_max_body_size 2G;
location / {
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $proxy_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_cache_bypass $http_upgrade;
proxy_pass http://192.168.0.2:3000;
}
}
# 集群2 - 指向 192.168.0.10
server {
listen 5000;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://192.168.0.10:5000;
}
}
# 集群3 - 指向 192.168.0.30
server {
listen 7000;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://192.168.0.30:11434;
}
}
完整:
# 集群1:转发到 192.168.0.2 服务器(3000-3006 端口)
server{
listen 3000;
listen [::]:3000 ipv6only=on; # 支持 IPv6
#server_name localhost docker.xieboke.net;
charset utf-8; # 启用 UTF-8 编码,避免中文乱码
#Allow large attachments
# 允许大文件上传(2G 上限,根据需求调整)
client_max_body_size 2G; # 适当调整文件大小的上限
#client_max_body_size 128M;
#目录别名转发
# 反向代理配置(核心:将 3000 端口请求转发到 192.168.0.2:3000)
location / {
# 反向代理缓存配置(关闭缓存,适合实时服务;需缓存可改为 on)
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
# 支持 WebSocket 连接(升级 HTTP 协议)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host; #这真是代理的好东西啊
#proxy_set_header Host $http_host;
# 传递请求头(让后端服务获取真实请求的 Host、IP)
proxy_set_header Host $proxy_host; # 修改转发请求头,让8080端口的应用可以受到真实的请求
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_cache_bypass $http_upgrade;
# 转发目标(需改为你的后端服务 IP:端口!)
proxy_pass http://192.168.0.2:3000;
}
# 错误页面配置(500/502 等错误时显示 50x.html)
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server{
listen 3001;
listen [::]:3001 ipv6only=on;
charset utf-8;
#Allow large attachments
client_max_body_size 2G; # 适当调整文件大小的上限
#目录别名转发
location / {
# 缓存配置(启用缓存,提升静态资源访问速度)
proxy_buffer_size 256k;
proxy_buffering on;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 2048m;
proxy_redirect off;
#proxy_set_header Host $host;#问题所在,没正确传递出httphost
# 传递真实请求头
proxy_set_header Host $http_host;
#proxy_set_header X-Real-IP '192.168.0.19';#设置为nginx所在的ip地址
#proxy_set_header X-Forwarded-Proto 'http';#从nginx访问的,只允许通过https,所以写死,不用$scheme了;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD; # 仅缓存 GET/HEAD 请求
proxy_cache_key $scheme$request_method$proxy_host$request_uri; # 缓存键定义
proxy_pass http://192.168.0.2:3001/; # 转发目标(需修改为你的后端)
}
}
# 省略 3002-3006、5000-5005 端口配置(与上述结构一致,核心修改 proxy_pass 目标)
server{
listen 3002;
listen [::]:3002 ipv6only=on;
charset utf-8;
#目录别名转发
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.2:3002/;
}
}
server{
listen 3003;
listen [::]:3003 ipv6only=on;
charset utf-8;
#目录别名转发
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.2:3003/;
}
}
server{
listen 3004;
listen [::]:3004 ipv6only=on;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.2:3004/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
#root html;
#}
}
server{
listen 3005;
listen [::]:3005 ipv6only=on;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.2:3005/;
}
}
server{
listen 3006;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.2:3006/;
}
}
#集群2
server{
listen 5000;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.10:5000/;
}
}
server{
listen 5001;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
proxy_set_header Host $host;
#proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.10:5001/;
}
}
server{
listen 5002;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
#proxy_pass http://192.168.0.10:5002/UI/Dashboard;
proxy_pass http://192.168.0.10:5002/;
}
}
server{
listen 5003;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.10:5003/;
}
}
server{
listen 5005;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.10:5005/;
}
}
#集群3
server{
listen 7000;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
#proxy_set_header Host $http_host;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.30:11434/;
}
}
# 集群3:7001 端口(支持跨域)
server{
listen 7001;
charset utf-8;
location / {
proxy_buffer_size 64k;
proxy_buffering on;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
proxy_max_temp_file_size 1024m;
proxy_redirect off;
#proxy_set_header Host $host;
#proxy_set_header Host $http_host;
#proxy_set_header Host $proxy_host; # 修改转发请求头,让8080端口的应用可以受到真实的请求
# 传递请求头(适配后端服务需求)
proxy_set_header Host http://192.168.0.30:11434/api;
#proxy_set_header Host http://192.168.0.19:7000/api; #堆上上面反代的ip还是回答Network Problem
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_convert_head off;
proxy_cache_methods GET HEAD;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
proxy_pass http://192.168.0.30:8080/; # 转发目标(需修改)
# CORS 跨域配置(允许前端跨域请求)
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token';
if ($request_method = 'OPTIONS') {
return 200; # 处理 OPTIONS 预检请求
}
}
}
配置优化建议
- 性能调优:
- 根据 CPU 核心数设置
worker_processes -
调整
worker_connections提高并发处理能力 -
缓存配置:
- 启用静态资源缓存
- 配置代理缓存减少后端压力
🛠️ 维护与管理
日常维护操作
- 服务启停 ```bash # 停止服务 docker compose down
# 启动服务 docker compose up -d
# 重启服务 docker compose restart ```
-
配置重载
bash # 进入容器重载配置 docker exec nginx nginx -s reload -
数据备份
bash # 备份配置和日志 tar -czf nginx-backup-$(date +%Y%m%d).tar.gz ./conf.d ./nginx.conf ./logs
监控与日志
1.查看实时日志
docker compose logs -f
2.访问日志分析
tail -f logs/access.log
3.错误日志监控
tail -f logs/error.log
🐛 常见问题排查
1. 端口冲突问题
问题现象:容器启动失败,提示地址已在使用中
解决方案:
# 检查端口占用
netstat -tulpn | grep :3000
# 修改冲突端口或停止占用进程
2. 代理配置错误
问题现象:502 Bad Gateway 错误
解决方案:
- 检查后端服务是否正常运行
- 验证 proxy_pass 地址是否正确
- 确认网络连通性
3. 权限问题
问题现象:配置文件加载失败
解决方案:
# 确保挂载目录权限正确
chmod -R 755 ./conf.d
chmod 644 ./nginx.conf
4. 静态资源访问问题
问题现象:CSS/JS 文件加载失败
解决方案:
- 检查 mime.types 包含
- 验证静态文件路径权限
- 确认 location 块配置正确
通过本教程,您应该已经成功部署并配置了 Nginx 反向代理服务。Nginx 的强大功能和灵活配置使其成为现代 Web 架构中的重要组件。如果在使用过程中遇到其他问题,可以参考 Nginx 官方文档或相关社区资源。