关键在于分层控制与精准覆盖:基础层定义共用服务,覆盖层按环境定制配置,变量层提供默认值;通过-f顺序加载实现覆盖,数组类字段追加,依赖用condition控制启动节奏,敏感信息严格隔离。

用 Docker Compose 管理多服务环境的配置,关键不是堆文件,而是分层控制和精准覆盖。一套清晰、可复用、易维护的结构,比写死一堆 if-else 更可靠。
按职责拆分配置文件
把配置按“谁负责什么”来切分,避免一个文件又管网络又管日志还管密码:
-
基础层(compose.yaml):只放所有环境共用的部分——服务名、镜像名、默认端口、卷定义、网络声明。不写任何环境相关值,比如不写
DEBUG=true,也不暴露数据库端口。 -
覆盖层(compose.dev.yaml / compose.prod.yaml):只改需要变的地方。开发环境加
volumes和environment,生产环境加deploy、healthcheck和资源限制。 -
变量层(.env):存放默认值,如
APP_VERSION=1.2.0、POSTGRES_VERSION=15。它不决定逻辑,只提供 fallback 值。
用好文件合并规则
Docker Compose 按顺序加载多个 -f 文件,后面的配置会覆盖前面同名字段,但数组类(如 ports、volumes)是追加而非替换:
- 启动开发环境:
docker compose -f compose.yaml -f compose.dev.yaml up - 启动生产环境:
docker compose -f compose.yaml -f compose.prod.yaml up - 测试环境加自定义 DB 地址:
MYSQL_HOST=test-db.example.com docker compose -f compose.yaml -f compose.test.yaml up,变量会自动注入到compose.test.yaml中的${MYSQL_HOST}占位符里。
服务间依赖与启动节奏控制
多服务不是一起拉起来就完事,得让它们按需就位:
- 用
depends_on+condition区分依赖强度:数据库用service_healthy,缓存用service_started,避免应用连不上就崩溃。 - 在 web 服务里加
restart: unless-stopped,数据库加healthcheck,让 Compose 主动判断状态而非靠超时硬等。 - 对启动慢的服务(如 Elasticsearch),可在应用侧加重试逻辑,或用
wait-for-it.sh脚本做前置检查,Compose 本身不处理等待超时。
敏感信息与环境隔离不混用
密码、密钥、API Token 这类不能进 Git 的内容,必须和配置结构分离:
- 在
compose.prod.yaml中用${DB_PASSWORD}引用变量,而不是写死值。 - 部署时通过 CI/CD 注入环境变量,或挂载外部 secret 文件(如
secrets字段 + Docker Swarm 或 Kubernetes 兼容方式)。 - 本地开发用
.env存测试账号,但确保该文件被.gitignore排除;生产绝不依赖.env,只认运行时传入的变量。











