最高效的方式是用服务名通信而非ip或localhost,需将互通服务接入同一自定义bridge网络(如app-net)以启用内置dns解析,实现零配置自动发现;若需分层隔离,则让中间服务(如api)跨接frontend与backend两个网络,使web无法直连db而必须经api转发;注意容器内禁用localhost访问其他服务、确保依赖服务已启动、显式声明networks字段、外部网络须预先创建。

直接用服务名通信,不用IP或localhost,这是Compose跨服务内网通信最高效的方式。关键不是“共享网络”,而是让需要互通的服务接入同一个自定义网络,再配合内置DNS解析,就能实现零配置、自动发现、动态适配的通信效果。
用一个自定义网络连通所有需互通服务
这是最常用也最推荐的做法,适合大多数前后端分离、API+DB等结构。
- 在 networks 下定义一个 bridge 网络(如
app-net) - 把 web、api、db 等服务都声明加入该网络,不写
external: true - 启动后,它们就在同一局域网内,
ping api、curl http://db:5432都能直接通
让中间服务跨接多个网络实现分层访问
当需要隔离前端和数据库,又想让API充当中间桥梁时,就靠这个模式。
- 定义两个网络:
frontend和backend -
web只加frontend,db只加backend -
api同时加入两个网络 → 它既能被 web 访问,也能访问 db - 这样 web 就无法直连 db,但流量经 api 转发是通的,安全又可控
避免常见通信失败陷阱
很多“连不通”其实不是网络配置问题,而是误用了地址或启动顺序。
- 容器里别用
localhost访问其他服务——它只指向自己,要用服务名(如db) - 确保目标服务已启动再发起连接,可用
depends_on控制顺序(注意:它只管启动顺序,不等服务就绪) - 同一项目下不同服务默认不在同一网络时,
docker-compose.yml中必须显式声明networks字段,不能省略 - 如果复用外部网络(
external: true),要先用docker network create创建好,否则启动失败
不需要额外装插件、不用改 hosts、也不用手动查 IP。只要网络声明对了,服务名就是域名,Docker 自己搞定解析和路由。










