在部署 Web 服务时,我们通常不会让应用直接暴露在公网端口上,而是通过 Nginx 做一层反向代理。这样既能统一入口、做负载均衡,也能集中管理 SSL 证书、静态资源缓存与访问控制。

本文基于我实际部署生产环境的经验,从零开始完整配置 Nginx 反向代理 + HTTPS,覆盖以下内容:

  • 反向代理与正向代理的区别
  • Nginx 安装与基础配置结构
  • 反向代理一个 Node.js 服务
  • HTTP 自动跳转 HTTPS
  • 静态资源缓存与 Gzip 压缩
  • 多站点共存的 server 块配置

一、反向代理与正向代理

正向代理代表客户端去访问服务器,我们常用的 VPN 就是典型的正向代理;反向代理则是代表服务器接收客户端请求,对外隐藏后端真实地址。Nginx 最常见的用途就是反向代理。

反向代理模式下,客户端只能看到 Nginx 的地址,后端服务可以只监听内网地址,从而提升安全性。

二、安装与目录结构

以 Ubuntu 系统为例,安装 Nginx:

# 更新软件源并安装
sudo apt update
sudo apt install -y nginx

# 检查版本
nginx -v

# 启动并设置开机自启
sudo systemctl enable --now nginx

Nginx 的配置文件默认位于 /etc/nginx/,核心结构如下:

/etc/nginx/
├── nginx.conf          # 主配置文件
├── sites-available/    # 站点可用配置
├── sites-enabled/      # 站点启用配置(软链接)
└── conf.d/             # 全局配置片段

三、配置反向代理

假设我们有一个 Node.js 服务运行在 127.0.0.1:3000,现在用 Nginx 在 80 端口对外提供服务。在 sites-available/ 下创建配置文件:

sudo vim /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name example.com;

    # 反向代理到 Node.js
    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }

    # 静态资源由 Nginx 直接返回,减轻后端压力
    location /static/ {
        alias /var/www/myapp/static/;
        expires 30d;
    }
}

启用站点并重新加载配置:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t          # 测试配置语法
sudo systemctl reload nginx

注意 proxy_set_header X-Real-IP 等头信息,它们能让后端拿到客户端真实 IP,这对日志分析和风控非常重要。

四、HTTP 自动跳转 HTTPS

为了让所有用户强制走 HTTPS,可以增加一个 80 端口的 server 块做 301 跳转:

# 强制跳转 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 站点
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

使用 nginx -t 测试后重载即可生效。推荐用 Let's Encrypt 的 certbot 自动申请并续期证书,避免手动维护过期问题。

五、静态资源缓存与 Gzip 压缩

对静态资源启用缓存可以显著提升页面加载速度:

# 全局启用 gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
gzip_min_length 1024;

server {
    # 带 hash 的文件名可长期缓存
    location /assets/ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

配合前端构建工具输出的带内容 hash 文件名,既能保证缓存命中率,又能在发版时自动更新缓存。

六、多站点共存

同一台服务器可以同时运行多个站点,只需为每个域名创建一个 server 块:

# 站点 A
server {
    listen 80;
    server_name a.com;
    location / { proxy_pass http://127.0.0.1:3000; }
}

# 站点 B
server {
    listen 80;
    server_name b.com;
    location / { proxy_pass http://127.0.0.1:4000; }
}

Nginx 会根据 Host 请求头自动匹配对应的 server 块,互不干扰。

七、常见问题排查

  • 502 Bad Gateway:后端服务未启动或端口错误,检查 proxy_pass 地址
  • 504 Gateway Timeout:后端响应超时,可调整 proxy_read_timeout
  • 权限不足:Nginx 工作进程默认是 www-data 用户,需保证静态目录权限正确
  • 配置不生效:修改配置后记得 nginx -t 测试并 reload

小结

Nginx 反向代理是生产环境部署的基石。掌握 server 块、proxy_pass、SSL 与缓存配置,就能轻松应对大多数 Web 服务的部署需求。建议将配置放在版本控制中管理,方便回滚和团队协作。