Nginx Proxy Manager 是入口控制台,不是把所有内网服务都推到外面的理由。

\n
我在家里部署 Nginx Proxy Manager,最主要的目的不是省几行 Nginx 配置,而是把入口、证书、上游服务和访问记录集中管理。家庭服务器的服务一多,端口表很快会乱;每个服务都自己处理 HTTPS 和域名,也会让续期、备份、排障变得分散。NPM 的价值是收口,但收口之后仍然要控制哪些服务真的需要入口。

先分清三个入口

NPM 常见端口有三类:80 用于 HTTP 入口和证书验证,443 用于 HTTPS 入口,81 是管理面板。这三类风险完全不同。我不会把 81 当普通 Web 页面处理,它只应该给内网、运维设备或受控访问方式使用;80/443 面向的是被代理服务,也需要按服务敏感度逐个判断。

在 Compose 里我会显式写出端口,不让面板默认行为替我决定。管理端口如果只在内网使用,可以只绑定到局域网地址,或者通过防火墙限制来源。入口端口则交给统一反代,内部服务尽量不要再暴露额外宿主机端口,减少“明明走了反代,实际还有旁路入口”的情况。

services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    container_name: npm
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

上游服务写清健康状态

我配置 Proxy Host 时优先使用 Docker 网络里的服务名和容器内端口,例如 app:8080,而不是宿主机映射端口。这样容器重建、宿主机端口调整时,反代关系更稳定。需要 WebSocket、长连接或大文件上传的服务,会单独记录对应的开关和超时时间,避免升级后只记得“之前能用”。

上游健康不能只看 NPM 页面显示在线。我会从 NPM 容器里直接访问上游:docker exec npm curl -I http://app:8080/health,再从局域网访问最终域名。前者验证容器网络,后者验证 DNS、证书和代理链路。两条路径分开测,能快速判断问题在上游应用、Docker 网络、证书还是外部入口。

对于没有健康接口的旧服务,我会至少准备一个稳定的只读页面作为探针,并记录它为什么能代表服务可用。只看 TCP 端口开放不够,因为应用可能已经卡在数据库连接、初始化迁移或登录后端。反代入口的健康判断越贴近真实使用,收到故障反馈时越不容易误判。

新增反代规则时,我会先用临时域名或本机 hosts 做验证,再切到正式域名。这样可以提前测完 Host 头、上游端口、路径改写和 WebSocket,不会把半成品入口直接交给日常使用。

证书和反代配置是一组资产

NPM 的 dataletsencrypt 目录必须一起备份。data 里有代理规则、账号、数据库和自定义配置,letsencrypt 里有证书和续期记录。只备份其中一个,恢复时可能出现页面还在、证书丢了,或者证书还在、规则没了的尴尬状态。

我会在升级或迁移前停掉容器,打包这两个目录,并记录当前镜像版本。恢复演练时不是只看容器能启动,而是挑一个真实域名访问,确认 301/302、HTTPS、上游页面、WebSocket 或上传接口都正常。入口服务一旦坏掉,会影响多个后端,所以它的恢复验证要比普通小服务更严格。

日志要能定位是哪一跳

反代问题常见现象很相似:502、504、证书错误、登录循环、静态资源打不开。排障时我会先看 NPM 日志里的目标上游、状态码和请求 Host,再看上游容器日志。502 多半是上游不可达或端口写错,504 多半是超时或上游卡住,登录循环可能是反代头、协议或 Cookie 域配置不一致。

NPM 很适合做家庭入口中心,但它不是安全边界的全部。管理面板要单独保护,上游服务要最小暴露,dataletsencrypt 要成组备份。真正稳定的反代不是页面上有很多绿色条目,而是每个条目都知道为什么开放、怎么恢复、坏了从哪一跳开始查。

最后修改:2026 年 06 月 13 日
如果觉得我的文章对你有用,请随意赞赏