用 Nginx 配置反向代理(含多域名)

家里或服务器上跑了好几个服务,每个都占一个端口,用起来很不方便。用 Nginx 做反向代理,就可以通过不同的域名访问不同的服务,顺便统一加上 HTTPS。

这篇记录:

  • 单个服务的反向代理
  • 多个域名分别代理到不同服务
  • 不想手写配置时,可以用的图形化工具

准备

安装 Nginx:

1
sudo apt update && sudo apt install nginx

准备好 SSL 证书(Let’s Encrypt 或自签都行),本文放在:

1
2
/etc/nginx/cert/cert.pem
/etc/nginx/cert/key.pem

假设本机跑着这几个服务:

  • Node.js:127.0.0.1:3000
  • Flask:127.0.0.1:5000
  • 某个面板:127.0.0.1:8080

代理单个服务

新建配置文件:

1
sudo vim /etc/nginx/sites-available/myproxy.conf

把 sub1.example.com 代理到 127.0.0.1:8080:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 443 ssl http2;
server_name sub1.example.com;

ssl_certificate /etc/nginx/cert/cert.pem;
ssl_certificate_key /etc/nginx/cert/key.pem;

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

多个域名代理到不同服务

每个域名写一个 server 块就行,可以都放在同一个配置文件里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# Node.js(3000 端口)
server {
listen 443 ssl http2;
server_name node.example.com;

ssl_certificate /etc/nginx/cert/cert.pem;
ssl_certificate_key /etc/nginx/cert/key.pem;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

# Flask(5000 端口)
server {
listen 443 ssl http2;
server_name flask.example.com;

ssl_certificate /etc/nginx/cert/cert.pem;
ssl_certificate_key /etc/nginx/cert/key.pem;

location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

# 面板(8080 端口)
server {
listen 443 ssl http2;
server_name panel.example.com;

ssl_certificate /etc/nginx/cert/cert.pem;
ssl_certificate_key /etc/nginx/cert/key.pem;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

这些子域名都要先在 DNS 里解析到服务器的公网 IP。

启用配置

1
2
3
4
5
6
7
8
# 链接到 sites-enabled
sudo ln -s /etc/nginx/sites-available/myproxy.conf /etc/nginx/sites-enabled/

# 检查语法
sudo nginx -t

# 重新加载
sudo systemctl reload nginx

补充

HTTP 自动跳转 HTTPS

1
2
3
4
5
server {
listen 80;
server_name your_domain.com;
return 301 https://$host$request_uri;
}

防火墙放行

1
2
sudo ufw allow 80
sudo ufw allow 443

不想手写配置的话

服务一多,手动改配置文件也挺烦,可以试试图形化工具:

  • Nginx Proxy Manager:网页上填域名和转发地址就行,能自动申请 Let’s Encrypt 证书,用 Docker 部署。
  • 运维面板也带反向代理功能,比如 1Panel、宝塔面板。