Docker中Flask容器连接MySQL容器反复出现1045访问拒绝错误求助
看起来你已经做了不少排查工作了——手动从Flask容器连MySQL能成功,但执行迁移时就报1045错误,确实挺让人困惑的。咱们一步步来拆解可能的问题,试试下面的解决方案:
一、先确认MySQL用户权限的正确性
虽然你说已经给alex用户授权了%、特定IP和localhost,但MySQL的用户匹配是有优先级的,而且8.0版本的授权逻辑有变化,可能你的权限设置没真正生效:
- 先进入MySQL容器,查看当前所有
alex用户的主机绑定:
docker-compose exec db mysql -u root -proot_pass
然后执行SQL:
SELECT user, host FROM mysql.user WHERE user='alex';
如果输出里有多个alex(比如alex@localhost、alex@172.18.0.3、alex@%),MySQL会优先匹配最具体的主机,可能刚好匹配到了权限不足的那个。
- 清理多余的用户,重新创建并授权:
-- 删除所有alex相关用户 DROP USER IF EXISTS 'alex'@'localhost'; DROP USER IF EXISTS 'alex'@'172.18.0.3'; DROP USER IF EXISTS 'alex'@'%'; -- 创建允许所有主机访问的alex用户 CREATE USER 'alex'@'%' IDENTIFIED BY 'root_password'; -- 授予main数据库的所有权限 GRANT ALL PRIVILEGES ON main.* TO 'alex'@'%'; -- 刷新权限使设置生效 FLUSH PRIVILEGES;
执行完后再用SELECT user, host FROM mysql.user WHERE user='alex';确认只有alex@%一条记录。
二、解决MySQL服务未就绪的问题
Docker Compose的depends_on只是保证容器启动顺序,不会等待MySQL服务完全初始化就绪。Flask容器可能在MySQL还没准备好接受连接时就启动执行迁移,导致临时的连接失败,看起来像是权限问题。
修改你的docker-compose.yml,给MySQL添加健康检查,让Flask等MySQL就绪后再启动:
services: backend : environment: - FLASK_APP=main.py build: context: . dockerfile: Dockerfile ports: - 8001:5000 volumes: - .:/app depends_on: db: condition: service_healthy # 等待MySQL健康检查通过 db: image: mysql:8.0.39 restart: always environment: MYSQL_DATABASE: main MYSQL_USER: alex MYSQL_PASSWORD: root_password MYSQL_ROOT_PASSWORD: root_pass volumes: - .dbdata:/var/lib/mysql ports: - 33069:3306 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s # 每5秒检查一次 timeout: 5s # 超时时间5秒 retries: 5 # 重试5次后标记为不健康
三、确认迁移命令的执行环境
如果你是在宿主机上执行迁移命令(比如直接跑flask db migrate),那你的连接字符串应该指向宿主机映射的端口:
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://alex:root_password@localhost:33069/main'
但如果你是在Flask容器内执行迁移(比如docker-compose exec backend flask db migrate),那原来的db:3306是对的——因为容器间通过Docker网络可以直接用服务名访问。
最后验证
修改完配置后,先删掉MySQL的持久化数据卷(避免旧的权限残留),然后重新启动容器:
docker-compose down -v docker-compose up --build
再尝试执行迁移命令,看看是否还会报错。
备注:内容来源于stack exchange,提问作者Ahmad

