目录

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。

/images/2025/12/05/create-token.png

生成后复制 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。

/images/2025/12/05/npm.png

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

/images/2025/12/05/certificate.png

填写:

  • Domain Names:*.yourdomain.com

  • DNS Provider:Cloudflare

  • Credentials:

    dns_cloudflare_api_token = xxxxxxxx

如下图所示:

/images/2025/12/05/dns.png

保存后 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

如下图所示:

/images/2025/12/05/host-detail.png

因为 dockge 与 NPM 在同一个网络里,可以直接用容器名当主机名!

然后点击 SSL 页签,SSL Certificate 选择泛域名证书(*.yourdomain.com),勾选 Force SSL 和 HTTP/2 Support,点保存即可。

添加 Cloudflare DNS 记录

打开 Cloudflare 管理后台,分别点击 Domain → DNS → Add Record:

/images/2025/12/05/dns-record.png

等待一段时间 DNS 生效后,访问 https://dockge.yourdomain.com 即可看到 dockge 服务的首页!

总结

通过 NPM + Cloudflare + Docker 共用网络,你可以实现:

  • 真正零暴露端口的后端服务
  • 自动更新的泛域名证书以及 HTTPS
  • 优雅的 Docker 服务反代架构,所有服务统一由 NPM 管控