You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tortoise/Python无法连接Docker MySQL 需先通过phpMyAdmin登录才可连通

问题原因分析
  • 核心原因是 docker-compose 的 depends_on 仅保证容器启动顺序,不会等待MySQL内部服务初始化完成。MySQL官方镜像首次启动时,需要执行环境变量指定的数据库创建、用户创建、权限配置等初始化逻辑,这个过程通常需要3~10秒不等,此时db容器状态已经是running,但实际上数据库服务还无法正常响应外部连接。你打开phpMyAdmin再登录的操作刚好消耗了这段初始化等待时间,等你登录完成时MySQL刚好完成初始化,你的rest服务因为配置了restart: always不断重试连接,此时就可以正常连上了,你误以为是phpMyAdmin登录操作触发了什么逻辑,本质只是等待时间刚好够。
  • 次要可能是MySQL 8.0+默认使用caching_sha2_password认证插件,如果你Python环境使用的mysqlclient或者aiomysql驱动版本过低,不支持该认证方式,会导致连接失败。而phpMyAdmin的驱动对该认证插件兼容性更好,登录时会自动处理相关兼容逻辑,甚至触发MySQL侧的用户认证缓存刷新,之后低版本驱动就可以正常连接。
  • 极小概率是自定义网桥的DNS解析延迟,首次启动时rest服务解析db域名失败,phpMyAdmin访问db的操作触发了网桥的DNS缓存,之后rest服务就可以正常解析到db的IP地址。
修复方案
    1. 给db服务增加健康检测,让rest服务等db完全就绪后再启动
      修改docker-compose.yaml中对应服务的配置:
db:
  image: mysql:latest
  restart: always
  environment:
    MYSQL_DATABASE: "bbms"
    MYSQL_USER: "bbms"
    MYSQL_PASSWORD: "B37PTdaWvbUQm"
    MYSQL_ROOT_PASSWORD: "asdasdasdasd"
  ports:
    - "3306:3306"
  volumes:
    - dbdata:/var/lib/mysql
  # 新增健康检测配置
  healthcheck:
    test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-ubbms", "-pB37PTdaWvbUQm"]
    timeout: 20s
    retries: 10

rest:
  build:
    context: ./
    dockerfile: ./docker/rest/Dockerfile
  restart: always
  # 修改依赖条件,等待db服务健康
  depends_on:
    db:
      condition: service_healthy
  environment:
    MYSQL_DATABASE: "bbms"
    MYSQL_USER: "bbms"
    MYSQL_PASSWORD: "B37PTdaWvbUQm"
    MYSQL_HOST: db
    MYSQL_PORT: 3306
  volumes:
    - ./src:/app
  ports:
    - "5000:5000"
    1. 强制MySQL使用兼容度更高的旧版认证插件,解决驱动兼容问题
      在db服务中新增command配置:
db:
  image: mysql:latest
  restart: always
  # 新增这行配置
  command: --default-authentication-plugin=mysql_native_password
  environment:
    MYSQL_DATABASE: "bbms"
    MYSQL_USER: "bbms"
    MYSQL_PASSWORD: "B37PTdaWvbUQm"
    MYSQL_ROOT_PASSWORD: "asdasdasdasd"
  ports:
    - "3306:3306"
  volumes:
    - dbdata:/var/lib/mysql
    1. 升级Python的MySQL驱动版本,确保支持caching_sha2_password认证,比如将aiomysql、mysqlclient升级到最新稳定版。
    1. 也可以在rest服务的启动脚本中增加等待逻辑,确认MySQL端口可访问后再启动Python服务,示例启动脚本:
#!/bin/bash
until nc -z $MYSQL_HOST $MYSQL_PORT
do
  echo "等待MySQL服务就绪..."
  sleep 2
done
python main.py

再修改rest服务的command配置执行该启动脚本即可。

内容的提问来源于stack exchange,提问作者Scratcha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:24:03