目录
一、前言与目标
在服务器上部署多个 Docker 服务时,我们常常会遇到一个问题:每个服务都想占用一个端口,导致我们需要记住一堆 IP地址:端口号,例如 http://1.2.3.4:8080, http://1.2.3.4:8090 等。这种方式不仅管理混乱,而且直接暴露端口在公网上也存在安全风险,同时还无法方便地使用 HTTPS 加密。
本教程的目标,就是建立一个标准化的流程,将所有新部署的 Docker 服务都隐藏在反向代理之后,通过 Nginx Proxy Manager (NPM) 实现:
- 禁止通过 IP:端口的方式直接公网访问。
- 为每个服务绑定一个独立的、好记的子域名(例如 service-a.yourdomain.com)。
- 自动配置并强制使用 HTTPS 加密。
二、准备工作
在部署任何新服务之前,请确保您已拥有:
- 一个正在运行的 Nginx Proxy Manager (NPM) 容器。
- 一个已创建的、用于容器间通信的共享 Docker 网络。 在本教程中,我们假设这个网络的名字叫 shared-network。- (如果还未创建,请执行:sudo docker network create shared-network)
- (请确保您的 NPM 容器也已经连接到了这个网络,具体方法见我们之前的讨论)
 
- (如果还未创建,请执行:
- 一个准备好使用的域名,并且可以随时添加新的子域名解析。
三、核心改造步骤
几乎所有 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 端口上。
我们的修改步骤如下:
- 找到并删除 -p 5230:5230这个端口映射参数。 这是最关键的一步,目的是“隐藏”服务。
- 添加 --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 端口上。
我们的修改步骤如下:
- 找到 ports部分并将其彻底删除或用#注释掉。
- 在服务定义下添加 networks部分,指定shared-network。
- 在文件末尾添加顶级的 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 中将域名指向它。
- 登录您的 NPM 管理面板 (http://<IP>:81)。
- 进入 Hosts->Proxy Hosts,点击Add Proxy Host。
- 在 Details 标签页填写:- Domain Names: memos.yourdomain.com(您的新子域名)
- Scheme: http
- Forward Hostname / IP: <新容器的容器名>(例如memos或some-app)
- Forward Port: <容器的内部端口>(例如5230或80)
 :右边的那个端口号。
- Domain Names: 
- 切换到 SSL 标签页,选择 Request a new SSL Certificate,并打开Force SSL开关。
- 点击 Save。
五、总结
遵循这个标准流程,您就可以将任意多个 Docker 服务都整齐地统一管理起来,告别混乱的IP和端口号,非常专业!
核心工作流:
- 改造配置:移除 ports映射,禁止公网IP访问。
- 连接网络:添加 network配置,将新服务连接到shared-network。
- 设置反代:在 NPM 中通过容器名和内部端口来设置反向代理。
