Docker配置Ubuntu正常Mac M1报错:Django无法连接MySQL
问题现象
执行docker-compose up时,Django应用抛出数据库连接错误:
Error: File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 166, in init
web_1 | super(Connection, self).init(*args, **kwargs2)
web_1 | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
相同配置在Ubuntu环境可正常运行,已尝试调整服务启动顺序、单独启动db服务(可正常运行)、修改卷路径、清理所有镜像/容器/卷后重建,问题仍未解决。
相关配置文件
docker-compose.yml
version: '3.2' services: web: restart: always expose: - "5000" build: context: . dockerfile: Dockerfile command: python manage.py runserver 0.0.0.0:5000 ports: - "9000:5000" environment: - MYSQL_HOST=db - MYSQL_USER=me - MYSQL_PASSWORD=me - MYSQL_DB=my_db depends_on: - db volumes: - ".:/code/google" db: image: mysql:5.7 restart: always expose: - "9306" ports: - "9306:3306" environment: - MYSQL_DATABASE=my_db - MYSQL_USER=me - MYSQL_PASSWORD=me - MYSQL_ROOT_PASSWORD=me volumes: - "./db_data:/opt/homebrew/var/mysql" - "./mysql-init:/docker-entrypoint-initdb.d"
Django数据库配置
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "my_db", "USER": "me", "PASSWORD": "me", "HOST": "db", "PORT": "3306", } }
解决方案
1. 替换为ARM64兼容的MySQL镜像
MySQL 5.7官方镜像未适配ARM64架构(Mac M1属于ARM64),通过Rosetta模拟运行时易出现网络连接不稳定问题。建议改用官方提供的ARM兼容版本:
将db服务的image: mysql:5.7替换为image: mysql/mysql-server:5.7,或改用对ARM支持更好的MariaDB镜像mariadb:10.5。
2. 修复db服务的expose端口错误
db服务中expose: - "9306"配置错误,MySQL默认端口为3306,应修改为:
db: # 其余配置不变 expose: - "3306"
错误的暴露端口可能导致容器内部网络识别异常,在M1的Docker网络环境下更易触发问题。
3. 添加MySQL就绪等待逻辑
depends_on仅保证db服务先启动,但不确保MySQL服务完全就绪。修改web服务的启动命令,添加等待逻辑:
web: # 其余配置不变 command: > sh -c " until nc -z db 3306; do echo 'Waiting for MySQL...'; sleep 2; done; python manage.py runserver 0.0.0.0:5000 "
需确保web镜像中安装了netcat:Debian/Ubuntu镜像可在Dockerfile中添加RUN apt-get update && apt-get install -y netcat;Alpine镜像则用RUN apk add netcat-openbsd。
4. 调整数据库卷挂载路径
Mac M1上挂载路径./db_data:/opt/homebrew/var/mysql不符合容器内MySQL的默认数据目录,容器内MySQL默认数据目录为/var/lib/mysql,修改为:
db: # 其余配置不变 volumes: - "./db_data:/var/lib/mysql" - "./mysql-init:/docker-entrypoint-initdb.d"
问题原因说明
Docker的跨环境一致性是基于同架构的,Mac M1为ARM64架构,Ubuntu多为x86_64架构。部分老版本官方镜像(如mysql:5.7)无ARM64版本,只能通过Rosetta 2模拟运行,模拟过程中易出现网络、文件系统等兼容性问题,导致容器间连接不稳定。
内容的提问来源于stack exchange,提问作者Wahdat Jan

