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

Docker Compose部署Flask应用时出现MySQLdb OperationalError(2002)连接问题求助

Hey there, let's fix this MySQL connection issue you're running into!

The Root Cause

When you set MYSQL_HOST = 'localhost' in your Flask config, your Flask container is trying to connect to a MySQL server inside its own container—not the separate MySQL container you created with Docker Compose. That's why you get the socket error: there's no MySQL running in the Flask container.

Your docker exec command works because you're directly accessing the MySQL container itself, where the socket file exists.

Step-by-Step Fixes

1. Update Flask's MySQL Host Configuration

Change the MYSQL_HOST value to match the service name of your MySQL container in docker-compose.yml (which is db). Docker Compose automatically creates DNS entries for service names, so your Flask container can resolve db to the MySQL container's IP.

Modified Flask config:

from flask_mysqldb import MySQL,MySQLdb
app = Flask(__name__)
app.config['MYSQL_HOST'] = 'db'  # Replace 'localhost' with 'db'
app.config['MYSQL_USER'] = '*****'
app.config['MYSQL_PASSWORD'] = '****'
app.config['MYSQL_DB'] = 'emp'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
mysql = MySQL(app)

2. Add Dependencies & Health Checks to Docker Compose

Make sure your Flask service waits for MySQL to be fully ready before starting. A basic depends_on ensures the MySQL container is up, but adding a health check guarantees the MySQL service is actually accepting connections.

Modified docker-compose.yml:

version: '3.1'
services:
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./db:/docker-entrypoint-initdb.d/:ro
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ****
      MYSQL_DATABASE: emp
      MYSQL_PASSWORD: ****
    ports:
      - "33061:3306"
    # Add health check to verify MySQL is ready
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
      interval: 5s
      timeout: 5s
      retries: 5
  emp:
    build: .
    restart: always
    ports:
      - 5005:5000
    # Wait for MySQL to be healthy before starting
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - my-db:/path/to/your/app/data  # Fix volume syntax (add target path)
volumes:
  my-db:  # Define the volume at the top level

3. Fix the Dockerfile's CMD Conflict

Your current Dockerfile has two CMD commands—only the last one (python3 app.py) will run, so your cron job won't start. To run both cron and Flask, use a startup script:

  1. Create a start.sh file in your project root:
#!/bin/bash
# Start cron in the background
cron -f &
# Start Flask in the foreground
python3 app.py
  1. Update your Dockerfile to use this script:
FROM python:3.6-buster
LABEL image for a very management application
# We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
# Update apt before installing packages
RUN apt-get update && apt-get install -y default-libmysqlclient-dev cron
RUN pip3 install -r requirements.txt
RUN touch /var/log/cron.log
COPY crontab /etc/cron.d/cjob
RUN chmod 0644 /etc/cron.d/cjob
# Load the cron job
RUN crontab /etc/cron.d/cjob
ENV PYTHONUNBUFFERED 1
# Copy and make startup script executable
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh
EXPOSE 5000
COPY . .
# Use the startup script to run both services
CMD [ "/app/start.sh" ]

Final Notes

  • You don't need to use the host port 33061 for container-to-container communication—your Flask app will connect to the MySQL container's internal port 3306 automatically.
  • The health check ensures Flask doesn't try to connect until MySQL is fully initialized (which can take a few seconds even after the container starts).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:54:04