Docker Compose 生产故障排查:多服务部署稳定性清单

Docker Compose 生产故障排查封面

Docker Compose 生产故障排查的重点,不是再教你如何写第一份 compose.yaml,而是帮助你在服务已经上线后,快速判断问题出在端口、网络、数据卷、启动顺序还是资源瓶颈。很多多服务应用在开发环境运行正常,迁移到 [VPS](https://cn.hostease.com/vps/)([虚拟专用服务器](https://cn.hostease.com/vps/))或[独立服务器](https://cn.hostease.com/dedicated-server/)后却频繁出现 502、数据库连接失败、容器反复重启,这通常不是单个配置项错误,而是部署链路缺少稳定性清单。

本文以一个常见的 Web 应用栈为例:反向代理、应用容器、数据库、缓存和计划任务。我们不重复讲基础编排语法,而是围绕真实生产故障拆解排查顺序。你可以把它当作上线前后的检查表,配合 服务器运维指南、网站性能优化指南 一起使用,先定位问题,再决定是否需要扩容或调整架构。

先确认故障边界:是容器问题还是宿主机问题

生产环境排障最容易走偏的地方,是一开始就盯着某个服务日志。更稳妥的做法是先判断故障范围:只有一个容器异常,还是整台服务器的网络、磁盘、内存都在告警。边界判断清楚后,后续命令才有意义。

docker compose ps

docker compose logs --tail=100 app

free -h
df -h
docker system df

docker stats --no-stream

如果 docker compose ps 中只有 app 服务不断重启,而数据库和缓存稳定,优先检查应用配置、依赖连接和健康检查。如果多个容器同时异常,且 df -h 显示磁盘占用超过 90%,就应先清理日志、镜像缓存或扩容磁盘,而不是反复重启应用。

上线后的第一条原则是保留证据。不要在没看日志前执行 docker compose down -v,这个命令会删除容器并可能清理数据卷。排障阶段建议只使用 restart、logs、exec、ps 这类低风险命令。

端口和反向代理:502 与无法访问的高频来源

浏览器打不开页面时,问题不一定在应用代码。对外访问链路通常是:公网请求进入服务器 80/443 端口,再由 Nginx 或其他反向代理转发到内部应用端口。只要其中一个端口映射、监听地址或容器网络写错,就会出现 502、连接超时或空白页。

ss -lntp | grep -E ':80|:443'

docker compose exec nginx curl -I http://app:3000/health

curl -I http://127.0.0.1

如果在 nginx 容器内访问 http://app:3000/health 失败,说明问题在 Compose 内部网络或应用监听地址;如果容器内访问成功,但宿主机访问失败,则重点检查端口映射、防火墙和反向代理配置。

生产配置中,数据库和缓存不建议映射到 0.0.0.0。更安全的写法是让它们只在内部网络通信,必要时仅绑定本机回环地址:

services:
  db:
    image: mysql:8.0
    ports:
      - "127.0.0.1:3306:3306"
    networks:
      - backend

  app:
    expose:
      - "3000"
    networks:
      - frontend
      - backend

这种方式可以减少数据库被公网扫描的风险。若业务还需要 HTTPS,可以在反向代理层配置 SSL(安全传输协议)证书,并参考 网站优化与安全配置 中的证书更新和缓存策略,避免证书过期导致访问中断。

Docker Compose 端口与反向代理排查图

服务依赖:depends_on 不等于真正可用

很多生产事故发生在重启后:容器状态显示已经启动,但应用马上报数据库连接失败。原因是 depends_on 默认只保证容器启动顺序,不代表数据库初始化、缓存加载或迁移任务已经完成。生产环境应把依赖检查写成可验证的健康状态。

services:
  db:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  app:
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

健康检查要写得足够具体。对 Web 应用来说,单纯检查进程存在并不够,建议提供 /health 接口,至少验证应用进程、数据库连接和缓存连接三项。接口返回 200 时再认为服务可用,返回 500 时让日志明确指出失败依赖。

如果你的应用启动时需要执行数据库迁移,建议拆成一次性任务,而不是让主应用容器在启动脚本里隐式执行。这样可以避免多个副本同时迁移,也便于在失败时单独回滚。

docker compose run --rm app npm run migrate
docker compose up -d app

数据卷与备份:先保护数据,再处理容器

容器可以删除重建,数据卷不能随意处理。生产环境中,数据库、上传文件、缓存持久化目录和证书目录都应明确写入命名卷或宿主机目录,并在文档中标注用途。排障时看到 volumes 配置,先判断它承载的是临时缓存还是核心数据。

docker volume ls | grep myapp

docker volume inspect myapp_db_data

docker compose exec -T db mysqldump -u root -p"$MYSQL_ROOT_PASS" myapp \
  | gzip > backups/myapp_$(date +%Y%m%d_%H%M).sql.gz

上线前至少准备两类备份:数据库逻辑备份和文件目录备份。数据库建议每天自动备份一次,保留 7 到 14 天;用户上传目录按业务频率决定,可以每天或每 6 小时同步一次。恢复演练同样重要,至少每月在测试环境执行一次导入,确认备份文件不是空包或损坏文件。

当磁盘空间不足时,先用 docker system df 判断镜像、构建缓存和日志占用,不要直接删除未知数据卷。清理前可以执行:

docker system prune -af

logging:
  driver: json-file
  options:
    max-size: "20m"
    max-file: "5"

Docker Compose 数据卷与备份排查图

网络、DNS 和环境变量:排查服务间连接失败

Compose 网络内的服务名可以直接作为 DNS(域名系统)主机名使用。例如应用连接数据库时应写 DB_HOST=db,而不是 localhost。在容器里,localhost 指向容器自己,这也是数据库连接失败的常见原因。

docker compose exec app getent hosts db

docker compose exec app nc -zv db 3306

docker compose exec app env | grep -E 'DB_HOST|DB_PORT|REDIS'

如果服务名无法解析,检查两个服务是否加入同一个 network;如果端口不通,检查数据库是否监听在容器内部端口;如果环境变量为空,重点排查 .env、env_file 和 CI/CD 注入变量是否一致。生产环境不要把开发环境的 .env 直接复制到服务器,否则很容易出现连接测试库、调试开关未关闭、密钥泄露等问题。

上线前稳定性清单

把上面的排查经验前移到上线前,可以减少大部分重复故障。下面这份清单适合在首次部署、版本更新和服务器迁移前执行。

  • 端口边界:公网只开放 80/443,数据库和缓存不直接暴露;用 ss -lntp 验证监听地址。
  • 健康检查:核心服务配置 healthcheck,应用提供 /health,检查间隔建议 10 到 30 秒。
  • 数据备份:数据库每日备份并保留 7 天以上,恢复演练至少每月一次。
  • 日志轮转:单容器日志限制为 20MB × 5 份,避免磁盘被日志占满。
  • 回滚路径:保留上一版镜像标签和上一份 Compose 文件,升级失败可在 5 分钟内回退。

如果你的业务流量已经稳定增长,还需要评估带宽(单位时间内可传输的数据量)、CPU、内存和磁盘 IO 是否匹配访问峰值。小型站点可以先从 VPS(虚拟[专用服务器](https://cn.hostease.com/dedicated-server/))起步;当数据库、缓存或文件存储需要更强隔离时,再考虑独立服务器。选择服务器时,建议优先确认 CPU 核心数、内存、磁盘类型、备份策略和技术支持响应时间,而不是只看价格。

总结与行动建议

Docker Compose 适合单机多服务部署,但生产稳定性取决于排查和运维细节。总结来看,排障顺序建议固定为:先看宿主机资源,再看容器状态,然后检查端口、网络、健康检查、数据卷和环境变量。这个顺序可以避免一上来就改配置,导致原始问题被掩盖。

如果你准备把项目部署到 Hostease 服务器环境,建议先按本文清单完成一次本地演练:模拟容器重启、数据库不可用、磁盘空间不足和证书续期失败四类场景。演练通过后,再选择合适的 VPS(虚拟专用服务器)主机 或 独立服务器 承载生产业务。这样上线后的问题会更少,出现故障时也能在可控范围内定位和恢复。

发表评论