如何从Flask应用连接EC2上Docker化的MySQL数据库
嘿,我来帮你拆解这个问题!你遇到的超时问题基本是网络连通性或者MySQL配置的锅,咱们一步步来解决:
1. 先搞定EC2和Docker的端口开放
这是最基础的前提,先确保外部能摸到MySQL的端口:
- 检查EC2安全组:必须添加一条入站规则,允许3306端口(MySQL默认端口)访问。测试阶段可以临时允许
0.0.0.0/0(所有IP),生产环境一定要限制成Flask应用所在的IP或者VPC网段。 - 检查MySQL容器的端口映射:启动容器时必须加
-p 3306:3306参数,把容器内的3306端口映射到EC2主机的3306端口。如果没做这个映射,外部根本访问不到容器里的MySQL。
2. 让MySQL接受外部连接
默认MySQL容器只允许容器内部访问,得改配置:
- 先进入容器(就是你手动操作的方式),登录MySQL:
mysql -u root -p - 授权外部用户访问:比如给root用户授权从任意IP访问(测试用,生产建议创建专用权限的用户):
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的数据库密码'; FLUSH PRIVILEGES; - 修改MySQL绑定地址:找到容器内的MySQL配置文件(通常在
/etc/mysql/mysql.conf.d/mysqld.cnf),把bind-address改成0.0.0.0,这样MySQL会监听所有网卡的请求。改完后重启容器:docker restart 你的mysql容器名
3. 配置Flask的连接字符串
不管用SQLAlchemy还是原生MySQL驱动,连接地址要写对:
- 用SQLAlchemy的话,连接URL格式是:
mysql+pymysql://用户名:密码@EC2公网IP:3306/你的数据库名?charset=utf8mb4 - 测试小技巧:先在Flask所在的环境(本地或容器里)用
telnet EC2_IP 3306或nc -zv EC2_IP 3306测试端口是否能通。如果不通,回到第一步排查网络。
4. Flask应用Dockerfile的注意事项(如果Flask也容器化了)
如果你的Flask也打包成Docker镜像,Dockerfile里要确保安装了数据库驱动:
- 示例Dockerfile:
FROM python:3.9-slim WORKDIR /app # 先复制依赖文件,利用Docker缓存 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 启动应用 CMD ["python", "app.py"] - 对应的
requirements.txt要包含必要依赖:flask flask-sqlalchemy pymysql - 别硬编码密码!用环境变量传递更安全:启动Flask容器时加参数
-e DB_USER=root -e DB_PASSWORD=你的密码 -e DB_HOST=EC2_IP -e DB_NAME=你的数据库名,然后在Flask代码里读取:import os from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = ( f"mysql+pymysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}" f"@{os.getenv('DB_HOST')}:3306/{os.getenv('DB_NAME')}" ) db = SQLAlchemy(app)
5. 更安全的替代方案:SSH隧道
如果不想把3306端口开放到公网,可以用SSH隧道转发端口:
- 执行这条命令(在Flask应用所在的机器上):
ssh -i "你的pem文件.pem" -L 3306:localhost:3306 ec2-user@EC2公网IP - 这样Flask的连接URL里的
host就写localhost,相当于通过SSH隧道访问EC2上的MySQL,不用开放3306端口,安全性更高。
内容的提问来源于stack exchange,提问作者stigward
相关产品推荐
相关产品推荐

