Docker环境下FastAPI连接MariaDB失败问题求助
解决方案步骤
1. 修正数据库连接配置(核心)
Docker容器间通讯不能用localhost/127.0.0.1,必须使用MariaDB容器的服务名(如docker-compose中定义的mariadb)作为主机地址。示例连接串:
# 替换为你的实际用户名、密码、服务名、数据库名 DATABASE_URL = "mysql+pymysql://victor_api:your_password@mariadb:3306/your_db_name"
- 若你是从宿主机本地测试连接,才用宿主机IP+映射的端口(如
127.0.0.1:3306)。
2. 停止重复创建/删除用户
直接复用已存在的victor/victor_api用户,通过以下步骤确认并修复权限:
- 进入MariaDB容器:
docker exec -it your_mariadb_container_name mysql -uroot -p - 检查用户权限:
SHOW GRANTS FOR 'victor_api'@'%'; - 若权限不足,补充授权(替换为你的数据库名):
GRANT ALL PRIVILEGES ON your_db_name.* TO 'victor_api'@'%'; FLUSH PRIVILEGES;
- 注意用户主机段用
%,允许容器网段内的连接,不要限制为localhost。
3. 解决文件锁与Socket连接失败
- Socket连接失败:容器间通讯必须用TCP/IP(主机+端口),禁止用本地Socket路径(如
/var/run/mysqld/mysqld.sock),因为容器间默认不共享本地文件。 - 文件锁错误:
- 检查宿主机挂载的MariaDB数据目录权限:
(容器内MariaDB用户的UID/GID默认是999,需与宿主机目录权限匹配)# 替换为你的数据目录路径 chown -R 999:999 ./mariadb_data - 重启MariaDB容器:
docker restart your_mariadb_container_name
- 检查宿主机挂载的MariaDB数据目录权限:
- 连接时序问题:MariaDB容器启动需要时间,在FastAPI中添加连接重试逻辑,示例:
from tenacity import retry, stop_after_attempt, wait_exponential from sqlalchemy import create_engine @retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=2, max=10)) def get_db_engine(): return create_engine(DATABASE_URL)
4. 重构Python初始化脚本
去掉删除用户的逻辑,改用IF NOT EXISTS避免重复创建错误,示例:
from sqlalchemy import create_engine, text def init_database(): # 先用高权限用户(如root)初始化数据库与权限 root_engine = create_engine("mysql+pymysql://root:root_password@mariadb:3306/") with root_engine.connect() as conn: # 避免"数据库已存在"错误 conn.execute(text("CREATE DATABASE IF NOT EXISTS your_db_name;")) # 仅当用户无权限时执行授权(可省略,直接用之前手动配置的权限) conn.execute(text("GRANT ALL ON your_db_name.* TO 'victor_api'@'%';")) conn.execute(text("FLUSH PRIVILEGES;")) conn.commit() # 用应用用户连接目标数据库,创建表 app_engine = create_engine(DATABASE_URL) with app_engine.connect() as conn: conn.execute(text(""" CREATE TABLE IF NOT EXISTS channels ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; """)) conn.commit()
5. Docker环境额外检查
- 确认所有服务(MariaDB、FastAPI)在同一个Docker网络中(docker-compose默认会创建统一网络,无需额外配置)。
- 查看MariaDB容器日志定位启动错误:
docker logs your_mariadb_container_name,重点关注权限、初始化失败等日志信息。
内容的提问来源于stack exchange,提问作者VictordeLeusse
相关产品推荐
相关产品推荐

