services 是什么
services 是 compose 文件的顶层键,也是整套编排的主体:每个子键是一个服务名,Compose 按它创建容器、注册网络别名、建立依赖关系。一份 compose 文件可以没有 volumes、networks、configs,但不能没有 services。
基本信息
| 文件结构 | services / networks / volumes / configs / secrets 五个顶层键,services 必填 |
|---|---|
| 容器命名 | 默认 <项目名>-<服务名>-<序号>,如 shop-web-1 |
| 项目名来源 | -p 参数指定,默认取 compose 文件所在目录名 |
| 服务名作用 | logs / exec / run / build / ps 等命令的定位参数 |
| 固定名称 | container_name 可覆盖默认命名 |
典型使用场景
- 本地一键起一组服务(web + api + db + 缓存),省掉一串 docker run 参数
- 容器间互访直接写服务名:同一项目网络内有嵌入式 DNS 解析,容器重建换 IP 也不影响调用方
- 多环境复用同一份文件:开发环境走 build、生产环境走 image,用覆盖文件与 .env 切换差异
- 把启动依赖写进 depends_on,up 时按依赖顺序拉起
- CI 里用 docker compose up -d 起测试依赖,跑完 docker compose down 清理
- 把服务拓扑当成可评审的文件提交进仓库,配合 docker compose config 在合并前校验
最小示例
最小示例
services:
web:
image: nginx:1.27-alpine # 一个服务默认对应一个容器
ports:
- "8080:80" # 宿主端口:容器端口
api:
build: ./api # 也可以只写 image 直接拉取
depends_on:
- web # 仅保证启动顺序
worker:
image: app/worker:1.4.2
restart: unless-stopped # 生产常用重启策略
command: ["./worker", "--concurrency=4"]服务名与容器名对照
| 文件里的写法 | 实际容器名 | 说明 |
|---|---|---|
| web | shop-web-1 | 默认 <项目名>-<服务名>-<序号>,序号从 1 开始 |
| container_name: shop-web | shop-web | 固定名字,无法再用 --scale 扩容 |
| 启动时加 -p prod | prod-web-1 | 项目名决定网络与卷的命名前缀 |
| -p prod up --scale web=3 | prod-web-1/2/3 | 扩容后靠序号区分副本 |
服务名同时是网络别名:同项目网络内的其他服务用服务名就能连通,这也是容器重建后 IP 变化不影响调用的原因。
改服务名的代价是容器重建加别名变更,反向代理 upstream、数据库白名单、监控采集等引用它的地方要同步改,上线后尽量不动名字。
服务名同时也决定了网络别名与卷前缀:同一份文件换项目名(-p)启动会得到完全独立的一套容器、网络与卷,这也是在同一台机器上并行跑多套环境的方法。