我的 Docker 服务标准部署流程:集成 Nginx Proxy Manager 禁止公网IP泄露访问

一、前言与目标

在服务器上部署多个 Docker 服务时,我们常常会遇到一个问题:每个服务都想占用一个端口,导致我们需要记住一堆 IP地址:端口号,例如 http://1.2.3.4:8080, http://1.2.3.4:8090 等。这种方式不仅管理混乱,而且直接暴露端口在公网上也存在安全风险,同时还无法方便地使用 HTTPS 加密。

本教程的目标,就是建立一个标准化的流程,将所有新部署的 Docker 服务都隐藏在反向代理之后,通过 Nginx Proxy Manager (NPM) 实现:

  1. 禁止通过 IP:端口 的方式直接公网访问。
  2. 为每个服务绑定一个独立的、好记的子域名(例如 service-a.yourdomain.com)。
  3. 自动配置并强制使用 HTTPS 加密

二、准备工作

在部署任何新服务之前,请确保您已拥有:

  1. 一个正在运行的 Nginx Proxy Manager (NPM) 容器。
  2. 一个已创建的、用于容器间通信的共享 Docker 网络。 在本教程中,我们假设这个网络的名字叫 shared-network
    • (如果还未创建,请执行:sudo docker network create shared-network
    • (请确保您的 NPM 容器也已经连接到了这个网络,具体方法见我们之前的讨论)
  3. 一个准备好使用的域名,并且可以随时添加新的子域名解析。

三、核心改造步骤

几乎所有 Docker 应用的官方文档都会提供一个简单的 docker run 命令或 docker-compose.yml 文件示例,它们通常都包含一个 -p <端口>:<端口>ports 的配置。我们的核心任务就是改造这个配置。

情况 A:当官方提供的是 docker run 命令时

假设您找到了一个新应用(例如 Memos 笔记),它的标准启动命令是这样的:

# --- 改造前的原始命令 ---
docker run -d \
  --name memos \
  -p 5230:5230 \
  -v ~/.memos/:/var/opt/memos \
  usememos/memos:latest

这个命令会将 Memos 服务直接暴露在你服务器的公网 IP 的 5230 端口上。

我们的修改步骤如下:

  1. 找到并删除 -p 5230:5230 这个端口映射参数。 这是最关键的一步,目的是“隐藏”服务。
  2. 添加 --network shared-network 参数。 这是为了将它连接到我们的内部“高速公路”。

修改后的命令:

# --- 改造后的命令 ---
docker run -d \
  --name memos \
  --network shared-network \
  -v ~/.memos/:/var/opt/memos \
  usememos/memos:latest
情况 B:当官方提供的是 docker-compose.yml 文件时

假设您找到了一个应用的 docker-compose.yml 示例:

# --- 改造前的原始配置 ---
services:
  some-app:
    image: some/app:latest
    ports:
      - "8989:80"
    volumes:
      - ./app-data:/data

这个配置同样会将 some-app 暴露在你服务器的 8989 端口上。

我们的修改步骤如下:

  1. 找到 ports 部分并将其彻底删除或用 # 注释掉。
  2. 在服务定义下添加 networks 部分,指定 shared-network
  3. 在文件末尾添加顶级的 networks 声明,将 shared-network 标记为 external: true

修改后的 docker-compose.yml

# --- 改造后的配置 ---
services:
  some-app:
    image: some/app:latest
    volumes:
      - ./app-data:/data
    networks:
      - shared-network

networks:
  shared-network:
    external: true

四、在 Nginx Proxy Manager 中配置反向代理

在您使用修改后的命令或配置成功启动了新的 Docker 服务后,最后一步就是在 NPM 中将域名指向它。

  1. 登录您的 NPM 管理面板 (http://<IP>:81)。
  2. 进入 Hosts -> Proxy Hosts,点击 Add Proxy Host
  3. Details 标签页填写:
    • Domain Names: memos.yourdomain.com (您的新子域名)
    • Scheme: http
    • Forward Hostname / IP: <新容器的容器名> (例如 memossome-app)
    • Forward Port: <容器的内部端口> (例如 523080)
    如何确定“内部端口”? 您需要查看新应用的 Docker Hub 页面或其文档,来确定它的程序在容器内监听的是哪个端口。通常就是原始命令中冒号:右边的那个端口号。
  4. 切换到 SSL 标签页,选择 Request a new SSL Certificate,并打开 Force SSL 开关。
  5. 点击 Save

五、总结

遵循这个标准流程,您就可以将任意多个 Docker 服务都整齐地统一管理起来,告别混乱的IP和端口号,非常专业!

核心工作流:

  1. 改造配置:移除 ports 映射,禁止公网IP访问。
  2. 连接网络:添加 network 配置,将新服务连接到 shared-network
  3. 设置反代:在 NPM 中通过容器名内部端口来设置反向代理。

By 行政