linux下用docker-compose编排多容器应用的核心是写对docker-compose.yml并执行命令;安装失败常见于未安装、路径/权限问题或版本不匹配;yaml缩进错误、字段误用、depends_on逻辑误解、卷清理不当等是主要故障点。

Linux 下用 docker-compose 编排多容器应用,核心就一条:写对 docker-compose.yml,再在同级目录下执行命令——不是靠记一堆 docker run 参数硬凑,也不是靠 shell 脚本拼凑启动顺序。
docker-compose 安装失败或版本不匹配的常见表现
执行 docker-compose --version 报错 command not found,或提示 docker-compose: command not found,基本是没装、路径不对、权限缺失;若报错 ERROR: Version in "./docker-compose.yml" is unsupported,则是 docker-compose 版本太低,不支持你写的 version: '3.8' 这类高版本字段。
- 官方二进制安装最稳:用
curl -L "https://github.com/docker/compose/releases/download/v2.36.2/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose(注意替换最新版号) - 必须加可执行权限:
chmod +x /usr/local/bin/docker-compose - 验证前先确认 Docker 引擎已运行:
systemctl is-active docker应返回active - Compose v2+ 与 Docker Engine 20.10+ 兼容性最好;v1(如 1.29.2)只支持到
version: '3.9',但已停止维护,别用
docker-compose.yml 缩进错误和字段误用导致服务起不来
YAML 对空格极其敏感,Tab 键、多缩少缩、冒号后缺空格,都会让 docker-compose config 直接报错退出,up 命令根本不会执行。
-
services下每个服务名顶格写,其子字段(如image、ports)必须统一用 2 个空格缩进 -
environment下变量要写成KEY: value或- KEY=value,不能混用;ports必须是字符串数组:["8080:80"],写成8080:80(无引号)会解析失败 -
depends_on只控制启动顺序,不等待依赖服务“就绪”;比如db容器启动了,但 PostgreSQL 还没完成初始化,web就可能连不上——得靠应用层重试或加healthcheck - 网络互通靠默认
default网络,服务间直接用服务名当 hostname,比如redis服务,其他容器里写redis:6379就行,不用配 IP
docker-compose up -d 启动后容器立即退出的排查点
执行 docker-compose up -d 后 docker-compose ps 显示状态是 Exit 1 或 Restarting,说明容器启动失败,不是挂了,是根本没跑起来。
- 先看日志:
docker-compose logs -f <service_name></service_name>,重点找exec user process caused: exec format error(架构不匹配)、no such file or directory(入口脚本路径错)、Permission denied(缺少执行权限) - 检查镜像是否真能本地拉取:
docker pull nginx:alpine,避免因网络或仓库限制造成静默失败 - 绑定挂载路径宿主机不存在会失败,比如
volumes: ["./conf:/etc/nginx/conf.d"],但当前目录下没有conf文件夹,就得提前mkdir conf - 使用
command覆盖默认启动命令时,如果写成command: python app.py,实际等价于sh -c "python app.py",容易因 shell 解析出错;更稳妥写法是command: ["python", "app.py"]
docker-compose down 清理不干净,下次 up 失败
docker-compose down 默认只删容器和网络,不删命名卷(volumes),也不删构建的镜像。残留卷会导致数据冲突,比如 PostgreSQL 第二次启动拒绝覆盖已有数据目录。
- 要彻底清理(含命名卷):
docker-compose down -v;但注意:这会丢掉所有持久化数据,生产慎用 - 想保留数据又避免冲突?把卷声明成外部卷:
volumes: [mydata:/var/lib/postgresql/data],并在volumes:段显式定义mydata: {},这样down -v才会删它 - 构建的镜像不会被自动清理,多次
up --build会堆积大量悬空镜像,定期执行docker image prune -f - 环境变量从
.env文件加载,但该文件不会被down影响;若改了.env却没重启服务,旧值仍生效——记得down后再up
真正卡住人的往往不是语法,而是 YAML 缩进肉眼难辨、服务健康状态没等齐、卷路径权限不对、或者以为 depends_on 能替代应用层连接池重试逻辑。动手前先 docker-compose config 验证结构,启动后立刻 logs -f 看输出,比反复猜快得多。










