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

Mac M1环境下Docker化Flask应用无法连接MySQL的解决方法

解决Flask应用无法连接Docker中MySQL服务的问题

问题背景

在Mac M1环境下,通过docker-compose部署Flask应用(Python 3.8 + Flask 2.2.2)和arm64v8/mysql 8服务时,Flask应用抛出连接错误:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)")

已尝试修改my.cnf开放远程连接,但问题未解决。


解决方案

1. 修正数据库连接地址

容器内的Flask应用不能用127.0.0.1连接MySQL——每个容器是独立的网络环境,在docker-compose的自定义网络app_network中,需要用MySQL服务名db作为主机地址。

修改Flask的数据库连接字符串示例:

import os
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = (
    f"mysql+pymysql://{os.getenv('MYSQL_USER')}:{os.getenv('MYSQL_PASSWORD')}@"
    f"{os.getenv('MYSQL_HOST', 'db')}:{os.getenv('MYSQL_PORT', 3306)}/{os.getenv('MYSQL_DATABASE')}"
)
db = SQLAlchemy(app)

这里的db对应docker-compose中MySQL服务的名称,容器会通过自定义网络自动解析该名称到MySQL容器的IP。

2. 确保MySQL服务完全就绪

depends_on仅保证MySQL容器先启动,但不保证数据库服务已经初始化完成。需要在Flask应用中添加连接重试逻辑:

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

def wait_for_db():
    retries = 10
    db_uri = os.getenv('SQLALCHEMY_DATABASE_URI')
    while retries > 0:
        try:
            engine = create_engine(db_uri)
            with engine.connect():
                print("数据库连接成功")
                return
        except OperationalError as e:
            retries -= 1
            print(f"数据库未就绪,重试剩余次数:{retries},错误信息:{e}")
            time.sleep(2)
    raise Exception("数据库初始化超时,无法建立连接")

# 在Flask应用启动前调用
wait_for_db()

3. 检查MySQL绑定配置

确保my.cnf中设置允许所有IP访问:

[mysqld]
bind-address = 0.0.0.0
port = 3306

注意:官方MySQL镜像默认会处理权限配置,无需手动修改/var/lib/mysql的所有权,可删除Dockerfile中的RUN chown -R mysql:root /var/lib/mysql/指令。

4. 配置数据库用户远程访问权限

在./docker/db目录下添加初始化SQL脚本(如init.sql),赋予用户从任意主机连接的权限:

GRANT ALL PRIVILEGES ON `${MYSQL_DATABASE}`.* TO `${MYSQL_USER}`@`%` IDENTIFIED BY `${MYSQL_PASSWORD}`;
FLUSH PRIVILEGES;

该脚本会在MySQL容器首次启动时自动执行,解决用户仅能本地连接的问题。

5. 简化MySQL Dockerfile

官方arm64v8/mysql镜像已支持通过环境变量初始化数据库,无需在Dockerfile中重复定义ARG和ENV,简化后的Dockerfile:

FROM arm64v8/mysql
COPY my.cnf /etc/mysql/my.cnf

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:13:19