Linux Docker Compose 服务编排实战

6次阅读

应使用 healthcheck 配合 depends_on 的 condition: service_healthy,同时应用自身需实现连接重试;容器秒退需检查 command/entrypoint 覆盖、日志和交互式调试;挂载权限问题通过 user: “${uid}:${gid}” 和 sysctls 修复;多环境用多文件组合(如 prod.yml)分离配置。

Linux Docker Compose 服务编排实战

docker-compose.yml 里 depends_on 不等容器就绪,怎么办

它只等容器启动成功(createdrunning),不等应用端口监听或健康检查通过。比如 db 容器进程起来了,但 postgresql 还在初始化,此时 app 就可能连不上。

实操建议:

  • healthcheck 配合 depends_oncondition 字段,例如:
    depends_on:   db:     condition: service_healthy
  • db 服务必须定义 healthcheck,比如用 pg_isready -U postgres -d mydb
  • 别依赖 depends_on 做业务级等待——应用自身该重试就得重试,docker 不负责应用逻辑就绪

docker-compose up 启动后容器秒退,常见原因

最常踩的坑是命令覆盖或入口点失效,尤其改过 commandentrypoint 后。

排查方向:

  • 运行 docker-compose ps 看状态,如果显示 Exit 1,立刻查日志:docker-compose logs <service_name></service_name>
  • 确认镜像默认 CMD 是否被空 command: [] 或错误字符串覆盖(比如写成 command: "npm start" 却没加 sh -c
  • 交互式调试:临时加 stdin_open: truetty: true,再 docker-compose run --rm <service> sh</service> 手动执行启动命令

开发环境想挂载本地代码进容器,但文件权限/热更新失效

linux 主机 UID 和容器内 UID 不一致时,挂载的文件会变成 root:root 或无写权限;某些框架(如 webpack、nodemon)也因 inotify 事件在挂载卷中不可靠而无法触发热重载。

解决方式:

  • user: "${UID}:${GID}"(需 shell 启动前导出环境变量)或硬编码匹配宿主机用户 UID/GID
  • 对 Node.js 项目,在 docker-compose.yml 的服务下加:
    sysctls:   fs.inotify.max_user_watches: 524288
  • 避免用 ./src:/app/src 这种粗粒度挂载;细粒度挂载 + chown -R node:node /app/src 初始化更稳

生产部署绕不开的 docker-compose.yml 分离技巧

开发用的 docker-compose.yml 通常含构建指令、暴露端口、挂载源码——这些不能直接上生产。

推荐做法:

  • 保留基础 docker-compose.yml 描述服务拓扑,把构建、端口、卷等环境相关配置拆到 docker-compose.override.yml(开发默认加载)和 docker-compose.prod.yml(生产显式指定)
  • 生产启动命令固定为:docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
  • prod.yml 中禁用 build:,改用预构建镜像:image: myapp:1.2.3;删掉所有 volumes 挂载,改用 configs 或 secrets 管理配置

多环境配置不是靠 if-else,而是靠文件组合——这个机制本身简单,但容易因为命名不统一或忘记 -f 参数导致配置漏加载。

text=ZqhQzanResources