Docker Compose 服务名解析与自定义网络配置
来源:17golang原创
时间:2026-09-29 02:35:17 286浏览 收藏
Docker Compose 的服务名解析依赖“是否接入同一网络”,不是依赖容器当前 IP。要让 web 找到数据库,应该把调用方和数据库放到同一个自定义网络,再用服务名或网络别名连接;不共享网络的服务,即使写在同一个 Compose 项目里,也不能直接互访。
官方地址:https://docs.docker.com/compose/how-tos/networking/
本例把web放入frontend,把app放入frontend与backend,把db只放入backend。因此 app 可以访问 db,web 不能绕过网络边界直接解析 db;数据库还可以在 backend 网络中使用database作为别名。
- 容器之间使用服务名和容器端口,宿主机端口映射不参与容器内 DNS。
aliases是网络级配置,同一个服务在不同网络可以有不同别名。- 排查顺序是网络成员、服务名/别名、外部网络是否已存在。
步骤一:把服务名解析和网络边界写进 Compose 文件
在项目目录创建或编辑 compose.yaml。顶层 networks 只声明网络,真正决定服务能否互访的是每个服务下面的 networks。下面的 # 注释说明了每个绑定的目的。
services:
web:
image: nginx:alpine
networks:
- frontend # 只接入前端网络
app:
image: demo-app:latest
networks:
- frontend # 接收 web 的请求
- backend # 再访问 db
db:
image: postgres:18
networks:
backend:
aliases:
- database # 仅在 backend 中增加可解析别名
networks:
frontend: {}
backend:
internal: true # 数据库网络不提供外部网关
保存后先检查三条关系:web 与 app 共享 frontend,app 与 db 共享 backend,web 和 db 没有共同网络。Compose 默认会给未显式配置网络的服务接入 default,但本例显式声明网络,边界更容易验收。

步骤二:用服务名和别名写连接地址
在 app 的连接配置中使用 db:5432 或 database:5432,其中 5432 是容器端口。不要把宿主机映射端口误写进容器间连接,也不要把一次启动得到的 IP 固定到环境变量里。
environment:
DB_HOST: db # 使用稳定的 Compose 服务名
DB_PORT: "5432" # 使用数据库容器端口,不是宿主机端口
DB_ALIAS_HOST: database # backend 网络中的可选别名
别名只在声明它的网络内有效。若一个网络中的多个容器共用同一个别名,解析到哪个容器并不保证,因此别名适合表达明确的单一依赖,不适合随意复用。
步骤三:检查展开配置并启动项目
打开项目终端并执行下面两条命令。它们是操作命令,不代表文章配图中的真实运行截图;第二条命令会按当前文件创建或更新网络和容器。
# 先展开 Compose 配置,确认 networks 层级和别名没有缩进错误
docker compose config
# 创建或更新服务、网络,并在后台运行
docker compose up -d
当命令完成后,在项目状态中应看到 web、app、db 均处于运行状态,并出现 frontend、backend 两个网络。若只修改服务配置后再次执行 up,容器可能获得新的 IP,但服务名保持稳定;已有连接需要由应用重新解析并连接。
步骤四:按网络成员验收可达范围
在 Docker Desktop 的 Projects/Apps 中打开本项目,进入项目的网络或 Inspect 相关状态面板。先看成员,不要先猜 IP:frontend 应包含 web、app,backend 应包含 app、db,并能看到 db 的 database 别名。
成功条件是:app 可用 db 或 database 找到数据库;web 不属于 backend,因此不应把它当作数据库客户端。图中的按钮、列表和绿色状态都是为本教程绘制的界面说明,不是 Docker Desktop 的真实截图。

| 检查对象 | 应看到的结果 | 异常含义 |
|---|---|---|
| frontend 成员 | web、app | web 无法访问 backend 内服务 |
| backend 成员 | app、db | app 到 db 的 DNS 路径存在 |
| db 别名 | database | 别名缩进或网络范围配置错误 |
步骤五:按三层顺序处理解析失败
- 先看网络成员:两个服务没有共同网络时,补服务级
networks,不要先改 DNS。 - 再看名称和端口:容器内使用服务名与容器端口;宿主机访问才使用
localhost:映射端口。 - 最后看外部网络:跨 Compose 项目共享网络时,使用
external: true,并在启动前先创建同名网络;网络不存在会直接报错。
networks:
shared:
external: true # 该网络由 Compose 之外预先创建
name: inter-project # 两个项目必须使用相同的实际网络名
不要用 network_mode: host 代替自定义网络:主机网络模式下服务名 DNS 不按本例工作,也不能和 networks 同时配置。到这里,服务名、别名和网络边界三件事已经分别验收。
常见问题
为什么 web 能启动,但解析不到 db?
启动成功不等于网络共享。检查 web 是否只接入 frontend、db 是否只接入 backend;如果没有共同网络,解析失败是配置边界的结果。
服务名和 aliases 应该选哪一个?
默认优先使用服务名,因为它随 Compose 服务定义稳定。只有需要兼容旧连接地址或表达明确业务别名时,再在对应网络下增加 aliases。
修改 compose.yaml 后为什么 IP 变了?
容器重建后 IP 可以变化,服务名保持不变。应用应捕获旧连接断开并重新按服务名解析,不应把旧 IP 写死。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
236 收藏
-
308 收藏
-
260 收藏
-
173 收藏
-
389 收藏
-
258 收藏
-
263 收藏
-
285 收藏
-
331 收藏
-
300 收藏
-
337 收藏
-
253 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习