Appearance
Nginx 共享网关与反向代理配置指南
目标:在单台服务器上运行多个项目时,构建一个轻量、可扩展的统一流量入口(Hub Nginx)。
策略:不依赖复杂的 UI 管理工具,回归原生的 Nginx 配置文件管理,以获得最大的灵活性和“配置即代码”的能力,便于版本控制与迁移。
1. 目录结构规范
建议在服务器上创建一个专门的网关目录(如 /opt/hub-nginx 或 ~/hub-nginx),所有项目共享此网关。
text
hub-nginx/
├── docker-compose.yml # 编排文件
├── nginx.conf # 主配置文件 (通用优化)
├── conf.d/ # 子站点配置目录 (核心)
│ ├── default.conf # 默认站点 (处理非法 IP 访问)
│ ├── app1.conf # 子项目 A 的反代配置
│ └── app2.conf # 子项目 B 的反代配置
├── ssl/ # SSL 证书集中存放目录
├── logs/ # Nginx 日志目录
└── static/ # 静态资源 (如 404 页面, ACME 验证文件)2. Docker Compose 部署配置
创建 docker-compose.yml,使用官方 Alpine 镜像,并将配置、证书、日志挂载到宿主机。
yaml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: hub-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
# 配置文件映射
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf.d:/etc/nginx/conf.d:ro
# 证书映射
- ./ssl:/etc/nginx/ssl:ro
# 日志映射
- ./logs:/var/log/nginx
# 静态资源映射 (用于存放验证文件或公共静态页)
- ./static:/usr/share/nginx/html/static:ro
networks:
- proxy_net
networks:
proxy_net:
name: proxy_net
# 设置为外部网络,方便其他子项目的容器接入
external: true⚠️ 启动前准备: 由于设置了 external: true,在第一次启动前,必须手动创建这个 Docker 网络:
bash
docker network create proxy_net3. 核心配置文件
3.1 主配置 nginx.conf
保持主配置文件简洁,只做全局优化,业务逻辑通过 include 加载。
nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
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" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# 包含所有子站点的配置
include /etc/nginx/conf.d/*.conf;
}3.2 默认拦截配置 conf.d/default.conf
处理非法域名扫描或直接通过 IP 的访问,直接返回 444(关闭连接)或 403,保护服务器安全。
nginx
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
# 必须提供一个默认证书以满足 SSL 握手,否则 Nginx 无法启动
# 可以使用自签名的 dummy 证书
ssl_certificate /etc/nginx/ssl/dummy.crt;
ssl_certificate_key /etc/nginx/ssl/dummy.key;
# 健康检查端点 (可选)
location /health {
return 200 'healthy';
}
# 拒绝其他所有未匹配域名的访问,直接断开连接
location / {
return 444;
}
}4. 接入子项目实战 (以 AppA 为例)
假设你在服务器上部署了另一个项目 AppA(容器名为 appA-server),你想通过 app.example.com 访问它。
4.1 子项目接入网络
首先,确保 AppA 的 docker-compose.yml 加入了 proxy_net 网络:
yaml
version: '3.8'
services:
web:
image: your-app-image
container_name: appA-server
# 不需要暴露 ports,通过内网通信
networks:
- proxy_net
networks:
proxy_net:
external: true4.2 配置反向代理
在网关的 conf.d/ 目录下新建 appa.conf:
nginx
server {
listen 80;
server_name app.example.com;
location / {
# 直接使用子项目的容器名作为地址
proxy_pass http://appA-server:80;
# 传递标准 Header
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;
}
}4.3 重载配置生效
修改完成后,无需重启网关容器,只需执行热重载命令即可:
bash
docker exec hub-nginx nginx -t # 测试配置是否正确
docker exec hub-nginx nginx -s reload # 热重载配置5. 日常运维命令速查
bash
# 1. 启动网关
docker compose up -d
# 2. 实时查看访问日志
docker compose logs -f nginx
# 3. 查看最后 100 行错误日志
tail -n 100 logs/error.log