You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker+Flask+MySQL启动连接失败,重启容器正常的原因咨询

问题原因与解决方案

原因分析

没错,就是你猜测的那样:Web应用启动时MySQL服务尚未完全就绪。

docker-compose里的depends_on只会保证mysql容器先于dockerflaskexample容器启动,但不会等待MySQL服务完成初始化(比如创建数据库、用户,以及监听3306端口)。当Flask应用尝试连接时,MySQL容器虽然已经启动,但服务还没准备好接受连接,所以抛出Connection refused错误。而重启容器时,MySQL服务已经完全初始化完成,所以能正常连接。

解决方案

方案1:在Flask应用中添加连接重试逻辑

修改__init__.py中的数据库连接代码,增加循环重试机制,直到连接成功或达到最大重试次数:

import pymysql
import time

# Establishing a connection to the MySQL database with retry
connection = None
max_retries = 10
retry_delay = 2  # seconds

for _ in range(max_retries):
    try:
        connection = pymysql.connect(
            host='mysql',
            database='webapp-db',
            user='webapp-db-user',
            password='webapp-db-password',
            port=3306,
            charset='utf8mb4',
        )
        print("Successfully connected to MySQL!")
        break
    except pymysql.err.OperationalError as e:
        print(f"Connection failed, retrying in {retry_delay}s... Error: {e}")
        time.sleep(retry_delay)

if not connection:
    raise Exception("Failed to connect to MySQL after maximum retries")

方案2:使用启动脚本等待MySQL就绪

在项目根目录创建一个启动脚本start_app.sh:

#!/bin/bash

# Wait for MySQL to be ready
while ! nc -z mysql 3306; do
  echo "Waiting for MySQL..."
  sleep 2
done

# Start Flask application
python app.py  # 替换成你的Flask启动命令

修改Dockerfile,添加netcat(用于端口检测)并设置启动命令为该脚本:

# 假设你的基础镜像为python系列
RUN apt-get update && apt-get install -y netcat-traditional
COPY start_app.sh /app/start_app.sh
RUN chmod +x /app/start_app.sh
CMD ["/app/start_app.sh"]

方案3:使用Docker健康检查(推荐,Docker 20.10+支持)

修改docker-compose.yaml,给mysql服务添加健康检查,并让dockerflaskexample服务等待MySQL进入健康状态:

services:
  dockerflaskexample:
    image: dockerflaskexample
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 5002:5002
    volumes:
      - app_code:/app
    depends_on:
      mysql:
        condition: service_healthy  # 等待MySQL服务健康就绪
    container_name: dockerflaskexample
  mysql:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: webapp-db-root-password
      MYSQL_DATABASE: webapp-db
      MYSQL_USER: webapp-db-user
      MYSQL_PASSWORD: webapp-db-password
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "webapp-db-user", "-pwebapp-db-password"]
      interval: 5s
      timeout: 5s
      retries: 10
volumes:
  mysql_data:
  app_code:

这个配置会让Docker持续检查MySQL服务是否能正常响应ping命令,只有当MySQL处于健康状态时,才会启动Flask容器。

内容的提问来源于stack exchange,提问作者TaihouKai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:16:33