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

Docker环境下FastAPI应用无法连接MySQL:'Can't connect to MySQL server on 'db''

问题

在Docker环境中部署搭配MySQL的FastAPI应用时,遇到数据库连接错误,报错信息:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'db' ([Errno -2] Name or service not known)")
(Background on this error at: https://sqlalche.me/e/20/e3q8)

对应的docker-compose.yml配置:

services:
  backend:
    build: .
    ports:
      - "8001:8000"
    networks:
      - music-app
    volumes:
      - .:/app
    env_file:
      - .env
    environment:
      - DATABASE_URL=${BACKEND_DATABASE_URL}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    depends_on:
      - db
    command: bash -c "alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"

  db:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql
    env_file:
      - .env
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
    ports:
      - "3307:3306"
    networks:
      - music-app
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "mysqladmin ping -h 127.0.0.1 -u root -p$$MYSQL_ROOT_PASSWORD",
        ]
      timeout: 20s
      retries: 10

volumes:
  mysql_data:

networks:
  music-app:
    driver: bridge

已做排查:

  • 确认.env中BACKEND_DATABASE_URL格式为mysql://[username]:[password]@[host]:[port]/[database_name]
  • 验证backend和db服务处于同一music-app网络
  • 配置了数据库健康检查

原因分析与解决方案

1. depends_on不等待数据库就绪

depends_on: [db]仅保证db服务先启动,但MySQL启动后需要时间完成初始化,后端执行alembic upgrade head时数据库可能还未就绪,导致连接失败。

解决方法:
修改backend的启动命令,加入等待数据库就绪的逻辑:

command: bash -c "until mysqladmin ping -h db -u root -p${MYSQL_ROOT_PASSWORD}; do sleep 2; done; alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"

如果后端镜像没有mysqladmin,可以用nc命令替代(需确保镜像安装了netcat,比如在Dockerfile中添加RUN apt-get update && apt-get install -y netcat-traditional):

command: bash -c "until nc -z db 3306; do sleep 2; done; alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"

2. 数据库URL配置错误

检查.env中的BACKEND_DATABASE_URL:

  • 服务间通信必须使用容器内部端口3306,而非宿主机映射的3307
  • 主机地址必须是db(docker-compose中服务的名称),不能是localhost或127.0.0.1
  • 确认用户名、密码、数据库名称正确,示例格式:mysql+pymysql://root:${MYSQL_ROOT_PASSWORD}@db:3306/${MYSQL_DATABASE}

3. MySQL 8.0认证插件兼容性问题

MySQL 8.0默认使用caching_sha2_password认证插件,pymysql可能存在兼容性问题导致连接失败。

解决方法:
在db服务的environment中添加认证插件配置:

environment:
  - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
  - MYSQL_DATABASE=${MYSQL_DATABASE}
  - MYSQL_DEFAULT_AUTH=mysql_native_password

4. 数据库容器初始化失败

如果上述方法无效,先排查数据库容器的启动日志,确认是否存在初始化错误(比如密码不符合复杂度要求):

docker-compose logs db

根据日志提示修正配置,比如调整MYSQL_ROOT_PASSWORD的复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:05:56