Docker化FastAPI应用连接MySQL容器失败问题排查求助
问题:FastAPI容器无法连接MySQL容器(Docker化部署)
我正在对一个使用MySQL和Selenium的FastAPI应用进行Docker化部署,但遇到FastAPI容器与MySQL容器连接失败的问题:
- 本地用MySQL Workbench以localhost为主机能成功连接MySQL容器
- FastAPI容器运行时抛出错误:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'mysql' ([Errno -3] Temporary failure in name resolution)
当前docker-compose.yml配置
version: '3' services: chrome: build: . image: selenium/node-chrome:3.141.59-20210929 ports: - "4444:4444" - "5900:5900" volumes: - "/dev/shm:/dev/shm" networks: - selenium mysql: image: mysql:8.0 command: --default-authentication-plugin=mysql_native_password restart: always environment: - MYSQL_ROOT_PASSWORD=admin - MYSQL_DATABASE=autojob - MYSQL_USER=user - MYSQL_PASSWORD=4444 healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] timeout: 20s retries: 10 volumes: - ./init:/docker-entrypoint-initdb.d - autojob:/var/lib/mysql ports: - "3307:3306" expose: - "3307" app: build: . restart: on-failure container_name: "autojobserve_container" command: uvicorn autojobserve.app:app --host 0.0.0.0 --port 8000 --reload ports: - 8000:8000 volumes: - "./:/app" networks: - selenium depends_on: mysql: condition: service_healthy volumes: autojob: {} networks: selenium:
FastAPI数据库连接代码
engine = create_engine("mysql+pymysql://user:4444@mysql:3307/autojob")
MySQL容器就绪日志
2022-11-08T11:49:26.334069Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock 2022-11-08T11:49:26.334869Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL. 2022-11-08 11:49:14+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started. 2022-11-08 11:49:14+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' 2022-11-08 11:49:14+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started. '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
问题原因及修复方案
1. 网络隔离导致服务名解析失败
mysql服务未加入selenium网络,而FastAPI容器(app服务)在该网络内,同一网络外的服务无法通过服务名互相访问。
修复:给mysql服务添加网络配置:
mysql: # ... 原有配置 networks: - selenium
2. 容器间通信端口错误
容器间通信应使用MySQL容器内部端口3306,而非宿主机映射的3307端口。端口映射3307:3306仅用于宿主机访问容器,容器间直接用内部端口即可。
修复:修改FastAPI连接字符串的端口:
engine = create_engine("mysql+pymysql://user:4444@mysql:3306/autojob")
3. 错误的expose配置
expose声明的是容器内部要暴露的端口,当前配置的3307是宿主机端口,不符合逻辑。MySQL镜像默认已暴露3306端口,可直接删除该配置。
修复:删除mysql服务中的expose: - "3307",或改为expose: - "3306"。
4. 优化healthcheck检测逻辑
当前healthcheck用localhost仅检测容器内本地连接,改为0.0.0.0可确保服务对外(容器间)可访问,更准确反映服务就绪状态。
修复:更新healthcheck配置:
healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "0.0.0.0"] timeout: 20s retries: 10
内容的提问来源于stack exchange,提问作者OLUYELE SUNDAY ANTHONY
相关产品推荐
相关产品推荐

