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

使用docker-compose部署Flask+MySQL时遭遇数据库连接超时错误

Docker-Compose部署Flask+MySQL连接失败问题

我尝试用docker-compose部署搭配MySQL数据库的Flask应用,试过多种方法让Flask启动前等待数据库就绪,但还是遇到连接超时错误。

我的docker-compose配置

version: "3.7"

services:
  waitfordb:
        image: dadarek/wait-for-dependencies
        depends_on:
            mysql:
              condition: service_completed_successfully
        environment:
            MYSQL_PORT: "5432"
        networks:
            - backend
        command: mysql:5432
  mysql:
    image: mysql:5.7
    ports:
      - "5432:5432"
    networks:
      - backend
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "12345678"
      MYSQL_DATABASE: flaskmysql
  web:
    build: .
    depends_on:
      mysql:
        condition: service_completed_successfully
      waitfordb:
        condition: service_completed_successfully
    ports:
      - 5000:5000
    
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: "12345678"
      MYSQL_DB: flaskmysql
  
networks:
    backend:
        driver: bridge

Flask应用数据库配置

app.config['SQLALCHEMY_DATABASE_URI']= f"mysql+pymysql://{config.MYSQL_USER}:{config.MYSQL_PASS}@5432/flaskmysql"

执行命令

docker-compose --env-file .env up 

错误信息

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '5432' (timed out)")

问题修复方案

1. 修正MySQL端口配置

MySQL默认监听端口是3306,你把容器端口映射成5432(PostgreSQL默认端口),但MySQL容器内部并没有在5432端口启动服务,导致端口检查和连接全错。修改mysql服务的端口映射:

ports:
  - "3306:3306"  # 恢复默认端口映射,外部通过3306访问容器内的MySQL

2. 修正waitfordb的等待命令

waitfordb需要等待MySQL容器的3306端口,而非5432:

waitfordb:
  # 其他配置不变
  command: mysql:3306

3. 修正Flask的数据库连接URI

连接地址应该用docker-compose服务名mysql作为主机,而非直接写端口号。正确格式为mysql+pymysql://用户名:密码@服务名:端口/数据库名:

# 用环境变量里的MYSQL_HOST对应服务名mysql,默认3306端口可省略
app.config['SQLALCHEMY_DATABASE_URI']= f"mysql+pymysql://{config.MYSQL_USER}:{config.MYSQL_PASSWORD}@{config.MYSQL_HOST}/{config.MYSQL_DB}"

注意:如果你的环境变量密码字段是MYSQL_PASS,替换成config.MYSQL_PASS即可,确保和docker-compose里的变量名一致。

4. 可选:增强数据库就绪检查

dadarek/wait-for-dependencies仅检查端口是否开放,但MySQL可能端口开放后仍未完成初始化(如创建数据库、加载权限)。可在Flask应用中添加连接重试逻辑:

from sqlalchemy import create_engine
from sqlalchemy.exc import OperationalError
import time

def init_db():
    max_retries = 10
    retry_count = 0
    while retry_count < max_retries:
        try:
            engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
            with engine.connect():
                print("数据库连接成功")
                break
        except OperationalError:
            retry_count += 1
            print(f"数据库未就绪,第{retry_count}次重试...")
            time.sleep(2)
    else:
        raise Exception("数据库连接超时")

# 应用启动前调用初始化
init_db()

内容的提问来源于stack exchange,提问作者Juan Cruz Alric Cortabarria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:40:22