目录
一、前言与目标
在服务器上部署多个 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 中通过容器名和内部端口来设置反向代理。