Nginx Proxy Manager 详细部署手册
jc21/nginx-proxy-manager —— 基于 Nginx 的反向代理管理面板,集成 Let's Encrypt,通过 Web UI 实现域名管理、SSL 证书申请与自动续期。 本手册覆盖:单机 Docker / Docker Compose 部署、后台配置、Let's Encrypt 证书、对接 BookStack / Wiki.js、备份迁移与排错。
目录
- 一、核心概念
- 二、环境准备
- 三、Docker Compose 部署(推荐)
- 四、首次登录与初始化
- 五、域名管理:配置反向代理
- 六、Let's Encrypt SSL 证书
- 七、高级功能
- 八、对接现有服务(BookStack / Wiki.js)
- 九、备份与迁移
- 十、更新升级
- 十一、常见问题排查
- 十二、安全加固清单
- 附:完整 docker-compose.yml
一、核心概念
1.1 它是什么
Nginx Proxy Manager(简称 NPM)= Nginx + Node.js 管理面板。它把复杂的 Nginx 反向代理配置、SSL 证书管理封装成 Web UI,让你点几下鼠标就能:
- 把
wiki.example.com→ 转发到后端容器bookstack:80 - 一键申请 / 自动续期 Let's Encrypt 证书
- 配置 HTTP Basic Auth、IP 黑白名单、自定义 Nginx 配置
1.2 架构
┌────────────────────────────────────┐
│ 宿主机(Docker) │
│ │
公网/内网 ──:80/:443──► [ NPM 容器 ] ◄─── Docker 网络 │
│ Nginx (反代) + 管理 API │ ┌────────────┐
│ :81 管理 UI │ │ BookStack │
│ │ │ Wiki.js │
│ 持久化: │ │ 其他服务 │
│ /data (配置+SQLite) │ └────────────┘
│ /etc/letsencrypt (证书) │
└────────────────────────────────────┘
1.3 关键组件
| 组件 | 说明 |
|---|---|
| Nginx | 真正的反向代理 / Web 服务器,监听 80/443 |
| Node.js 后端 | 提供 REST API,管理配置、证书 |
| 管理 UI | Vue.js 前端,默认端口 81 |
| SQLite | 内置数据库,存代理规则、用户、证书元信息(无需外部 DB) |
| acme.sh / Certbot 逻辑 | 内置 Let's Encrypt 客户端,处理签发与续期 |
1.4 端口说明
| 端口 | 用途 | 建议 |
|---|---|---|
| 80 | HTTP(ACME 验证 + 跳转 HTTPS) | 必须对外 |
| 443 | HTTPS | 必须对外 |
| 81 | 管理 UI | 不要直接暴露公网,改映射或前置鉴权 |
| 8080/8443 | 可选:管理 UI 的 HTTP/HTTPS(部分版本) | 按需 |
二、环境准备
2.1 前置条件
- Linux 服务器(Ubuntu 22.04 / Debian 12 推荐)
- Docker 20+ 与 Docker Compose v2
- 至少一个已解析到服务器 IP 的域名
- 防火墙放行 80、443(Let's Encrypt HTTP-01 必需)
- 80/443 端口未被其他服务占用(如直接装的 Nginx、Caddy)
2.2 创建目录
sudo mkdir -p /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager
sudo mkdir -p data letsencrypt
目录规划:
/opt/nginx-proxy-manager/
├── docker-compose.yml
├── data/ # NPM 配置 + SQLite 数据库
└── letsencrypt/ # Let's Encrypt 证书(可选单独挂)
三、Docker Compose 部署(推荐)
3.1 完整 compose 文件
version: "3.8"
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80" # HTTP + ACME 验证
- "443:443" # HTTPS
- "81:81" # 管理 UI(生产建议改映射,如 127.0.0.1:81:81)
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy
# 可选:限制日志大小
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# 后续加入需要代理的服务,加入同一网络即可
# 例如 BookStack、Wiki.js 添加 network: proxy
networks:
proxy:
driver: bridge
📌 说明:NPM 内置 SQLite,无需额外数据库,开箱即用。
3.2 启动
cd /opt/nginx-proxy-manager
docker compose up -d
# 查看日志
docker compose logs -f nginx-proxy-manager
看到 nginx: [notice] start 与 Proxy Manager ready 即启动成功。
3.3 单独 Docker 命令(不使用 Compose)
docker run -d \
--name nginx-proxy-manager \
--restart unless-stopped \
-p 80:80 \
-p 443:443 \
-p 81:81 \
-v /opt/nginx-proxy-manager/data:/data \
-v /opt/nginx-proxy-manager/letsencrypt:/etc/letsencrypt \
jc21/nginx-proxy-manager:latest
四、首次登录与初始化
4.1 访问管理 UI
浏览器打开:http://服务器IP:81
4.2 默认账号
| 项目 | 值 |
|---|---|
admin@example.com |
|
| Password | changeme |
⚠️ 首次登录后立即修改邮箱与密码(系统会强制引导)。
4.3 创建普通用户(推荐)
Admin Panel → Users → Add User:
- Role:可选
User(仅管理自己的代理)或Admin(全部权限) - 生产环境日常用普通账号,避免长期用 admin
4.4 初始设置
Admin Panel → Settings:
- Default Site:未匹配域名的默认行为(默认 404 即可)
- HTTP to HTTPS Redirect:全局强制 HTTPS(建议开启)
- Trusted Proxies:若 NPM 前面还有 CDN / 负载均衡,填其 IP 段
五、域名管理:配置反向代理
5.1 添加 Proxy Host(核心操作)
进入 Hosts → Proxy Hosts → Add Proxy Host,填写:
Details 选项卡:
| 字段 | 示例 | 说明 |
|---|---|---|
| Domain Names | wiki.example.com |
可多个,逗号分隔;支持通配符需 DNS Challenge |
| Scheme | http |
与后端通信协议 |
| Forward Hostname / IP | bookstack |
Docker 服务名或容器 IP |
| Forward Port | 80 |
后端容器内端口 |
| Cache Assets | ✓ | 缓存静态资源 |
| Block Common Exploits | ✓ | 拦截常见漏洞扫描 |
| Websockets Support | 按需 | 如 Vue/WS 应用需开 |
| Access List | 公开 / 自定义 | 访问控制 |
SSL 选项卡(见第六章)
Advanced(高级):可粘贴自定义 Nginx 配置片段,如:
location /api/ {
proxy_read_timeout 300;
}
5.2 Forward Hostname 的正确写法
关键是 Docker 网络内的服务名解析:
# 同一 docker-compose 网络
services:
npm:
networks: [proxy]
bookstack: # ← 这个就是 hostname
networks: [proxy]
则 Forward Hostname = bookstack(服务名),不是 localhost、127.0.0.1(那是 NPM 容器自己)。
若服务在另一台机器 / 宿主机:填宿主机内网 IP(如 192.168.9.99),并确保网络可达。
5.3 Redirection Hosts(域名跳转)
Hosts → Redirection Hosts:把 www.example.com → example.com,或旧域名跳新域名。
5.4 Stream Hosts(TCP/UDP 代理)
Hosts → Stream Hosts:四层代理,如把 :22 转发到内部 SSH、MySQL :3306 等(需 NPM 监听对应端口)。
六、Let's Encrypt SSL 证书
6.1 前提
- 域名 A 记录已解析到 NPM 所在服务器公网 IP
- 80 端口对外可达(HTTP-01)
- 能访问
http://域名/.well-known/acme-challenge/
6.2 为单个 Proxy Host 申请
编辑 Proxy Host → SSL 选项卡:
| 字段 | 选择 |
|---|---|
| SSL Certificate | Request a new SSL Certificate |
| Force SSL | ✓(强制 HTTPS) |
| HTTP/2 Support | ✓ |
| HSTS | 按需 |
| 你的邮箱(Let's Encrypt 注册) | |
| I Agree to Let's Encrypt Terms | ✓ |
点击 Save,NPM 自动完成:
- ACME 验证(
/.well-known/acme-challenge/) - 签发证书
- 配置 Nginx SSL
- 加入自动续期队列(内置 cron,证书 < 30 天自动 renew)
6.3 DNS Challenge(无公网 80/443 或通配符)
家宽无公网 IP、或要 *.example.com 通代:
SSL → Use a DNS Challenge → 选择提供商(Cloudflare / Aliyun / TencentCloud 等)→ 填入 API Token。
以 Cloudflare 为例:
Credentials:{"api_token":"xxxx"}- 申请后自动续期,通配符证书一次覆盖所有子域。
6.4 查看与监控证书
SSL Certificates 页面:
- 列表显示每个域名证书到期时间
- 可手动
Renew Now强制续期 - 内置自动续期,通常无需人工干预
6.5 自定义证书(已有证书 / 商业证书)
SSL Certificates → Add Certificate → Custom:粘贴 fullchain.pem + privkey.pem,供 Proxy Host 选用。
七、高级功能
7.1 Access Lists(访问控制)
Access Lists → Add List:
- BASIC Auth:用户名 + 密码,弹窗登录(适合后台、管理面板的二次保护)
- IP Whitelist / Blacklist:限制来源 IP
创建后在 Proxy Host 的 Access List 下拉选用。
💡 实践:给 NPM 管理 UI(81 端口)也加一层保护——用另一个 Proxy Host
npm.example.com+ Access List,再把 81 端口映射改为127.0.0.1:81:81。
7.2 自定义 Nginx 配置
每个 Proxy Host 的 Advanced 选项卡,可插入任意 Nginx 指令:
# 增大上传大小
client_max_body_size 100m;
# 反代 WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 自定义头部
proxy_set_header X-Forwarded-Host $host;
全局配置:Admin Panel → Settings → Custom Nginx Configuration。
7.3 Dead Hosts / 404 页面美化
Settings → Default Site 配置自定义 404/502 页面。
7.4 日志
- 访问日志:
/data/logs/proxy-host-X_access.log - 错误日志:
/data/logs/proxy-host-X_error.log
可在 UI 的 Proxy Host → Logs 直接查看。
八、对接现有服务(BookStack / Wiki.js)
8.1 场景
已有 BookStack、Wiki.js 通过 Docker 运行,现在用 NPM 统一入口 + HTTPS。
8.2 网络打通(关键)
让 NPM 与后端服务在同一 Docker 网络:
# /opt/nginx-proxy-manager/docker-compose.yml
services:
nginx-proxy-manager:
# ... 同上
networks:
- proxy
- bookstack_net # 加入 BookStack 的网络(需先在 BookStack compose 中创建外部网络)
networks:
proxy:
driver: bridge
bookstack_net:
external: true # 假设 BookStack 自建了名为 bookstack_net 的网络
或在 BookStack 的 compose 里把网络改为 external: true 并命名为一致。
更简单做法:把所有服务放进同一个 docker-compose.yml(见附录)。
8.3 配置 Proxy Host
| Proxy Host | Domain | Forward Hostname | Forward Port |
|---|---|---|---|
| BookStack | wiki.example.com |
bookstack |
80 |
| Wiki.js | docs.example.com |
wiki |
3000 |
SSL 选项卡申请证书、Force SSL。
8.4 后端服务无需 HTTPS
NPM 终结 TLS(对外 HTTPS),后端用 HTTP 即可(同一主机内,安全可控),简化架构。
8.5 后端应用的 URL 配置
BookStack:APP_URL=https://wiki.example.com(与访问域名一致)
Wiki.js:HOST=docs.example.com(或后台 Administration → General Settings 里的 Site URL)
NPM 默认已传递 X-Forwarded-Proto、X-Forwarded-Host,多数应用自动识别 HTTPS。若应用仍认为 HTTP,在 Advanced 显式加:
proxy_set_header X-Forwarded-Proto https;
九、备份与迁移
9.1 备份内容
| 路径 | 内容 | 重要性 |
|---|---|---|
./data/ |
配置 + SQLite 数据库(所有 Proxy Host / 用户 / Access List) | 核心 |
./letsencrypt/ |
Let's Encrypt 证书与账户 | 重要(可重新签发,但麻烦) |
9.2 备份脚本
#!/bin/bash
# /opt/nginx-proxy-manager/backup.sh
set -e
DATE=$(date +%F)
DEST="/root/npm-backup-${DATE}.tar.gz"
tar czf "${DEST}" \
-C /opt/nginx-proxy-manager \
data letsencrypt docker-compose.yml
# 保留 30 天
find /root -name "npm-backup-*.tar.gz" -mtime +30 -delete
echo "备份完成: ${DEST}"
chmod +x /opt/nginx-proxy-manager/backup.sh
sudo crontab -e
# 每周日 3:00 备份
0 3 * * 0 /opt/nginx-proxy-manager/backup.sh
9.3 迁移到新服务器
- 新机安装 Docker,部署相同
docker-compose.yml - 停止容器:
docker compose down - 恢复
data/与letsencrypt/ - 启动:
docker compose up -d - 验证所有 Proxy Host 正常
十、更新升级
10.1 标准流程
cd /opt/nginx-proxy-manager
docker compose pull
docker compose up -d
10.2 大版本升级注意事项
- 升级前务必备份
data/ - 关注 NPM GitHub Releases 的 Breaking Changes
- 若使用外部数据库(MySQL/PostgreSQL 版本),先升级 DB schema
10.3 固定版本(生产推荐)
image: jc21/nginx-proxy-manager:2.11.3 # 不用 latest,避免意外升级
十一、常见问题排查
| 问题 | 原因 / 解决 |
|---|---|
| 502 Bad Gateway | Forward Hostname/IP 不通;服务名拼写错误;后端未启动;网络不在同一 docker 网络 |
| 504 Gateway Timeout | 后端响应慢;在 Advanced 增加 proxy_read_timeout 300; |
| 证书申请失败 | 80 端口不通 / 域名未解析 / .well-known 被拦截;检查 Block Common Exploits 是否误拦 |
| ERR_CONNECTION_REFUSED :81 | NPM 未启动或 81 端口映射被改;docker ps 检查 |
| 重定向循环(https→https) | 后端又做了一次 HTTPS 跳转;确保后端用 HTTP,由 NPM 终结 TLS |
| Mixed Content 警告 | 后端生成的资源 URL 是 HTTP;设 APP_URL 为 https + X-Forwarded-Proto |
| WebSocket 连不上 | Proxy Host 勾选 Websockets Support,或 Advanced 加 Upgrade 头 |
| 上传大文件 413 | Advanced 加 client_max_body_size 100m; |
| 修改配置不生效 | NPM 自动 reload,偶发需重启容器:docker compose restart |
| 数据库锁 / SQLite error | 并发写入冲突;检查是否有多个 NPM 实例指向同一 data/ |
11.1 调试命令
# 查看 NPM 日志
docker compose logs -f nginx-proxy-manager
# 进入容器查看 Nginx 配置
docker exec -it nginx-proxy-manager bash
cat /data/nginx/proxy_host/*
# 测试 ACME 验证可达
curl -v http://wiki.example.com/.well-known/acme-challenge/test
# 检查证书有效期
openssl x509 -in letsencrypt/live/wiki.example.com/fullchain.pem -noout -dates
十二、安全加固清单
- 修改默认 admin 密码,并创建普通用户日常使用
- 81 管理端口不要直接暴露公网:改为
127.0.0.1:81:81,或用域名 + Access List 保护 - 开启全局 HTTP→HTTPS 跳转
- 启用 HSTS(确认无 HTTP 需求后再开)
- 定期备份
data/ - 限制
Trusted Proxies(若前置 CDN / LB) - 升级前先备份
- 监控证书到期(NPM UI 可见,或外部监控)
- 避免把 NPM 的
/data挂载到不受信任的路径
附:完整 docker-compose.yml
一体化示例:NPM + BookStack + Wiki.js 全部在同一网络,开箱即用。
version: "3.8"
services:
# ============ 反向代理 ============
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81" # 仅本地访问管理 UI
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy
# ============ BookStack ============
bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- APP_URL=https://wiki.example.com
- APP_KEY=base64:xxxx # 首次启动前生成
- DB_HOST=bookstack-db
- DB_PORT=3306
- DB_USERNAME=bookstack
- DB_PASSWORD=bookstackpass
- DB_DATABASE=bookstack
depends_on:
- bookstack-db
networks:
- proxy
bookstack-db:
image: lscr.io/linuxserver/mariadb:latest
container_name: bookstack-db
restart: unless-stopped
environment:
- MYSQL_DATABASE=bookstack
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=bookstackpass
- MYSQL_ROOT_PASSWORD=rootpass
volumes:
- ./bookstack-db:/config
networks:
- proxy
# ============ Wiki.js ============
wiki:
image: ghcr.io/requarks/wiki:2
container_name: wiki
restart: unless-stopped
environment:
- DB_TYPE=postgres
- DB_HOST=wiki-db
- DB_PORT=5432
- DB_USER=wiki
- DB_PASS=wikipass
- DB_NAME=wiki
depends_on:
- wiki-db
networks:
- proxy
wiki-db:
image: postgres:17
container_name: wiki-db
restart: unless-stopped
environment:
- POSTGRES_USER=wiki
- POSTGRES_PASSWORD=wikipass
- POSTGRES_DB=wiki
volumes:
- ./wiki-db:/var/lib/postgresql/data
networks:
- proxy
networks:
proxy:
driver: bridge
部署后 NPM 配置:
| Domain | Forward Hostname | Port | 说明 |
|---|---|---|---|
wiki.example.com |
bookstack |
80 | BookStack,申请 SSL |
docs.example.com |
wiki |
3000 | Wiki.js,申请 SSL |
快速开始(TL;DR)
# 1. 准备
sudo mkdir -p /opt/nginx-proxy-manager && cd /opt/nginx-proxy-manager
sudo mkdir -p data letsencrypt
# 2. 写入上面的 docker-compose.yml
# 3. 启动
docker compose up -d
# 4. 访问 http://服务器IP:81,用 admin@example.com / changeme 登录并改密
# 5. Hosts → Proxy Hosts → Add:
# Domain: wiki.example.com
# Forward: bookstack : 80
# SSL: Request new cert,Force SSL ✓
# 6. 验证 https://wiki.example.com 可访问
参考资源
- NPM 官方文档:https://nginxproxymanager.com/
- GitHub:https://github.com/NginxProxyManager/nginx-proxy-manager
- Docker Hub:https://hub.docker.com/r/jc21/nginx-proxy-manager
- Let's Encrypt 速率限制:https://letsencrypt.org/docs/rate-limits/
更新于 2026-09-13 · 适用 NPM v2.x 现行版本
没有要显示的评论
没有要显示的评论