docker-compose部署Flask+MySQL报无法连接mysql服务错误
问题报错
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'mysql' ([Errno -2] Name or service not known)")
故障根因
报错由多个配置错误共同导致:
- Dockerfile中错误将运行时启动应用的逻辑放在了镜像构建阶段执行,构建阶段的容器不会加入docker compose的内部网络,完全无法解析
mysql这个服务主机名 depends_on配置仅控制容器的启动顺序,不会等待MySQL服务完成初始化、开始监听端口,web应用启动时MySQL还未就绪,无法建立连接- 配置中使用的
links是docker compose早期版本的过时配置,v3+版本默认同网络下服务名可直接解析,保留该配置无实际作用反而可能引发网络解析异常
修复步骤
第一步:修正Dockerfile配置
删除构建阶段执行应用启动命令的错误行,补充端口探测需要的依赖,修正后完整Dockerfile如下:FROM python:3.9-slim-buster RUN apt-get update && apt-get install -y git python3-dev gcc gfortran libopenblas-dev liblapack-dev netcat-openbsd \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --upgrade -r requirements.txt COPY app app/ EXPOSE 5000 CMD ["python", "app/server.py", "serve"]第二步:修正docker-compose.yml配置
移除过时的links配置,给MySQL服务添加健康检查,给web服务添加启动前的端口探测逻辑,确保MySQL完全就绪后再启动应用,修正后完整配置如下:version: "3.7" services: web: build: . depends_on: mysql: condition: service_healthy ports: - 5000:5000 environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: 12345678 MYSQL_DB: flaskmysql command: > bash -c " while ! nc -z mysql 3306; do echo '等待MySQL服务就绪...' sleep 1 done echo 'MySQL已就绪,启动Web应用' python app/server.py serve " mysql: image: mysql:5.7 ports: - "32000:3306" volumes: - ./mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: 12345678 MYSQL_DATABASE: flaskmysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p12345678"] interval: 5s timeout: 5s retries: 10 volumes: mysql-data:第三步:清理旧缓存重新启动服务
执行以下命令清理旧的构建缓存、残留容器和卷,重新启动服务:docker-compose down -v docker-compose build --no-cache docker-compose up -d
连通性验证
如果启动后仍存在连接问题,可按以下步骤排查:
- 执行
docker-compose exec web bash进入web容器内部 - 执行
getent hosts mysql,如果返回MySQL容器的内部IP地址,说明服务名解析正常 - 执行
nc -zv mysql 3306,如果返回端口连通成功的提示,说明网络链路正常,此时应用可正常连接数据库
内容的提问来源于stack exchange,提问作者Juan Cruz Alric Cortabarria
相关产品推荐
相关产品推荐

