docker-compose.yml 是服务契约而非配置清单,缩进、冒号、空格/tab 混用会导致解析失败;service 名须为合法 dns 标签(如 web-app),不可含下划线;depends_on 仅控启动顺序,不保证就绪,需配合 healthcheck;bind mount 用绝对路径并预设权限;network_mode: host 使服务脱离 compose 网络;.env 变量需通过 docker-compose config 验证。

docker-compose.yml 文件不是配置清单,而是服务契约——写错一个缩进、漏掉一个冒号、混用空格和 Tab,docker-compose up 就会直接报 yaml: unmarshal errors 或静默忽略字段。它不校验语义,只认结构。
service 名字必须是合法 DNS 标签,不能含下划线
Docker Compose 会把 service 名作为默认网络中的主机名。如果写成 web_app,容器内 ping web_app 会失败,因为下划线不被 DNS 解析支持。
- ✅ 正确写法:
web-app、db、cache - ❌ 错误写法:
web_app、redis-server-1(末尾数字虽合法,但易与自动扩展名冲突) - ⚠️ 注意:
container_name可以自定义(如web_app_v2),但它不影响服务发现,仅用于docker ps显示和docker exec -it <name></name>
depends_on 不等于“等它启动完成”,只是控制启动顺序
depends_on 只保证依赖服务的容器已 created 并 started,但不检查其内部应用是否 ready(比如 PostgreSQL 还在初始化 WAL,MySQL 还没开监听端口)。直接连过去大概率报 Connection refused。
Python Linux版 为 Python.org 官方提供的 Python 3.14.6 Linux/Unix 源码包,适合在Linux/Unix环境中安装、运行 Python 代码并学习函数、模块和脚本开发。
- ✅ 真实可用方案:在应用侧加重试逻辑,或用
healthcheck+condition: service_healthy - ✅ 示例片段:
services:
app:
depends_on:
db:
condition: service_healthy
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 5
- ⚠️ 注意:
healthcheck是容器级探针,不替代应用层健康接口;interval太短会压垮 DB,太长则拉起慢
volumes 路径写错会导致数据丢失或权限拒绝
本地路径映射(bind mount)若用相对路径,基准是 docker-compose.yml 所在目录,不是执行命令的当前目录;宿主机路径不存在时,Docker 会自动创建空目录——但可能属 root,导致容器内非 root 用户(如 node、postgres)无法写入。
- ✅ 推荐写法:用绝对路径 + 显式
chown初始化(如sudo chown -R 991:991 ./data/postgres,其中 991 是 postgres 官方镜像的 UID) - ✅ 避免写法:
./data:/var/lib/postgresql/data(相对路径)、./config/nginx.conf:/etc/nginx/nginx.conf(覆盖只读文件易失败) - ⚠️ 注意:
volume类型(非 bind mount)由 Docker 管理,路径不可见,适合无状态缓存;bind才能映射宿主机真实路径,适合开发或持久化
network_mode: "host" 和 services 同处一个 compose 文件时会失效
一旦任意 service 声明了 network_mode: host,该服务就脱离 Compose 默认桥接网络,无法通过 service 名访问其他服务(如 curl http://redis:6379 会失败),且 ports 字段被忽略(端口直接暴露在宿主机)。
- ✅ 替代方案:用
networks自定义 bridge 网络,并确保所有 service 加入同一网络(默认已加入) - ✅ 若真需 host 模式(如性能敏感或需访问
/dev设备),应单独拆出该 service,不和其他服务共用docker-compose.yml - ⚠️ 注意:
host模式下environment中的HOSTNAME、PATH等变量来自宿主机,不是容器环境
最常被跳过的其实是 .env 文件加载顺序和变量展开规则——${VAR} 在 YAML 里不解析,必须靠 shell 层预处理或 Compose 的 env_file;而 docker-compose config 是唯一能验证语法+变量替换是否成功的命令,别等 up 报错才查。










