nginx-proxy-manager-zh 完整指南:从零搭好你的自托管服务反向代理网关
【免费下载链接】nginx-proxy-manager-zh基于nginx-proxy-manager翻译的中文版本项目地址: https://gitcode.com/gh_mirrors/ng/nginx-proxy-manager-zh
服务器上自托管服务多了,Jitsi、Gitea、Grafana 的域名和证书各管各的,改一行 Nginx 配置就头大。nginx-proxy-manager-zh 是一款中文界面的 Nginx 反向代理管理工具:代理规则、HTTPS 证书自动签发与续签、IP 黑白名单,全在浏览器表单里点完,不用手写 conf。本文从部署讲到排障,一次跑通。
📍 工具定位:给自托管服务装一个浏览器里的网关
一句话:它把 Nginx 的反向代理能力包进一个 Docker 容器里,你在网页表单里点什么,它就生成对应的 conf 并热加载,顺便把 Let's Encrypt 证书的签发、续签全托管掉。这个中文版本基于官方 nginx-proxy-manager 构建,只替换了前端界面,所以功能与英文版完全一致,菜单、提示、文档全是中文。
它适合谁:
- 自托管玩家 / 家庭实验室:一堆容器服务想统一挂域名、上 HTTPS,但不想维护一堆 conf 文件;
- 小团队运维:需要给内网服务加 IP 白名单、基本认证这类访问控制,且要留审计痕迹;
- 对 Nginx 半生不熟的人:常用场景(WebSocket、强制 HTTPS、HSTS、自定义 location)都有勾选框。
选型一句话对比:
| 你的情况 | 比较合适的选择 |
|---|---|
| 两三个服务,愿意写配置 | 直接手写 Nginx 或 Caddy,最灵活 |
| 几十个服务、要界面、要中文 | nginx-proxy-manager-zh |
| 服务已经全部跑在 K8s 上 | 直接用 ingress-nginx 等 Ingress 方案 |
🔍 一图看懂:一次请求是怎么流转的
这个容器里其实跑着两套系统:面向公网的 Nginx(负责代理 80/443 流量)和面向你的管理端(81 端口的 Web UI + Express API + 数据库)。
【业务流量】 浏览器 ──80/443──▶ Nginx ──按域名匹配──▶ 内网服务(Jitsi / Gitea / Grafana …) ▲ │ 由模板渲染出的 conf 驱动 【管理流量】 管理界面(81) ──▶ Express API ──▶ 数据库(SQLite 默认) 保存时:模板渲染 → nginx -t 校验 → 通过才 reload注意最下面那行:每次你在界面点保存,都会走"模板渲染 →nginx -t语法校验 → reload"的流程;校验不通过就自动回滚,并把这个主机在界面上标为离线,而不是让一台错误配置把你整站打挂。这是它比手写 conf 安心得多的核心原因。
🛠️ 快速上手:3 步跑起中文镜像
第 1 步:准备环境
装好 Docker 和 Docker Compose,然后确认宿主机80、443、81 三个端口空闲(81 是管理界面,若被占用可改成8181:81)。镜像支持 amd64 / arm64 / armv7,树莓派可以直接跑。
国内网络拉取
chishin/nginx-proxy-manager-zh镜像慢的话,先在 Docker 配置里加镜像加速器再拉,别反复重试。
第 2 步:写 compose 文件
services: app: image: chishin/nginx-proxy-manager-zh:release # 中文界面镜像 restart: unless-stopped ports: - "80:80" # 公网 HTTP(Let's Encrypt 验证也要用它) - "443:443" # 公网 HTTPS - "81:81" # 管理界面,只建议对可信网络开放 volumes: - ./data:/data # 数据库、JWT 密钥,务必持久化 - ./letsencrypt:/etc/letsencrypt # 证书存放,重建容器不丢两个数据卷是唯一的"家当":备份好./data和./letsencrypt,换机器迁移就靠它们。
第 3 步:启动并完成首次登录
docker compose up -d # 首次初始化要几分钟:生成密钥、建表、创建管理员 docker compose ps # 确认容器 healthy浏览器访问http://服务器IP:81,用默认账号登录后会强制要求改邮箱和密码,别跳过——这个邮箱用来收证书到期提醒:
Email: admin@example.com Password: changeme如果想跳过首次改密流程,可以在 compose 里预设:
INITIAL_ADMIN_EMAIL和INITIAL_ADMIN_PASSWORD两个环境变量。
⚙️ 能力拆解:四个干活的模块
🧩 能力一 | 代理主机:一个表单暴露一个内网服务
能做什么:把"域名 → 内网容器:端口"映射成一条反向代理规则;勾选框覆盖 WebSocket、缓存、已知漏洞拦截;还能加自定义 location(比如把/api单独转发给另一个后端)、并在"高级配置"里注入原生 Nginx 指令。
什么时候用:暴露任何 Web 服务时的默认选择。项目里还有三种伴生主机类型:
| 类型 | 用途 |
|---|---|
| 代理主机 | 真正的反向代理 |
| 重定向主机 | 只做 301/302/308 跳转(比如裸域跳www) |
| 流主机 | 直接转发 TCP/UDP 端口(非 HTTP 流量) |
| 停机主机 | 让 Nginx 对某域名返回 503,"下线但不删配置" |
注意点:转发目标建议填容器名 / Docker 网络内的主机名,而不是宿主机 IP,否则容易绕出公网或直接 502。需要长连接的服务(Jitsi、各类 WebSocket 应用)记得勾选 WebSocket 支持。
🧩 能力二 | SSL 自动化:HTTPS 证书自动签发与自动续签
能做什么:选 Let's Encrypt 作为证书来源,两种方式——HTTP 验证(靠 80 端口下发验证文件,要求 80/443 公网可达)和 DNS 服务商验证(调 DNS API,通配符证书必须用它)。配套开关:强制 SSL(HTTP 301 跳 HTTPS)、HTTP/2、HSTS。证书 90 天到期前会自动续签,存进./letsencrypt数据卷。
什么时候用:任何有公网域名的服务,默认全开。家庭实验室用 DDNS + 公网 IP 时,HTTP 验证即可;想给*.home.lab一把通配证书就切 DNS 验证。
注意点:HTTP 验证失败九成是域名没解析到本机、或 80 端口没放通,别先怀疑工具本身。
🧩 能力三 | 访问控制:按 IP 和账号决定放行
能做什么:先建"访问列表"(ACL),再挂到具体主机上。ACL 有两种玩法:按IP / CIDR 段做允许或拒绝;按用户名 + 密码(HTTP 基本认证)做门禁。同一主机可以"拒绝名单 + 允许名单"叠加使用。
什么时候用:Grafana、Portainer、文件同步这类不该对整个公网开放的管理面板;给团队服务加一道账号门禁。
注意点:如果目标应用自己也用基本认证登录,它和 NPM 的认证会抢同一个Authorization头,导致两边有一边登录不上——这类服务二选一,优先用 IP 白名单。
🧩 能力四 | 高级配置与自定义模板:表单不够用的出口
能做什么:每台主机有一个"高级配置"文本框,直接注入原始 Nginx 片段——限流、proxy_*_timeout、额外响应头、Gzip 白名单都从这里进;默认站点(没匹配到任何主机的请求落到哪)也可改。所有 conf 由backend/templates/目录下的 Liquid 模板渲染生成(proxy_host.conf、stream.conf、_certificates.conf、_access.conf等),读懂它们能帮你判断"这个需求到底该用哪个表单选项"。
什么时候用:表单勾不出来的需求才动它;90% 的场景前面的勾选框就够。
注意点:不要手改容器里已生成的 conf 文件——它归 NPM 所有,下一次保存就会重新渲染把你改的覆盖掉。改动一律放"高级配置",或深度定制时自行 fork 模板重新构建镜像。
🏠 落地案例:家庭实验室一次接入 4 个服务
场景:一台带公网 IP 的家用服务器,域名home.lab,Docker 里跑了 4 个服务,目标是一个域名规划、一把证书、各配各的访问控制。
| 子域名 | 服务 | 转发到 | 附加配置 |
|---|---|---|---|
| app.home.lab | Jitsi Meet | jitsi:443 | 强制 SSL + WebSocket |
| git.home.lab | Gitea | gitea:3000 | 访问列表:仅团队成员账号 |
| grafana.home.lab | Grafana | grafana:3000 | 访问列表:仅允许家庭网段 CIDR |
| media.home.lab | Jellyfin | jellyfin:8096 | 强制 SSL |
操作路径:
- 一把证书:在"证书"里用 DNS 服务商验证申请
*.home.lab通配符(HTTP 验证拿不到通配符); - 批量建主机:按上表逐台添加代理主机,全部选用这把通配证书;
- 挂访问控制:先建两个 ACL(一个账号型、一个 CIDR 型),分别挂到 Gitea 和 Grafana;
- 验证:
curl -I https://git.home.lab # 期望返回 200,且证书 CN 匹配 *.home.lab主机多到不想点界面时(十几台以上),别硬点:创建一个 API Token,用脚本批量调用接口建主机,体验会好得多——
backend/routes/下的接口是全的。
🚑 排障手册:先查这四处
① 现象:访问代理主机返回 502 / 连接被拒可能原因:转发目标填错(用了宿主机 IP 而非容器名)、两边不在同一 Docker 网络、目标容器没起来。 处理动作:docker compose ps确认目标容器状态;确认 NPM 容器与目标容器已连入同一网络(docker network ls);在 NPM 容器内curl -I http://目标:端口验证连通性。
② 现象:Let's Encrypt 申请失败,提示验证错误可能原因:DNS 未解析到本机、80/443 端口未对公网开放、解析还没生效。 处理动作:先用nslookup 域名确认 A 记录正确,再检查路由器端口转发与防火墙;换 DNS 服务商验证则检查 API 密钥权限。
③ 现象:给主机加了账号密码后,目标应用反而登录不上可能原因:NPM 基本认证与应用自身的认证共用Authorization请求头,互相覆盖。 处理动作:该服务改用 IP 白名单,或去掉应用侧的基本认证。
④ 现象:用 DNSPod 做 DNS 验证时证书一直创建失败(ARM 设备尤其常见)可能原因:certbot-dns-dnspod插件依赖的zope在 ARM 上安装失败,没能打进镜像。 处理动作:进容器手工补装后重试:
docker exec -it 容器名 bash pip install certbot-dns-dnspod pip install zope exit🧭 下一步
- 把日志接出去:内置审计日志记录了"谁在什么时候改了什么";Nginx 的 access / error 日志可以配 Logstash/Loki 采集,排障从"翻容器"升级成"搜日志"。
- API 自动化:创建 API Token 后,配合脚本做主机批量创建、证书状态巡检,接入你自己的 CI/定时任务。
- 平滑升级:
docker compose pull && docker compose up -d即可换新版本,中文镜像持续跟随官方版本更新,数据库迁移自动完成。 - 规模再上台阶:服务全部进 K8s 后,这部分可以迁移给 ingress-nginx,NPM 留作边缘与非 K8s 服务的入口。
现在就可以打开 81 端口,把那个用IP:端口凑合了很久的服务加上去——五分钟后,一个带域名和有效证书的地址就在等你了。
【免费下载链接】nginx-proxy-manager-zh基于nginx-proxy-manager翻译的中文版本项目地址: https://gitcode.com/gh_mirrors/ng/nginx-proxy-manager-zh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考