Docker Compose 把卷名写进 depends_on 后报 undefined service
depends_on 必须引用 services 下的服务名。数据库服务叫 database、数据卷叫 db 时,应修正依赖引用,保留原卷与挂载,再用相同部署参数校验配置。
执行 docker compose up -d 时,Compose 在创建容器之前拒绝项目:
service "app" depends on undefined service db: invalid compose project
文件里明明有 db,却仍然报未定义时,先看它出现在哪一层。顶层 volumes 下的 db 是卷名;depends_on 引用的必须是 services 下的服务名。数据库数据卷存在,不代表项目里存在同名数据库服务。
下面针对现代 Docker Compose 插件的项目配置校验。不同版本的错误措辞可能不同,但不能仅凭“本机能运行、另一台主机失败”,就把这个错误归为云平台网络或数据库版本问题。应先核对两边实际读取的文件和服务定义。
找出 db 所属的配置层级
下面是说明名称关系的简化配置。镜像名和数据路径均为占位示例,不能直接替代已有数据库部署;真实项目仍需保留认证、数据目录和其他必要设置:
services:
database:
image: your-database:your-tag
volumes:
- db:/var/lib/example-db
app:
image: your-app:your-tag
depends_on:
- db
volumes:
db:
这里定义了两个服务:database 和 app。db 只在卷声明与挂载中出现,没有 services.db。Compose 处理 app 的启动依赖时找不到这个服务,于是拒绝整个项目。
三个位置的含义分别是:
services.database:数据库服务的名称,也是这个例子中可供depends_on引用的名称。volumes.db:命名卷的配置项,用来描述存储。services.database.volumes里的db:...:把这个卷挂到数据库容器指定路径。
此外,container_name 只是在给容器指定自定义名字。即使它写成 db,也不会把 database 这个服务改名为 db。depends_on 中不要填卷名、镜像名或自定义容器名来代替服务名。
只修正依赖引用,保留数据卷
在上面的配置中,把 app 的依赖改成已经存在的 database 即可。修改后的相关服务片段为:
services:
app:
image: your-app:your-tag
depends_on:
- database
这是修改位置的片段,不是完整 Compose 文件;应在原文件中修改对应值,保留原来的 database 服务、卷声明和应用配置。原本的 db:/var/lib/example-db 与顶层 volumes.db 不需要随之改名。
若实际使用长语法,则修改作为键的服务名,同时保留原有条件。例如,原本采用 service_started 时,对应片段是:
depends_on:
database:
condition: service_started
如果原项目使用的是其他条件,不要为了匹配例子顺手改掉它。此处要修正的是引用目标,而不是重新设计启动条件。
也可以通过重命名服务让名字一致,但通常没有必要为这个错误扩大改动范围。服务名还可能用于容器间访问、脚本和其他依赖声明;改名后这些位置都需要复核。卷的实际名称又可能受项目名或显式 name 设置影响,随意改卷名可能让应用挂到另一个空卷,看起来像数据丢失。
先保存 Compose 文件原版本,再修改错误的依赖引用。不要删除数据库目录、删除卷或创建一个空的 db 服务来让校验勉强通过。新建占位服务不能替代真正的数据库依赖。
用启动时相同的文件验证
在项目目录先记录使用的 Compose 版本,并校验配置。单文件项目示例:
docker compose version
docker compose -f compose.yaml config --quiet
config --quiet 校验配置而不打印完整模型,避免顺手把环境变量和连接配置输出到终端记录中。校验通过只说明项目模型有效,不表示数据库已经启动或应用连接成功。
如果平时同时使用基础文件和环境文件,校验也必须保留同样的文件顺序、项目名与环境。示例:
docker compose -p demo -f compose.yaml -f compose.prod.yaml config --quiet
docker compose -p demo -f compose.yaml -f compose.prod.yaml config --services
demo 和两个文件名应替换为实际部署参数。config 会合并文件并解析变量,--services 输出服务名。修正后应能看到 database 和 app,而不是要求卷名 db 也出现在服务列表中。
配置仍无效时,服务列表命令本身也可能报错,不必期待它先列出一份可用结果。回到实际加载的文件,检查 database 是否位于顶层 services 下,以及提供该定义的文件是否被包含。只在另一份未加载的文件中找到同名服务,不能满足当前项目的依赖引用。
若本机与部署主机结果不同,对比实际文件内容、执行目录、完整启动参数和 Compose 版本。两边目录中恰好都有一个同名文件,并不能证明加载的是同一份配置。分享诊断材料时只保留必要的名称关系,删去密码、令牌和真实连接串。
更新后分别检查启动与就绪
本地配置校验通过后,在确认备份和允许的维护时段内,沿用原项目参数更新服务。up 会按配置创建或更新容器;配置或镜像变化时可能重建现有容器,因此不能把它当成无影响的验证命令,也不要临时换一个项目名去操作已有数据库。
这次修复的直接成功标准是:原来的 undefined service db 消失,Compose 能按正确服务名解析依赖并继续启动。随后还要确认数据库与应用进程正常、应用实际连到预期数据库,原数据和持久化挂载保持一致。
短语法 depends_on 只对应服务启动条件,不保证数据库已经能处理查询。若改名后出现 connection refused,这是进入运行阶段后的另一个问题,应结合健康检查和应用重试处理,不能据此把依赖名改回卷名。
需要回退时,恢复最近一份可用配置并用相同项目参数重新应用。若备份的配置本身就带有错误引用,应保留它供比较,不应把它当成可用回退版本。配置回退不会撤销应用已经写入的数据;涉及数据恢复时,应按数据库自己的备份恢复流程处理。


