还在手写Nginx配置?我用Nginx Proxy Manager把域名、HTTPS和反代全放进网页里
前言
我以前配反向代理最烦的不是写第一份nginx.conf,而是后面服务越来越多以后,每加一个域名都要再改一段配置。
HTTP转HTTPS、证书申请、WebSocket、不同后端端口,全都堆在配置文件里。哪次少一个括号或者改错一个路径,重新加载Nginx时才发现问题。
所以这次我直接换成了Nginx Proxy Manager。
它还是Nginx做底层,但常用操作都放进Web页面:填域名、填目标IP和端口、按需要开SSL,然后保存。家里没有公网IP的话,再让cpolar把NPM的80端口送到公网。
下面从Docker部署开始,再分别做域名反代、HTTPS和/app/路径转发,把最常用的几种玩法跑一遍。

1.Nginx Proxy Manager到底解决什么问题?
Nginx Proxy Manager(NPM)是一个基于Nginx的开源反向代理管理工具。它把常见的域名转发、SSL证书、访问控制等配置做成Web界面,适合不想长期手写nginx.conf、又需要统一管理多个Web服务的人。
- 域名反向代理(将 yourdomain.com 指向内网服务如 192.168.1.100:3000)
- 自动申请和续期 Let’s Encrypt 免费 SSL 证书(一键启用 HTTPS)
- 强制 HTTPS、HTTP/2、HSTS 等安全设置
- 访问控制(IP 白名单、基础认证)
- 多用户支持与权限管理
传统手写Nginx为什么容易出错?
传统使用 Nginx 做反向代理时,你需要:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://192.168.1.50:8080;
proxy_set_header Host $host;
}
}
除了反向代理本身,还要继续处理HTTPS、证书续期、WebSocket和访问控制。服务一多,配置文件会越来越难维护。
NPM把这类常见操作集中到图形界面:
域名 → 目标主机/IP → 目标端口 → 按需配置SSL和访问策略
常用功能
| 可视化代理主机管理 | 添加/编辑/删除代理规则,支持 WebSocket、自定义头部等 |
| 自动 SSL 证书 | 集成 Let’s Encrypt,支持 HTTP 和 DNS 两种验证方式 |
| 强制 HTTPS | 自动将 HTTP 请求重定向到 HTTPS |
| 访问控制 | 可为每个代理设置 Basic Auth(用户名/密码)或 IP 限制 |
| Docker 原生支持 | 官方提供 Docker 镜像,一键部署 |
适合哪些场景?
- 给家里的 NAS、Home Assistant、Pi-hole 添加域名和 HTTPS
- 在一台云服务器上托管多个 Web 服务(如博客、Wiki、监控系统),通过不同域名区分
- 快速为测试环境暴露公网地址(配合内网穿透)
部署前要注意
- 如果希望NPM自己通过HTTP Challenge申请Let’s Encrypt证书,域名必须能从公网正确访问到NPM的80端口;也可以使用DNS Challenge;
- 直接作为公网反向代理入口时,80/443通常需要正确映射或放行;
- 管理端口81不要直接裸露到公网,管理员账号和密码要单独保护。
它比较适合家庭实验室、NAS、自建服务和中小规模Web入口管理。
2.使用Docker Compose部署Nginx Proxy Manager
先创建一个单独目录保存Compose文件、NPM数据和证书:
mkdir nginx-proxy-manager
cd nginx-proxy-manager
2.1 推荐:使用SQLite的简化部署
当前官方安装文档默认使用SQLite,不需要额外数据库容器。创建docker-compose.yml:
2026版本说明:截至2026年10月,Nginx Proxy Manager当前最新版为2.16.0,官方安装页也使用这个版本号。本文新稿把镜像固定到2.16.0,避免latest未来变化后导致复现结果不一致。
services:
app:
image: 'jc21/nginx-proxy-manager:2.16.0'
restart: unless-stopped
ports:
– '80:80'
– '81:81'
– '443:443'
volumes:
– ./data:/data
– ./letsencrypt:/etc/letsencrypt
如果你有独立数据库管理需求,也可以使用MySQL/MariaDB。
2.2 可选:使用MariaDB
当前官方文档仍支持MySQL/MariaDB。下面按2026年官方示例整理为MariaDB容器方式:
services:
app:
image: 'jc21/nginx-proxy-manager:2.16.0'
restart: unless–stopped
ports:
– '80:80'
– '443:443'
– '81:81'
environment:
TZ: "Asia/Shanghai"
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "请改成强密码"
DB_MYSQL_NAME: "npm"
volumes:
– ./data:/data
– ./letsencrypt:/etc/letsencrypt
depends_on:
– db
db:
image: 'linuxserver/mariadb'
restart: unless–stopped
environment:
MYSQL_ROOT_PASSWORD: '请改成独立的Root强密码'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: '请与上面的DB_MYSQL_PASSWORD保持一致'
TZ: 'Asia/Shanghai'
volumes:
– ./mariadb:/config

保存Compose文件后启动容器:
docker-compose up -d
docker compose up -d

容器启动后,通过http://服务器IP:81进入Nginx Proxy Manager管理界面:

首次初始化后,创建或登录管理员账号,并立即使用独立强密码。

登录成功后即可进入管理面板。

管理面板中还可以继续配置代理主机、证书、访问列表等功能。

3.先准备一个外部访问域名或公网入口
Proxy Host需要根据请求中的Host/域名把流量转发到不同后端,因此在配置反向代理前,需要先确定外部访问入口。
原稿这里没有直接使用自有域名解析,而是通过cpolar先获得一个固定公网子域名,再把请求送到本地NPM的80端口。
3.1 cpolar在这里负责什么?
本文使用cpolar把NPM的80端口映射到公网,让没有公网IP的本地服务器也能收到来自外部域名的HTTP请求。
3.2 安装cpolar
执行原稿提供的一键安装命令:
sudo curl https://get.cpolar.sh | sh

安装后检查cpolar服务状态:
sudo systemctl status cpolar

cpolar启动后,通过IP:9200进入Web管理界面并登录账号:
登录后即可创建和管理隧道。

3.3 创建固定公网子域名并指向NPM
如果希望长期使用同一个公网入口,可以按原稿配置固定二级子域名。

进入“预留”,选择保留二级子域名,地区按原稿选择China Top,名称可以自定义。原稿示例为npm1。

随后进入“隧道管理 → 创建隧道”,把公网入口映射到NPM的80端口:
- 隧道名称:可自定义,本例使用了:nginx,注意不要与已有的隧道名称重复
- 协议:http
- 本地地址:80
- 域名类型:固定二级子域名
- Sub Domain:填写保留成功的二级子域名
- 地区:选择China Top

创建完成后,在“在线隧道列表”中可以看到固定公网地址。后面的Proxy Host就使用这个Host名称来匹配请求。

4.配置Proxy Host反向代理
4.1 添加一个Proxy Host
进入Hosts → Proxy Hosts → Add Proxy Host,开始创建反向代理规则:


Details页需要填写:
Domain Names :填写网站域名,需要上面做好DNS解析,把域名绑定到服务器IP
Scheme : 选择HTTP或HTTPS。默认http即可,除非有自签名证书
Forward Hostname/IP :填写要代理到的目标主机名或IP地址,或者Docker容器内部IP(NPM和程序服务在同一台服务器上)
Forward Port:填写目标主机的端口号,这里是NPM管理界面81端口
Cache Assets :缓存,根据需求选择打开
Block Common Exploits: 阻止常见的漏洞,根据需求选择打开
Websockets Support :WS支持,根据需求选择打开
Access List: NPM自带的一个限制访问功能
原稿第一个示例把npm1.cpolar.top转发到192.168.42.140:81,也就是NPM自己的管理界面。这个示例能说明反代流程,但真实使用时更建议优先代理业务服务,不要把81管理端口长期公开。

填写完成后保存Proxy Host。


如果规则匹配正常,就可以通过公网Host访问对应后端。

第二个示例把请求转发到内网192.168.52.213:3080,这更接近实际使用:NPM只做统一入口,真正业务运行在其他端口或主机上。

保存后即可通过外部Host访问这个3080服务。

4.2 什么时候需要在NPM里申请SSL证书?
如果你使用的是自己的域名,并且流量直接到达NPM的80/443端口,可以继续在NPM里申请Let’s Encrypt证书。
如果前面用的是cpolar HTTPS地址:外部浏览器与cpolar公网入口之间已经是HTTPS,通常不需要再为同一个cpolar子域名在NPM里重复申请证书。NPM里的Let’s Encrypt更适合你自己拥有并控制DNS的域名,或者真正由NPM承担TLS终止的场景。

在SSL页选择申请新的证书,填写邮箱、同意条款,并按需启用Force SSL。

证书签发成功后,浏览器即可通过HTTPS访问。

4.3 进阶:把/app/路径转发到另一个后端
原稿还演示了子路径转发:把https://npm1.cpolar.top/app/代理到内网192.168.50.213:9090。

进入对应Proxy Host的高级配置。

先用rewrite规则去掉/app/前缀:
rewrite ^/app/?(.*)$ /$1 break;


再补一条/app到/app/的重定向:
location = /app {
return 301 https://$host/app/;
}

保存后访问https://npm1.cpolar.top/app/即可测试。需要注意,并不是所有Web应用都天然支持部署在子路径下;如果页面里的静态资源或回调地址仍指向根路径,还需要在目标应用中额外设置Base URL或Path Prefix。

总结
搭完以后,我觉得Nginx Proxy Manager最大的价值不是“以后不用学Nginx”,而是终于不用每加一个服务就复制一大段配置。
域名、目标IP、目标端口、WebSocket、SSL都能在一个页面里看。以后家里的NAS服务、测试站点或者内网工具越来越多,先到NPM里加一条Proxy Host就行。
没有公网IP时,cpolar负责把外部请求送进来;NPM再根据域名或路径决定后面到底转给谁。两层职责分开以后,思路反而清楚很多。
不过SSL这里别重复折腾:如果你用的本来就是cpolar提供的HTTPS公网地址,外层已经有TLS;真要让NPM自己管证书,更适合使用自己拥有并能控制DNS的域名。
对经常自建服务的人来说,这种“统一入口 + 图形化反代”的爽点,比单纯少写几行配置更实际。
网硕互联帮助中心







评论前必须登录!
注册