Docker Compose 中的项目名、服务名、容器名与数据卷名
前言
在同一台机器上跑多份 Compose 时
- 项目名决定容器、网络、卷等资源的前缀是否冲突。
- 服务名既是
compose.yaml里的键,也常常作为默认网络上的 DNS 名称。 - 容器名是
docker ps里看到的 宿主机维度的唯一名字,默认由 Compose 按 项目名 + 服务名 + 副本序号生成,也可用container_name写死。 - 数据卷名若在文件里写的是「逻辑卷键」,运行时往往会带上项目前缀,除非你用了 外部卷或
name固定全名。
项目名
默认值与优先级
Compose 会为本次编排计算一个 项目名(project name),用于拼接容器名、默认网络名、未显式命名的命名卷等。
常见优先级(由高到低)如下。
- 命令行
-p或--project-name。 - 环境变量
COMPOSE_PROJECT_NAME。 - Compose 文件顶层的
name字段(Docker Compose V2 开始支持)。 - 若以上皆无,则使用 Compose 文件所在目录的目录名。
下面是一段仅用于说明「文件中声明项目名」的示例,把 myshop 换成你的工程名即可。
1 | name: myshop |
查看版本
1 | docker-compose version |
注意点
项目名里建议避免空格与特殊符号,使用和 DNS 标签兼容的 [a-z0-9_-] 一类字符更省事。
改项目名往往意味着一整套新前缀的网络与卷(除非卷用了 外部或 name),迁移数据前要核对 docker volume ls。
同一项目名重复执行 docker compose up 会沿用同一前缀下的资源命名空间,适合做「这一套栈」的幂等拉起。
项目名建议直接在
docker-compose.yml中设置,默认的容器名和数据卷名都依赖项目名。项目名如果没设置会默认使用所在的文件夹名。
服务名
设置
services: 下的 键即为服务名,例如 web、db。
1 | services: |
该键用于 docker compose up db、docker compose exec web sh 等子命令的定位。
命名习惯与约束
服务名应视为 稳定的逻辑名称:与镜像名、运行态容器名区分开。
后者见下文 容器名 一节。
在 用户自定义网络上,同一网络内容器可用 服务名做 DNS 解析(例如在 web 里 ping db)。
具体行为以 Compose 为该网络配置的 alias、depends_on 与网络模式为准。
建议使用 小写字母、数字、下划线或连字符,并避免与镜像仓库地址、端口等概念混淆。
容器名
默认命名
不显式写 container_name 时,容器名一般由 项目名、服务名、实例序号 依次拼接而成。
单实例时序号也常为 1。
常见形式为 {项目名}-{服务名}-{序号}(例如 myshop-web-1)。
容器名不建议自己命名,如果要自己命名最好前面带上项目名,否则在查找容器的时候不好区分。
显式 container_name
需要 固定宿主机上的名字(例如给外部脚本、旧版编排或监控探针用)时,可在服务下写 container_name。
1 | services: |
container_name 在整台 Docker 宿主机上必须 全局唯一;与别的 Compose 栈、手工 docker run --name 也不能撞名。
一旦写死 多副本(deploy.replicas > 1 或 scale)通常会 冲突或 不再被支持,因此 有状态单实例、边缘代理这类场景更常见。
未写 container_name 时,Compose 仍可用 服务名在默认网络上做服务发现。
写了 container_name 并不等于把 DNS 查询名强行改成该字符串,别名仍以 Compose 网络配置为准。
与项目名、服务名的关系
项目名变更会牵动 默认容器名前缀,容易让日志与告警里的 旧名失效。
服务名是 Compose 子命令与 默认 DNS 的入口;容器名更多是 运维与排障视角的 实例标签。
同一服务多次 up / recreate 时 容器 ID会变,默认容器名往往仍遵循同一模式。
若依赖 固定容器名做自动化,优先评估是否应改成 标签、网络别名或 编排级服务名。
数据卷名
默认命名
volumes: 顶层下的 键是 卷在项目内的逻辑名;挂载到服务里时使用 逻辑名:容器路径。
1 | services: |
未指定 external、也未写 name 时,Docker 创建的 实际卷名通常是 ${项目名}_${逻辑卷键}(例如 myshop_pgdata)。
逻辑键仅在本 Compose 文件内用来引用这份卷。
显式命名
若你希望卷名 固定、且不随项目前缀变化,在该卷定义下使用 name。
1 | volumes: |
此时宿主上的卷名一般为 corp_pg_prod_01(与 name 一致),适合做 跨项目共用或与运维命名规范对齐。
改用 name 后要警惕:旧前缀卷若仍存在,会变成「新卷空目录」,看起来像数据丢失。
外部卷 external
卷已 docker volume create 或由别的栈创建时,应在 Compose 里声明 external: true,必要时用 name 指向真实卷名。
1 | volumes: |
外部卷的 name 必须是 宿主已存在的卷名,否则 up 会报错。
bind mount 不算命名卷
形如 ./data:/app/data 的挂载是 bind mount,不产生 volumes: 顶层键意义上的「命名卷」。
匿名卷、tmpfs 等也不与本节的「命名卷前缀」混在一起讨论。
命名建议
项目名建议指定名称。
服务名始终自己起简短稳定的名字。
其余交给默认:容器名、命名卷(不写卷级 name)用自动生成即可。
小结
项目名决定默认前缀:-p、COMPOSE_PROJECT_NAME 与文件 name 优先于目录名推断。
服务名是编排与 DNS(用户定义网络) 中的稳定键,应与 容器名、镜像名区分开。
容器名默认常含 项目名、服务名、序号;container_name 可写死但须 全局唯一,且不利多副本。
命名卷未写 name 时多为 项目名_逻辑键;要写死全名或接外部卷则用 name / external。
调整项目名、container_name 或卷 name 前,先在 docker ps -a、docker volume ls、docker network ls 里核对,避免接上空白数据卷或名称冲突。