登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  软件教程

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,但本例显式声明网络,边界更容易验收。

Docker Compose 服务 web app db 与 frontend backend 网络和 database 别名的配置说明图
图1:Docker Compose 网络配置说明图,展示服务名 DNS 与自定义网络的绑定关系,不是实际截图。

步骤二:用服务名和别名写连接地址

在 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 的真实截图。

Docker Compose frontend backend 网络成员、database 别名与服务运行状态的验收说明图
图2:Docker Compose 网络结果说明图,展示成员与别名的验收状态,不是运行截图。
检查对象应看到的结果异常含义
frontend 成员web、appweb 无法访问 backend 内服务
backend 成员app、dbapp 到 db 的 DNS 路径存在
db 别名database别名缩进或网络范围配置错误

步骤五:按三层顺序处理解析失败

  1. 先看网络成员:两个服务没有共同网络时,补服务级 networks,不要先改 DNS。
  2. 再看名称和端口:容器内使用服务名与容器端口;宿主机访问才使用 localhost:映射端口。
  3. 最后看外部网络:跨 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 写死。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>