报数据库连不上?Docker Compose 启动顺序假象:depends_on 不是万能的!

📖 背景

服务器重启后。大屏(Flask)总是报错 Connection refused。看日志:Can't connect to MySQL server on 'db'。

执行 docker compose up -d 也是一样。明明写了 depends_on: - db。db 容器明明在运行。

🔍 原因

小学生版解释:

depends_on 就像比赛时的"排队"。它只保证跑道上 db 先跑,dashboard 后跑。

但 db(MariaDB)是个大胖子。跑到起跑线后,还要花 5 秒系鞋带(初始化数据库、监听端口)。

dashboard 跑得飞快,起跑后直接敲门,发现 db 还没弄好,立刻报错退出。

🛠 解决

不能用 depends_on。要用 healthcheck(健康检查)+ condition: service_healthy。

修改 docker-compose.yml:

复制代码
services:
  db:
    image: mariadb
    healthcheck:
      # 只要 docker 内执行该命令成功,才算健康
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 5s
      timeout: 3s
      retries: 5

  dashboard:
    image: flask-app
    depends_on:
      db:
        condition: service_healthy # 关键:等 db 健康了再启动

改完执行 docker compose up -d 重建。

✅ 验证效果

用 docker ps 观察。

注意看 STATUS 这一列:db 变成 Up (healthy) 之前,dashboard 会显示 Created 或 Waiting。一旦 db 变绿(healthy),dashboard 才会启动。

大屏不报错了。

💣 三个坑

老版本 Compose 不认:如果你的 docker compose 版本很老(V2 以下),可能不支持 condition: service_healthy,必须升级 compose 插件。

健康检查命令写错:test 里的命令如果没有指定 CMD 或者写错,容器永远 unhealthy,导致后端永远起不来。

不写超时退出:如果不配合 restart: always(重启策略),一旦后端起太快报错退出,它就不会自己重试了。

相关推荐
Ashe8135 分钟前
MySQL 慢日志先别急着加索引:三个指标能拦掉大半误判
数据库
ClouGence22 分钟前
最基础的异构数据库 DDL 同步,我们踩过哪些坑?
数据库·mysql·postgresql
羑悻的小杀马特2 小时前
Redis持久化三剑客:RDB二进制快照、AOF文本日志、混合模式如何守护你的数据安全?
数据库·redis·缓存·aof·持久化存储·rdb
小呆爱发呆2 小时前
第三章 MySQL 库表操作
数据库·mysql·adb
时间的拾荒人2 小时前
Redis 进阶实战:渐进式遍历、持久化机制与事务详解
数据库·redis·缓存
wz97542 小时前
Docker 从 systemd 托管容器、overlay2 存储驱动到 Compose 多容器实战
spring cloud·docker·eureka
普通人63 小时前
MySQL_FIND_IN_SET函数详解
android·数据库·mysql
真上帝的左手3 小时前
4. 关系型数据库-MySQL-Canal 进阶
数据库·mysql·canal
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》DataManager数据管理模块:SQLite持久化存储
开发语言·数据库·c++·sqlite