docker-compose部署Flask时pymysql连接MySQL报127.0.0.1连接拒绝错误
问题根因
两个核心配置错误导致连接被拒绝:
- 容器网络隔离机制:Docker Compose会为同栈服务创建独立的共享网桥,容器内的
127.0.0.1仅指向当前容器自身的回环地址,不会指向宿主机或其他同网络容器。你在Flask容器内连接127.0.0.1:33061,实际是在请求Flask容器自己的33061端口,该端口没有运行任何MySQL服务,自然返回连接拒绝。 - 端口映射适用范围错误:你配置的
"0.0.0.0:33061:3306"是将MySQL容器的3306端口映射到宿主机的33061端口,这个规则仅对宿主机生效(所以你用DBeaver在宿主机上能正常连接),同Docker网络内的容器通信不需要走宿主机端口映射,直接访问容器内部的服务端口即可。
另外你贴的docker-compose.yml存在YAML格式错误:MYSQL_PASSWORD环境变量缩进错误、volumes字段缩进层级不对,直接启动会报配置解析失败。
修复方案
按以下步骤调整配置即可解决问题:
- 修正Flask代码中的数据库连接参数
将数据库host改为Compose中定义的MySQL服务名mysql_db(Docker内置DNS会自动将服务名解析为对应容器的内网IP),端口改为MySQL容器内部默认服务端口3306,修改后的连接代码如下:
from flask import Flask import pymysql app = Flask(__name__) @app.route('/') def index(): return '<h1>Login</h1>' if __name__ == '__main__': connection = pymysql.connect(host='mysql_db', user='root', password='password', port=3306, cursorclass=pymysql.cursors.DictCursor) cur = connection.cursor() cur.execute(''' SELECT * FROM data_warehouse.ofactory_results''') order_no = cur.fetchone() print(order_no) print('STARTTTTTTT!') app.run(debug=True, host='0.0.0.0')
*注意:Flask启动建议加上host='0.0.0.0'参数,否则容器外无法访问5000端口。
- 修正docker-compose.yml格式与启动依赖
调整缩进错误,添加depends_on配置保证MySQL容器优先启动,修正后的完整配置如下:
version: "3.9" services: app: build: context: . ports: - 5000:5000 depends_on: - mysql_db mysql_db: container_name: mysql_db image: mariadb:latest restart: always ports: - "0.0.0.0:33061:3306" environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=data_warehouse - MYSQL_USER=debezium - MYSQL_PASSWORD=debezium volumes: - ./mysql:/var/lib/mysql - ./mysql/my.cnf:/etc/mysql/my.cnf
配置中保留的33061端口映射仅用于宿主机访问数据库,容器间通信用不到该配置,可根据需求决定是否保留。
- 重新构建启动服务
在项目目录下执行以下命令重建容器栈:
docker-compose up --build -d
注意事项
depends_on仅能控制容器的启动顺序,无法保证MySQL服务完全初始化就绪。如果出现偶发启动连接失败,可以在Flask启动逻辑中添加数据库连接重试机制,或使用wait-for-it类脚本检测MySQL端口连通性后再启动应用服务。
内容的提问来源于stack exchange,提问作者Bill Tran
相关产品推荐
相关产品推荐

