跳转到主要内容

Nginx Proxy Manager 详细部署手册

jc21/nginx-proxy-manager —— 基于 Nginx 的反向代理管理面板,集成 Let's Encrypt,通过 Web UI 实现域名管理、SSL 证书申请与自动续期。 本手册覆盖:单机 Docker / Docker Compose 部署、后台配置、Let's Encrypt 证书、对接 BookStack / Wiki.js、备份迁移与排错。


目录


一、核心概念

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 默认账号

项目 值
Email 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 按需
Email 你的邮箱(Let's Encrypt 注册)
I Agree to Let's Encrypt Terms ✓

点击 Save,NPM 自动完成:

  1. ACME 验证(/.well-known/acme-challenge/)
  2. 签发证书
  3. 配置 Nginx SSL
  4. 加入自动续期队列(内置 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 迁移到新服务器

  1. 新机安装 Docker,部署相同 docker-compose.yml
  2. 停止容器:docker compose down
  3. 恢复 data/ 与 letsencrypt/
  4. 启动:docker compose up -d
  5. 验证所有 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 现行版本