Nginx 反向代理与 HTTPS 配置速查
Node 应用一般不直接对外监听 80 / 443 端口,而是放在 Nginx 后面。这样做的好处是证书、压缩、静态文件、多站点都交给 Nginx 处理,应用本身只管业务。
下面是我自己部署时最常用的一份配置,按需修改域名和端口即可。
申请证书
用 certbot 申请免费的 Let's Encrypt 证书最省事:
# Ubuntu / Debian
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
证书有效期 90 天,certbot 安装后会自动添加续期任务,可以用下面的命令确认续期是否正常:
sudo certbot renew --dry-run
如果用的是云厂商的免费证书,下载 Nginx 格式的证书文件,放到服务器上,在配置里指定路径即可。
完整配置
# HTTP 全部跳转到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 10m;
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
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;
}
}
几个容易忽略的点
X-Forwarded-Proto:应用拿到的请求永远是 HTTP 的。不传这个头的话,应用会以为自己跑在 HTTP 下,生成的回调地址、Cookie 的 Secure 属性都会出错。Express 需要配合 app.set('trust proxy', 'loopback') 才会读取它。
client_max_body_size:默认只有 1MB,上传图片或提交长文章时会直接返回 413。
http2 写法:Nginx 1.25.1 之后推荐用单独的 http2 on;,旧写法 listen 443 ssl http2; 会有警告。
WebSocket:如果应用用到了 WebSocket,还需要加上:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
修改后
每次改完配置,先检查再重载,不要直接 restart:
sudo nginx -t && sudo systemctl reload nginx
nginx -t 能发现绝大多数语法错误,reload 不会中断现有连接。