NPM+CloudFlare实现泛域名HTTPS
在自建多个服务的情况下,如果每个容器都需要暴露端口到宿主机,不仅不安全,还容易端口冲突。
更优雅的方式是:所有服务与 Nginx Proxy Manager(NPM)放在同一个 Docker 网络中,不需要对宿主机暴露任何业务端口,只暴露 NPM 自己的 80 / 443 / 81 即可。
再结合 Cloudflare 的 DNS API,我们可以自动申请泛域名证书,让所有子域名自动启用 HTTPS。
整体架构
client --> cloudflare dns/cdn --> NPM(80/443) --> 内网 docker 服务所有后端服务均在同一个名为 proxy 的 docker 网络中:
┌──────────────┐
│ cloudflare │
└──────┬───────┘
│
public https
│
┌──────────▼──────────┐
│ Nginx Proxy Mgr │ <--- 只暴露 80/443/81 端口
└──────────┬──────────┘
│ 内网转发
┌────────────┴────────────┐
│ docker network │
│ proxy │
└────┬──────────────┬─────┘
│ │
┌──────▼─────┐ ┌────▼──────┐
│ app1:3000 │ │ app2:8080 │ <-- *不暴露到宿主机*
└────────────┘ └───────────┘准备事项
Cloudflare 托管域名
为了使用 DNS-01 验证申请泛域名证书,域名必须托管在 Cloudflare。
Cloudflare API Token
分别点击 Profile → API Tokens → Create Token,使用 Edit zone DNS 模板来创建 Token。

生成后复制 Token 备用。
创建共用 Docker 网络
在 NPM 启动前创建一个共用网络:
sudo docker network create proxy所有服务(包括 NPM )都将加入这个网络。
部署 NPM
推荐docker compose 部署 NPM,配置如下:
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
- 80:80
- 81:81
- 443:443
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
environment:
- TZ=Asia/Shanghai
networks:
- proxy
networks:
proxy:
external: true提示:只有 NPM 需要暴露宿主机端口,其他服务不需要暴露!
启动NPM:
docker compose up -d部署其他服务
这里以 dockge 服务为例,内部端口5001,不暴露宿主机端口:
services:
dockge:
image: louislam/dockge:1
container_name: dockge
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# Stacks Directory
# ⚠️ READ IT CAREFULLY. If you did it wrong, your data could end up writing into a WRONG PATH.
# ⚠️ 1. FULL path only. No relative path (MUST)
# ⚠️ 2. Left Stacks Path === Right Stacks Path (MUST)
- /home/gitop/dockge/stacks:/home/gitop/dockge/stacks
environment:
# Tell Dockge where to find the stacks
- DOCKGE_STACKS_DIR=/home/gitop/dockge/stacks
- TZ=Asia/Shanghai
expose:
- "5001"
networks:
- proxy
networks:
proxy:
external: true申请泛域名证书
打开 NPM 管理后台 http://your-vps-ip:81。

分别点击 Certificates → Add Certificate,选择 Let’s Encrypt via DNS。

填写:
-
Domain Names:
*.yourdomain.com -
DNS Provider:Cloudflare
-
Credentials:
dns_cloudflare_api_token = xxxxxxxx
如下图所示:

保存后 NPM 会自动向 Let’s Encrypt 申请免费证书并自动更新证书。
为服务配置反向代理
还是以 dockge 为例,例如想把 dockge.yourdomain.com 代理到 dockge 容器。分别点击 Hosts → Proxy Hosts → Add Proxy Host。
填写:
| 项 | 值 |
|---|---|
| Domain Names | dockge.yourdomain.com |
| Forward Hostname / IP | dockge |
| Forward Port | 5001 |
| Scheme | http |
如下图所示:

因为 dockge 与 NPM 在同一个网络里,可以直接用容器名当主机名!。
然后点击 SSL 页签,SSL Certificate 选择泛域名证书(*.yourdomain.com),勾选 Force SSL 和 HTTP/2 Support,点保存即可。
添加 Cloudflare DNS 记录
打开 Cloudflare 管理后台,分别点击 Domain → DNS → Add Record:

等待一段时间 DNS 生效后,访问 https://dockge.yourdomain.com 即可看到 dockge 服务的首页!
总结
通过 NPM + Cloudflare + Docker 共用网络,你可以实现:
- 真正零暴露端口的后端服务
- 自动更新的泛域名证书以及 HTTPS
- 优雅的 Docker 服务反代架构,所有服务统一由 NPM 管控