Docker Compose 启动时报 no service selected
Compose 文件中的服务都设置了 profiles,却没有启用匹配的 profile 时,up 可能报 no service selected。对比服务列表,按需启用 profile、指定服务,或恢复核心服务的默认启动方式。
Compose 文件里明明有多个服务,运行 docker compose up -d 却只得到:
no service selected
运行 docker compose config --services,服务列表也是空的;普通 config 输出甚至只剩 services: {}。如果 config --profiles 仍能列出 profile 名称,应检查是否所有服务都设置了 profiles,但本次命令没有启用任何匹配的 profile。
profiles 会参与服务选择。给服务加上它,并不只是增加一个方便分类的标签。未匹配到启用 profile 的服务通常会被排除;所有服务都被排除后,普通 up 就没有可启动的对象。
下面按 Docker Compose V2 的命令写法说明。错误文本和配置输出可能随版本变化,判断应以文件内容、启用的 profile 和实际服务列表为准。不要仅凭可执行文件名带不带连字符判断版本。
对比启用 profile 前后的服务列表
先确认检查与启动使用的是同一份文件。以下 compose.yaml 是示例文件名;有多个 -f、指定项目目录或环境文件时,要在这些命令里保留相同参数和文件顺序:
docker compose -f compose.yaml config --profiles
docker compose -f compose.yaml config --services
docker compose -f compose.yaml --profile app config --services
把 app 换成第一条命令列出的实际名称。第一条用于查看文件定义了哪些 profile,不能据此认定它们已经启用。第二条查看当前条件下的服务,第三条则验证启用指定 profile 后是否出现预期服务。
例如,这份配置把两个服务分别放在不同 profile 中:
services:
api:
image: registry.example.com/team/api:tested
profiles: [app]
reports:
image: registry.example.com/team/reports:tested
profiles: [reports]
这是服务选择的示例配置,镜像地址需替换成你有权限使用、已验证的测试镜像,并补回项目需要的配置。没有其他启用 profile 的设置时,普通命令选不到这两个服务;启用 app 后会选到 api。
若启用正确 profile 后仍然没有预期服务,应回头核对实际读取的文件、合并配置和 profile 名称。若报的是变量缺失或依赖不满足,也要先解决对应的配置错误。不要因为服务列表为空就修改 Docker socket 权限或删除容器数据;服务筛选发生在 Compose 配置层,提权不会自动启用 profile。
按需启动一组,或明确指定一个服务
确认服务列表正确后,在测试环境中用同样的 profile 启动:
docker compose -f compose.yaml --profile app up -d
也可以通过命令前的环境变量启用它:
COMPOSE_PROFILES=app docker compose -f compose.yaml up -d
这里的变量属于运行 Compose 命令的进程。不要把它仅写进某个服务的容器环境变量,然后期待它反过来控制 Compose 的服务选择。上面的前缀写法只给这一条命令设置变量,不会永久修改当前终端。
如果只想启动某个明确的服务,可以直接指定服务名:
docker compose -f compose.yaml up -d api
被显式指定的服务可以在没有手动启用 profile 时运行。Compose 还会按依赖关系处理它需要的服务,但不会因为其他服务拥有相同 profile,就把它们全部启动。
profile 名和服务名不是一回事:示例里的 app 是 profile,api 才是服务名。把 app 放到 up -d 后面,会被当成服务名处理,除非文件恰好也定义了同名服务,否则不会达到启用 profile 的效果。
对于 depends_on,还要检查依赖服务是否可用。如果依赖也受另一个未启用的 profile 限制,模型可能无效。应按部署意图启用所需的 profile,或让共同依赖成为默认服务,不要为了消除配置报错直接删除真实依赖。
默认就应运行的服务可以去掉 profiles
如果 api 本来就是每次部署都需要的主服务,保留它的全部配置,只移除该服务的 profiles 字段即可。没有 profiles 的服务默认启用,调试工具、报表任务等仍可继续使用 profile 按需启动。
这个改动会影响后续所有未指定服务名的 up:主服务将进入默认选择范围。改之前保存配置版本,确认定时任务和部署脚本是否依赖原先的隔离方式;不要一口气删除所有服务的 profiles,以免调试或维护任务也变成默认启动项。
若只想查看所有 profile 下能选到的服务,可以使用:
docker compose -f compose.yaml --profile '*' config --services
这里的星号需要引号,避免被 shell 展开。把同样参数用于 up 会启用全部 profile,可能启动不该运行的工具或任务,因此不应把它当作通用修复命令。
名为 all 的 profile 没有内置的“全部”含义。只有文件确实给相关服务分配了 all,--profile all 才会选中它们;真正的全选写法是 --profile '*'。
启动后的检查和撤回
config --services 能证明 Compose 选中了服务,不能证明容器已经正常工作。启动命令会创建或启动容器;已有容器的配置或镜像发生变化时,还可能停止并重建容器。正式环境操作前应保留配置、原镜像引用及所需数据备份,安排允许变更的时间。
用同一项目参数查看包括已退出容器在内的状态:
docker compose -f compose.yaml --profile app ps --all
检查目标服务是否存在、是否退出或持续重启;配置了健康检查时再看健康状态,并验证实际接口或业务功能。如果容器启动后退出,服务选择问题可能已经解决,接下来需要处理容器自身的错误。
如果只是本次试启动了原先未运行的 api,需要撤回时可以单独停止它:
docker compose -f compose.yaml stop api
stop 保留容器,不删除它。若同时启动了依赖,应根据启动前的状态判断哪些也需要停止,不要误停原本就在运行的服务。仅从下一条命令中去掉 --profile,不会自动撤回此前已经运行的容器。
若改过 YAML,恢复保存的配置后重新核对服务列表;若容器已被重建,恢复原配置与镜像也需要单独安排。配置回退不会撤销应用已经写入的数据,不要用 down -v 处理这类服务选择错误。


