开始输入,可搜索发票、服务、域名、工单,以及 更多...
Node.js、Python(Flask/Django/FastAPI)、Go 等应用通常监听在 127.0.0.1:3000 这类本地端口,不适合直接暴露到公网。本文讲解如何用 Nginx 反向代理把域名请求转发给后端应用,并正确处理 WebSocket、获取客户端真实 IP、用 certbot 配置免费 HTTPS,最后整理 502 Bad Gateway 的常见原因。命令适用于 Debian/Ubuntu 与 Rocky Linux/AlmaLinux。
先确保应用本身能在服务器本地访问,否则后面的反向代理一定会报 502。建议应用只监听 127.0.0.1,由 Nginx 统一对外,并用 systemd 或 pm2 等守护进程保证应用崩溃后自动重启。
# Debian / Ubuntu
apt update && apt install -y nginx
# Rocky Linux / AlmaLinux
dnf install -y nginx
systemctl enable --now nginx
# Make sure the backend app is listening locally (example: port 3000)
ss -lntp | grep 3000
curl -I http://127.0.0.1:3000
把域名解析到服务器 IP 后,新建 /etc/nginx/conf.d/app.conf。map 段让普通请求和 WebSocket 升级请求都能被正确处理;X-Forwarded-* 头把客户端 IP 和原始协议传给后端;proxy_read_timeout 调大可避免长连接或慢接口被提前断开。如需上传大文件,相应调大 client_max_body_size。
# /etc/nginx/conf.d/app.conf (included on Debian/Ubuntu and Rocky/AlmaLinux)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name app.example.com;
client_max_body_size 20m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_connect_timeout 10s;
proxy_read_timeout 300s;
}
}
每次修改后先用 nginx -t 检查语法再重载。Rocky/AlmaLinux 默认开启 SELinux,会阻止 Nginx 连接后端端口,需要打开 httpd_can_network_connect。防火墙放行 80 和 443(更多规则见“Linux 防火墙”教程)。
nginx -t && systemctl reload nginx
curl -I -H "Host: app.example.com" http://127.0.0.1
# Rocky/AlmaLinux (SELinux): allow Nginx to connect to backend ports
setsebool -P httpd_can_network_connect 1
# Open HTTP/HTTPS in the firewall
ufw allow 'Nginx Full' # Debian/Ubuntu with ufw
firewall-cmd --permanent --add-service=http --add-service=https
firewall-cmd --reload # Rocky/AlmaLinux
经过反向代理后,应用看到的来源 IP 都是 127.0.0.1。Nginx 已经通过 X-Real-IP 和 X-Forwarded-For 传递真实 IP,还需要让应用框架“信任”本机代理。如果 Nginx 前面还有 CDN 或负载均衡,则要在 Nginx 中用 real_ip 模块还原,只信任 CDN 的地址段,防止伪造。
// Node.js / Express: trust the proxy on localhost
app.set('trust proxy', 'loopback');
// req.ip now returns the real client IP
# Python Flask / any WSGI app
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
# Gunicorn
gunicorn --bind 127.0.0.1:8000 --forwarded-allow-ips="127.0.0.1" app:app
# Only if Nginx itself sits behind a CDN or load balancer (http or server block):
set_real_ip_from 203.0.113.0/24; # the CDN / LB address ranges
real_ip_header X-Forwarded-For;
real_ip_recursive on;
certbot 的 nginx 插件会自动申请 Let's Encrypt 证书、在配置中加入 443 监听,并用 --redirect 把 HTTP 跳转到 HTTPS。申请前请确认域名已解析到本机且 80 端口可从公网访问。证书有效期 90 天,安装后会自动续期。
# Debian / Ubuntu
apt install -y certbot python3-certbot-nginx
# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release && dnf install -y certbot python3-certbot-nginx
certbot --nginx -d app.example.com --redirect -m [email protected] --agree-tos --no-eff-email
# Renewal runs from a systemd timer; test it:
certbot renew --dry-run
systemctl list-timers | grep -i certbot
X-Forwarded-Proto,请按步骤 4 配置信任代理。502 表示 Nginx 无法从后端拿到正常响应。先看 Nginx 错误日志,根据关键字判断:连接被拒绝说明应用没运行或端口不对;Permission denied 多为 SELinux;还要注意 Node 17 以上版本中 localhost 可能解析为 IPv6 的 ::1,导致应用只监听 [::1]:3000,而 Nginx 连接的是 127.0.0.1。
tail -n 50 /var/log/nginx/error.log
# connect() failed (111: Connection refused) -> app stopped or wrong port
# connect() ... (13: Permission denied) -> SELinux: setsebool -P httpd_can_network_connect 1
# upstream prematurely closed connection -> app crashed / restarted
# upstream timed out (110) -> app too slow: raise proxy_read_timeout or fix the app
systemctl status myapp
journalctl -u myapp -n 100 --no-pager
ss -lntp | grep -E ':3000|:8000' # 127.0.0.1:3000 vs [::1]:3000 ?
检查是否设置了 proxy_http_version 1.1 以及 Upgrade/Connection 两个头;如果前面还有 CDN,需要在 CDN 端开启 WebSocket 支持。空闲连接默认 60 秒断开,可调大 proxy_read_timeout 或让应用发送心跳。
可以。每个域名写一个 server 块,指向不同端口即可;也可以在同一域名下用不同 location 路径转发。如果需要每个站点使用独立 IP,可参考“每站独立 IP(Nginx)”教程。
504 表示后端响应超时。请优化慢请求,或适当调大 proxy_read_timeout,并检查应用日志是否卡在数据库或外部接口。
如果按以上步骤操作后问题仍未解决,请提交工单联系 IMIDC 7×24 技术支持,并附上服务器 IP、系统版本、执行过的命令和完整报错信息,方便工程师快速定位。