2026 Nginx Proxy Manager 反代面板:一个端口管所有 Docker 服务
部署了十个 Docker 服务以后会遇到一个很头疼的问题:每个服务一个端口号。Immich 用 2283、Jellyfin 用 8096、FreshRSS 用 8080、Open WebUI 用 3000、AdGuard Home 用 3000——这么多端口根本记不住。每次想打开某个服务都要先想想”它是什么端口来着?“。而且还不仅仅是记不记得住的问题——大部分服务没有 HTTPS 加密,你在公网上访问时,账号密码和上传的内容都是明文传输的,任何人都能抓包看到。更烦人的是端口暴露在公网上,天天被各种自动扫描工具挨个探测,日志里全是扫描失败的记录,看得人心烦。
Nginx Proxy Manager(简称 NPM)就是来解决这些问题的。它提供了一个直观的 Web 界面,让你可视化配置反向代理规则——把 jellyfin.你的域名.com 转发到内网的 8096 端口,把 immich.你的域名.com 转发到 2283 端口,把 rss.你的域名.com 转发到 FreshRSS 的 8080 端口。所有流量统一走标准的 80 端口和 443 端口你只需要记住一个域名加不同的子前缀,不用记任何端口号。而且 NPM 能自动申请 Let’s Encrypt 的免费 SSL 证书,一键开启 HTTPS,地址栏直接出现安全锁图标。
配好之后整个体验就是:你在浏览器里输入 jellyfin.你的域名.com,HTTPS 自动加密,NPM 自动转发到内网的 Jellyfin 服务,一切都是无缝的。你甚至不用关心服务跑在哪个端口上,那些配置细节已经被 NPM 隐藏了。这跟用一个端口一个端口去记的体验差别非常大——就好像从记 IP 地址到记域名的跨越。
一、Docker 部署
一个 Compose 文件搞定:
services: npm: image: jc21/nginx-proxy-manager:latest container_name: npm restart: unless-stopped ports: - "80:80" - "443:443" - "81:81" volumes: - ./npm/data:/data - ./npm/letsencrypt:/etc/letsencrypt三个端口的作用:80 和 443 是公网入口——用户访问你的子域名时先走这两个端口。81 是 NPM 的管理界面。配置反代规则和 SSL 证书都在 81 端口上操作。
docker compose up -d首次访问 http://你的IP:81,用默认账号 admin@example.com / changeme 登录。登录后系统会强制要求修改邮箱和密码——用你自己的邮箱,密码不要简单。
二、配置第一条反代规则
配好 NPM 之后就可以开始把各个服务挂到域名下了。下面以配置 Jellyfin 为例,把整个流程走一遍。
第一步,配置域名 DNS。
去你的域名 DNS 管理后台(阿里云、腾讯云、Cloudflare 都可以),添加一条 A 记录。主机记录填 jellyfin,记录值填你服务器获取到的公网 IP。如果你的域名是 example.com,这条记录的效果就是 jellyfin.example.com 这个子域名会指向你的服务器公网 IP。DNS 解析生效后,从任何地方访问 jellyfin.example.com 都会找到你的服务器。这是最重要的前提——DNS 没配好后面所有步骤都是白做。
第二步,在 NPM 中添加反代规则。
登录 NPM 管理界面(端口 81),点 “Proxy Hosts” → “Add Proxy Host”。域名填 jellyfin.example.com。转发目标地址填 http://你的服务器内网IP:8096——因为 Jellyfin 容器监听的是 8096 端口。如果你把 NPM 和 Jellyfin 部署在同一台机器上,可以用 http://host.docker.internal:8096 或者直接填宿主机在局域网里的 IP 地址。
第三步,申请 SSL 证书。 切换到 SSL 标签页。选 “Request a new SSL Certificate”,勾选 “Force SSL”(强制 HTTPS——访问 HTTP 版本的域名时自动跳转到 HTTPS)。Let’s Encrypt 的证书申请是自动完成的——NPM 会向 Let’s Encrypt 证明你拥有这个域名的控制权,验证通过后自动签发证书。全程只需要几秒钟。证书有效期三个月,到期前 NPM 自动续期,不需要你操心。
第四步,保存并验证。
点 “Save” 保存。打开浏览器访问 https://jellyfin.example.com。地址栏出现安全锁图标,页面正常打开——配置成功了。现在 Jellyfin 通过标准的 HTTPS 端口访问了,不需要记 8096 这个端口号。
同样的步骤给每个需要外网访问的服务——Immich、FreshRSS、Open WebUI、AdGuard Home——重复一遍。全部配完之后你只需要记住 *.你的域名 这个模式,不用记任何端口号。
三、NPM 功能详解
| 功能 | 说明 |
|---|---|
| 强制 HTTPS | 每个反代规则都可以开启,HTTP 访问自动跳转到 HTTPS |
| HSTS | 告诉浏览器下次直接走 HTTPS,减少一次重定向 |
| 访问列表 | 限制特定 IP 段的访问,比如只让国内 IP 访问 |
| 限流 | 防止某个服务被大量请求打崩 |
| 缓存 | 对静态资源开启缓存,加速访问 |
| 自定义 Nginx 配置 | 高级用户可以加自定义的 Nginx 指令 |
日常场景下你只需要配域名、转发目标、SSL 证书三项就够了。其他功能用到的时候再说。不过有一点值得提前了解——NPM 支持在同一台服务器上管理多个域名。如果你有好几个域名都想指向这台服务器,直接在 NPM 里加新的 Proxy Host 就行,每个域名各自配自己的转发规则和 SSL 证书。比如 work.example.com 转发到你的工作项目,home.example.com 转发到你的家庭媒体服务。NPM 根据用户访问的域名自动路由到对应的端口和目录。
四、安全建议
| 建议 | 理由 |
|---|---|
| 管理面板不暴露公网 | NPM 的 81 端口只在内网或通过 Tailscale 访问。所有配置操作走内网,不给外人登录入口 |
| 非公开服务不走 NPM | 有些服务(比如 PVE 管理页面、数据库管理工具)不需要公网访问,直接用 Tailscale 组网访问更安全。参考Tailscale 教程 |
| 强制 HTTPS + HSTS | 每个反代规则都开启,一个不漏 |
| 定期检查访问日志 | NPM 记录每个域名的请求情况。发现异常 IP 频繁请求就加到黑名单里 |
| 用 Docker 管理 NPM | NPM 跑在 Docker 里,升级、备份、迁移都很方便。参考PVE 教程在虚拟机里跑 Docker |
五、NPM vs Cloudflare Tunnel
两者都可以解决外网访问自托管服务的问题,但适用场景不同:
| 维度 | Nginx Proxy Manager | Cloudflare Tunnel |
|---|---|---|
| 原理 | 在服务器上做反向代理和 SSL 终结 | 在服务器和 Cloudflare 之间建立加密隧道 |
| 是否需要公网 IP | 需要,必须有公网地址 | 不需要,只要服务器能出网就行 |
| 端口暴露 | 开放 80 和 443 端口 | 不开放任何入站端口,安全性更高 |
| 访问速度 | 直连,最快 | 经过 Cloudflare 节点中转,比直连慢一些 |
| 配置复杂度 | 低,全可视化界面 | 中等,需要用命令行安装和配置客户端 |
| 隐藏真实 IP | 不隐藏,DNS 解析暴露服务器 IP | 隐藏,用户只能看到 Cloudflare 的 IP |
怎么选: 如果有公网 IP,用 NPM 最简单,速度也最快。如果没有公网 IP(比如你的宽带是内网 IP),或者想隐藏服务器真实 IP 防止被直接攻击,用 Cloudflare Tunnel。两者也可以配合使用——NPM 管理服务转发和 SSL 证书,Cloudflare 做前端 CDN 加速和 DDoS 防护,走 Cloudflare 代理模式(点亮橙色云朵图标)。不过要注意国内网络环境下 Cloudflare 的 CDN 节点速度不一定理想,建议先测试延迟再决定是否启用。
六、常见问题
Q:Let’s Encrypt 证书申请失败?
最常见的原因是域名 DNS 的 A 记录还没生效。用 ping 你的域名 确认——如果返回的 IP 不是你服务器的公网 IP,说明 DNS 还没生效或者配错了。DNS 生效时间一般几分钟到几小时不等,耐心等一会儿再试。另外确认 80 端口没有被其他程序占用——运行 sudo lsof -i :80 检查,如果有其他程序占了 80 端口,NPM 就没法完成域名验证。
Q:配好了但浏览器报 502 错误?
NPM 转发目标地址填错了。检查目标地址的 IP 和端口是否正确,确认目标服务确实在运行。可以在 NPM 服务器上用命令测试:curl http://目标IP:端口。如果 curl 能拿到响应但浏览器报错,检查目标地址是不是填了 127.0.0.1——如果 NPM 和目标服务不在同一个容器网络里,不能用 localhost,要用宿主机 IP 或者容器名。
Q:用了 NPM 还需要 Tailscale 吗? 需要。NPM 管公网访问,Tailscale 管内网访问。PVE 管理页面、SSH 服务、数据库管理工具、家庭内部用的服务——这些不需要暴露到公网的服务走 Tailscale 更安全。大原则是:必须公网访问的走 NPM,其他全走 Tailscale。
Q:NPM 和 Caddy 比哪个好? Caddy 也是优秀的反代工具,它的优势是配置文件自动 HTTPS,不需要手动管理证书。NPM 的优势是可视化界面,适合不熟悉 Nginx 配置的用户。功能上两者差不多,选哪个看个人喜好——喜欢点鼠标的用 NPM,喜欢写配置的用 Caddy。
Q:多个域名指向同一个服务怎么做? 在 NPM 里创建多个 Proxy Host,每个配不同域名,转发目标都指向同一个服务地址就行。NPM 会根据请求的域名自动路由到对应的后端服务。同一个服务也可以有多个域名,比如给家庭内部用的短域名和给朋友访问的长域名。
延伸阅读
- Docker 换源避坑指南 — 部署前的必备准备
- Nginx Proxy Manager 反代面板 — 统一管理所有服务的访问入口
- 自建 RSS 信息流 — 彻底告别算法推荐
配好 NPM 之后,你再部署一个新服务时只需要做两件事:第一,确保服务只监听 127.0.0.1 地址,不直接暴露到公网;第二,在 NPM 里加一条反代规则配上 SSL 证书。全部域名统一走 HTTPS,不用再记端口号。久而久之你会发现自己已经完全忘了哪个服务跑在哪个端口上——也根本不需要记得。在浏览器里输入子域名就能访问,就像用商业软件一样自然。搭配本站的 Tailscale 组网方案一起用,公网走 NPM、内网走 Tailscale,所有远程访问问题一次解决。
推荐指数:⭐⭐⭐⭐⭐
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!