Skip to content

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_net

3. 核心配置文件 ​

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: true

4.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

方舟 · Ark