nginx 反向代理指南
本页内容
反向代理位于应用前面,把访客的请求转发给它们。有了前置的 nginx,运行在某个端口上的 Node.js 应用、Docker 容器或管理面板就能变成 https://app.example.com,带有 HTTPS、正确的请求头,并且一切都在一个地方管理。
本指南一步步在 Ubuntu 上把 nginx 配置为反向代理:server 块、请求头、WebSockets、免费 HTTPS,以及你最可能遇到的错误。
反向代理有什么用
- 统一的公网入口。nginx 监听 80 和 443 端口,把每个域名或路径转发到对应的应用,应用本身从不直接暴露在互联网上。
- HTTPS 集中处理。证书由 nginx 负责;后面的应用可以在 localhost 上使用普通 HTTP。
- 一台服务器运行多个应用。
app.example.com、api.example.com和example.com/blog可以分别指向不同的服务。 - 附加功能:压缩、缓存、上传限制和访问规则,无需改动应用。
第 1 步:安装 nginx
sudo apt update sudo apt install nginx
打开 http://your-server-ip,应该能看到 nginx 欢迎页。如果你使用 ufw,用 sudo ufw allow 'Nginx Full' 放行网页流量。
确认你的应用正在运行,并且在服务器本机上可以访问,例如用 curl http://127.0.0.1:3000 测试。如果这一步失败,nginx 也会失败。
用完整 root 权限运行 nginx 和你的应用:HytHost KVM VPS 套餐 €2.92/月起。
查看 VPS 套餐第 2 步:创建代理 server 块
在 Ubuntu 上,每个站点在 /etc/nginx/sites-available/ 中有一个文件,通过 sites-enabled 中的链接启用。创建 /etc/nginx/sites-available/app.example.com:
server {
listen 80;
server_name app.example.com;
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;
}
}
启用它,测试配置并重新加载:
sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
把域名的 A 记录指向你的服务器,http://app.example.com 就会显示你的应用。重新加载前务必运行 nginx -t:它能在拼写错误让网站宕机之前发现问题。
请求头与结尾斜杠
Host传递访客请求的域名。没有它,nginx 会发送proxy_pass中的地址,依赖 host 生成链接的应用就会出错。X-Real-IP和X-Forwarded-For传递访客的 IP 地址。没有它们,每个请求看起来都来自127.0.0.1。X-Forwarded-Proto告诉应用访客是否使用了 HTTPS,避免出现循环重定向。
Ubuntu 的 nginx 软件包在 /etc/nginx/proxy_params 中自带这些行,所以 include proxy_params; 是一种简写。
结尾斜杠很重要。对于挂在某个路径下的应用:
location /app/ {
proxy_pass http://127.0.0.1:3000/;
}
端口后面带斜杠时,/app/login 到达应用时变成 /login。不带斜杠时,应用收到完整的 /app/login。
WebSockets
聊天应用、实时仪表盘和许多管理面板都使用 WebSockets,需要额外两个请求头。在 http 块中添加一次这个 map,例如放在新文件 /etc/nginx/conf.d/websocket.conf 中:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
然后在 location 中:
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 1h;
被代理的连接如果 60 秒内没有传输任何数据,nginx 就会关闭它;更长的 proxy_read_timeout 能让空闲的 WebSockets 保持打开。proxy_http_version 1.1 从 nginx 1.29.7 起才是默认值,而 Ubuntu 24.04 自带的是 1.24,所以请保留这一行。
第 3 步:用 Certbot 免费启用 HTTPS
sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/local/bin/certbot sudo certbot --nginx -d app.example.com
Certbot 会获取免费的 Let's Encrypt 证书,把 HTTPS 设置添加到你的 server 块,并可以把 HTTP 重定向到 HTTPS。它会自动续期证书;用 sudo certbot renew --dry-run 检查。更多证书相关内容见如何获取免费 SSL 证书。
修复 502、504 和 413 错误
| 错误 | 常见原因 | 解决方法 |
|---|---|---|
| 502 Bad Gateway | nginx 无法连接到应用:应用已停止、崩溃,或监听在其他端口或地址上 | 启动应用,用 curl http://127.0.0.1:PORT 检查端口,查看 /var/log/nginx/error.log |
| 504 Gateway Timeout | 应用超过 60 秒才响应 | 加快请求处理,或为该 location 调高 proxy_read_timeout |
| 413 Request Entity Too Large | 上传的文件超过 nginx 默认的 1 MB 限制 | 在 server 块中设置 client_max_body_size 50m; |
| 重定向循环 | 应用不知道访客使用了 HTTPS | 传递 X-Forwarded-Proto,并告诉应用它位于代理之后 |
每次修改后:先运行 sudo nginx -t,再运行 sudo systemctl reload nginx。
在 HytHost VPS 上运行
反向代理需要一台你能控制 80 和 443 端口的服务器。HytHost VPS 套餐基于 KVM,提供完整 root 权限、SSD 存储和 DDoS 防护;选择 Ubuntu 24.04,按上面的步骤操作即可。要在容器中运行应用?先参考如何在 Ubuntu 上安装 Docker 配置好 Docker,并把容器端口绑定到 127.0.0.1,这样只有 nginx 能访问它们。
常见问题
反向代理把请求转发给后面的一个或多个应用。负载均衡器是一种把请求分散到同一应用多个副本上的反向代理。nginx 两者都能做,用一个列出这些副本的 upstream 块即可。
nginx 无法连接到后面的应用。检查应用是否正在运行,并监听 proxy_pass 中的地址和端口,再查看 /var/log/nginx/error.log 了解具体原因。
如果应用运行在同一台服务器上,就不需要。nginx 为访客处理 HTTPS,并通过 127.0.0.1 上的普通 HTTP 与应用通信,数据不会离开这台机器。
为每个应用创建独立的 server 块,各自设置 server_name,例如 app.example.com 和 api.example.com,每个块用 proxy_pass 指向不同的端口。
可以。把每个容器的端口只发布在 127.0.0.1 上,再让 proxy_pass 指向它。这样容器不会暴露在公网上,这一点很重要,因为 Docker 发布的端口会绕过 ufw。
这篇指南对你有帮助吗?