轻量云服务器实战:Docker部署NPM打造可视化反向代理与自动SSL

举报
yd_213990305 发表于 2026/11/11 17:26:45 2026/11/11
【摘要】 ## 一、 引言:为什么需要可视化反向代理?随着个人云主机的普及,越来越多的开发者开始在单台云服务器上同时运行多个服务,例如:- 个人博客系统(如 Halo、WordPress)- 状态监控看板(如 Uptime Kuma)- 私有知识库或轻量网盘(如 Memos、Alist)- 各种自定义后端 API 服务这些服务默认运行在不同的内网端口(如 3000、3001、8080、5230 等)。...

## 一、 引言:为什么需要可视化反向代理?

随着个人云主机的普及,越来越多的开发者开始在单台云服务器上同时运行多个服务,例如:
- 个人博客系统(如 Halo、WordPress)
- 状态监控看板(如 Uptime Kuma)
- 私有知识库或轻量网盘(如 Memos、Alist)
- 各种自定义后端 API 服务

这些服务默认运行在不同的内网端口(如 3000、3001、8080、5230 等)。如果直接对外暴露端口,不仅容易引发安全隐患,而且不支持优美的独立子域名以及统一的 HTTPS 加密访问。

传统方案通常是安装原生 Nginx,然后手写大量的 `upstream` 和 `server` 块配置文件,并结合 `certbot` 定时脚本申请证书。但这种做法存在几大痛点:
1. **语法门槛高**:反向代理 WebSocket、报头重写、跨域配置稍有不慎就会导致 502/504 错误。
2. **证书管理碎**:多个二级域名需要逐个配置证书路径,容易出现续签脚本失效或证书遗忘续期。
3. **运维成本高**:每次新增服务都需要 SSH 登录终端,修改配置文件并 `nginx -s reload`。

**Nginx Proxy Manager(简称 NPM)** 彻底解决了这一问题。它基于 OpenResty 开发,集成了简洁直观的 Web UI、自动化的 Let's Encrypt 证书签发引擎、灵活的访问控制列表(Access Lists)和端口转发功能,运行时内存仅占用约 100MB~150MB,非常适合运行在 1核1G 或 2核2G 的轻量云服务器上。

---

## 二、 部署准备与环境检查

本文以 Ubuntu 24.04 LTS 云服务器环境为例。在开始前,请确认服务器已具备 Docker 及 Docker Compose 运行环境。

### 1. 检查 Docker 状态
在终端执行以下命令,验证 Docker 引擎状态:

```bash
docker --version
docker compose version
```

若尚未安装 Docker,推荐执行官方一键安装脚本:
```bash
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo systemctl enable --now docker
```

### 2. 检查 80 与 443 端口占用
Nginx Proxy Manager 需要接管宿主机的 HTTP(80)与 HTTPS(443)流量,请确保当前没有其他 Web 服务器(如 Apache 或旧版 Nginx)占用这两个核心端口:

```bash
sudo lsof -i :80
sudo lsof -i :443
```

如果已有系统原生 Nginx 在运行,可先将其停止并禁用:
```bash
sudo systemctl stop nginx
sudo systemctl disable nginx
```

---

## 三、 编写 Docker Compose 编排文件

我们将所有的容器配置与持久化数据收敛在 `/opt/containers/nginx-proxy-manager` 目录下,便于日后统一备份与迁移。

### 1. 创建工作目录
```bash
sudo mkdir -p /opt/containers/nginx-proxy-manager
cd /opt/containers/nginx-proxy-manager
```

### 2. 编写 `docker-compose.yml`
创建编排文件:

```bash
sudo vim docker-compose.yml
```

写入以下配置内容:

```yaml
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      # 接受公网 HTTP 流量
      - '80:80'
      # NPM 可视化管理后台端口(建议配合防火墙做限制)
      - '81:81'
      # 接受公网 HTTPS 流量
      - '443:443'
    volumes:
      # NPM 数据库与配置文件
      - ./data:/data
      # Let's Encrypt 证书及密钥存储
      - ./letsencrypt:/etc/letsencrypt
    environment:
      - TZ=Asia/Shanghai
      # 禁用不必要的崩溃上报,降低资源消耗
      - DISABLE_IPV6=true
    deploy:
      resources:
        limits:
          memory: 384M
```

> **架构与资源设计说明**:
> - **轻量级内置存储**:NPM 默认采用轻量级 SQLite 数据库存储在 `./data/database.sqlite` 中,无需额外启动 MySQL/MariaDB 容器,直接节省 200MB+ 内存开销。
> - **证书安全隔离**:`./letsencrypt` 目录挂载在宿主机,即便容器销毁重建,申请好的 SSL 证书与私钥也不会丢失。
> - **内存上限保护**:通过 `limits.memory: 384M` 设定防线,防止极端突发流量或扫描撞库引发宿主机 OOM。

---

## 四、 服务启动与初始化配置

### 1. 拉取镜像并启动
在 `/opt/containers/nginx-proxy-manager` 目录下执行:

```bash
sudo docker compose up -d
```

查看容器启动日志,确保初始化迁移顺利完成:
```bash
sudo docker compose logs -f
```
看到终端输出 `[Setup    ] Setup Complete` 类似字样后,按 `Ctrl + C` 退出日志跟踪。

### 2. 首次登录与修改安全凭证
在浏览器中访问:`http://<你的服务器公网IP>:81`。

* **初始默认账号**:`admin@example.com`
* **初始默认密码**:`changeme`

首次登录成功后,系统会强制弹出个人信息与密码修改弹窗:
1. **修改管理员邮箱**:填写你的真实常用邮箱(该邮箱后续也将用于接收 Let's Encrypt 证书即将过期的安全提醒通知)。
2. **设置强密码**:设置包含字母、数字及特殊符号的复杂密码,并立即保存。

---

## 五、 实战:三分钟完成服务反代与 SSL 证书自动签发

假设我们在云服务器本地运行了一个 Web 容器(如前面部署在 `127.0.0.1:3001` 的 Uptime Kuma 监控看板),并且我们拥有域名 `example.com`,现在希望通过 `status.example.com` 实现全自动 HTTPS 加密访问。

### 1. 配置 DNS 域名解析
前往你的域名 DNS 控制台(如 Cloudflare、阿里云或华为云 DNS),新增一条 A 记录:
- **主机记录**:`status`
- **记录类型**:`A`
- **记录值**:填写你的云服务器公网 IP
- **TTL**:默认即可

### 2. 在 NPM 中添加反向代理规则(Proxy Host)
1. 登录 NPM 控制台,点击顶部导航栏的 **“Hosts” -> “Proxy Hosts”**。
2. 点击右上角 **“Add Proxy Host”** 按钮。
3. 在 **“Details”** 选项卡中进行如下配置:
   - **Domain Names**:填写 `status.example.com` 并按回车确认。
   - **Scheme**:选择 `http`。
   - **Forward Hostname / IP**:填写容器所在宿主机内网 IP 或使用宿主机别名。若容器与 NPM 处于同一宿主机,建议填写宿主机的内网 IP,或直接使用 Docker 内部网络别名;若使用 host 模式直接填写 `172.17.0.1` 或宿主机内网 IP。
   - **Forward Port**:填写目标服务的内部端口(例如 `3001`)。
   - **开启功能选项**:
     - 勾选 **Cache Assets**(静态资产缓存,加速加载)
     - 勾选 **Block Common Exploits**(开启常见 Web 漏洞与恶意注入过滤防护)
     - 勾选 **Websockets Support**(如后端是实时通信或 Socket 页面,务必勾选)

### 3. 一键申请并配置免费 SSL 证书
切换到 **“SSL”** 选项卡:
1. **SSL Certificate**:下拉选择 **“Request a new SSL Certificate”**(申请新证书)。
2. 勾选 **Force SSL**(强制将 HTTP 80 重定向到 HTTPS 443)。
3. 勾选 **HTTP/2 Support**(开启 HTTP/2 协议,大幅提升多请求并发传输性能)。
4. 勾选 **HSTS Enabled**(开启严格传输安全协议,防止降级劫持)。
5. 填入你的电子邮箱,并勾选 **“I Agree to the Let's Encrypt Terms of Service”**。
6. 点击右下角 **“Save”**。

NPM 会自动与 Let's Encrypt ACME 服务器发起 HTTP-01 验证挑战,验证通过后自动写入 Nginx 配置并平滑加载。整个过程通常在 5~15 秒内自动完成,无需敲击任何一行黑屏命令!

更省心的是:**NPM 会在后台定时自动巡检,并在证书到期前 30 天自动静默续签**,彻底告别证书过期导致的网站告警。

---

## 六、 进阶安全加固:Access Lists(访问控制列表)

轻量云服务器上的某些私有服务(例如管理后台、测试端点)不希望对公网完全开放。NPM 提供了开箱即用的 **Access Lists** 功能,无需写正则即可实现双重安全防护。

### 1. 创建访问控制策略
1. 点击导航栏 **“Access Lists” -> “Add Access List”**。
2. **Name**:填写规则名称,如 `Internal-Only`。
3. **Authorization(Basic Auth 密码锁)**:
   - 添加用户名和密码。即使外部用户获知了访问域名,也必须输入此账号密码才能进入后续页面。
4. **Access(IP 白名单限制)**:
   - 在白名单列表中添加信任的固定 IP 地址(例如你家庭宽带公网 IP 或公司办公网段)。
   - 勾选 **Satisfy Any**(满足任一条件即可)或 **Satisfy All**(必须同时满足 IP 白名单与账号密码)。
5. 点击 **Save** 保存。

### 2. 绑定策略到目标站点
返回 **Proxy Hosts** 列表,编辑对应的站点,在 **Access List** 下拉列表中选择刚刚创建的 `Internal-Only`。未在白名单内或输入错误密码的用户,将被直接阻断并返回 `401 Unauthorized` 或 `403 Forbidden`。

---

## 七、 备份与灾难恢复方案

由于我们采用了清晰的目录隔离挂载,整个系统的灾备方案非常优雅纯粹:

```bash
#!/bin/bash
# 保存为 /opt/containers/nginx-proxy-manager/backup_npm.sh
BACKUP_PATH="/opt/backup/npm"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_PATH

# 压缩持久化数据与证书库
tar -czvf "$BACKUP_PATH/npm_backup_$DATE.tar.gz" \
  -C /opt/containers/nginx-proxy-manager data letsencrypt docker-compose.yml

# 仅保留最近 14 天的备份
find $BACKUP_PATH -type f -name "npm_backup_*.tar.gz" -mtime +14 -delete
```

加入 Linux `crontab` 定时器即可实现每周自动化归档备份。如果日后需要更换服务器,只需将备份包解压到新服务器的对应目录,执行 `docker compose up -d` 即可实现全量无缝秒级复活!

---

## 八、 总结与最佳实践建议

在本文中,我们通过 Docker Compose 在轻量云服务器上落地了一套开箱即用的反向代理中枢。Nginx Proxy Manager 不仅保留了 Nginx 高性能、低开销的底层内核,更通过现代化的图形交互打破了配置繁琐的壁垒。

**实践建议总结**:
1. **端口安全管控**:管理后台使用的 `81` 端口建议在云安全组中仅对管理员特定 IP 开放,或者通过 SSH 本地端口转发访问,避免管理后台直接裸奔公网。
2. **充分利用 WebSocket 开关**:对于长轮询、实时推送类应用(如即时通讯、在线终端、监控面板),务必在站点配置中开启 Websockets Support。
3. **域名规划清晰**:建议使用泛解析(如 `*.yourdomain.com`)配合二级域名,配合 NPM 实现“一个域名开箱一个新服务”,大幅提升个人云上实验与开发的交付效率。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。