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

Docker容器中Django项目无法连接MySQL的问题求助

问题:Docker容器内Django无法连接MySQL数据库

在Windows 10系统中安装Docker v4.20.1,通过docker-compose启动了db(MySQL)、phpmyadmin、web三个容器。phpmyadmin可正常访问MySQL数据库,本地主机运行Django项目也能成功连接该数据库,但在web容器内运行Django执行migrate命令时,出现无法连接127.0.0.1:3306的错误。

错误日志

root@80c6e906cf7e:/usr/src/app# python caravan/manage.py migrate
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/connection_cext.py", line 291, in _open_connection
    self._cmysql.connect(**cnx_kwargs)
_mysql_connector.MySQLInterfaceError: Can't connect to MySQL server on '127.0.0.1:3306' (111)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 289, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.10/dist-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 270, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/django/base.py", line 399, in get_new_connection
    cnx = mysql.connector.connect(**conn_params)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/pooling.py", line 293, in connect
    return CMySQLConnection(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/connection_cext.py", line 120, in __init__
    self.connect(**kwargs)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/abstracts.py", line 1181, in connect
    self._open_connection()
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/connection_cext.py", line 296, in _open_connection
    raise get_mysql_exception(
mysql.connector.errors.DatabaseError: 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/app/caravan/manage.py", line 22, in <module>
    main()
  File "/usr/src/app/caravan/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/commands/migrate.py", line 100, in handle
    self.check(databases=[database])
  File "/usr/local/lib/python3.10/dist-packages/django/core/management/base.py", line 485, in check
    all_issues = checks.run_checks(
  File "/usr/local/lib/python3.10/dist-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/usr/local/lib/python3.10/dist-packages/django/core/checks/model_checks.py", line 36, in check_all_models
    errors.extend(model.check(**kwargs))
  File "/usr/local/lib/python3.10/dist-packages/django/db/models/base.py", line 1558, in check
    *cls._check_indexes(databases),
  File "/usr/local/lib/python3.10/dist-packages/django/db/models/base.py", line 2002, in _check_indexes
    connection.features.supports_expression_indexes
  File "/usr/local/lib/python3.10/dist-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/mysql/features.py", line 318, in supports_expression_indexes
    and self._mysql_storage_engine != "MyISAM"
  File "/usr/local/lib/python3.10/dist-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/mysql/features.py", line 162, in _mysql_storage_engine
    return self.connection.mysql_server_data["default_storage_engine"]
  File "/usr/local/lib/python3.10/dist-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/django/base.py", line 541, in mysql_server_data
    with self.temporary_connection() as cursor:
  File "/usr/lib/python3.10/contextlib.py", line 135, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 705, in temporary_connection
    with self.cursor() as cursor:
  File "/usr/local/lib/python3.10/dist-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 330, in cursor
    return self._cursor()
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 306, in _cursor
    self.ensure_connection()
  File "/usr/local/lib/python3.10/dist-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 288, in ensure_connection
    with self.wrap_database_errors:
  File "/usr/local/lib/python3.10/dist-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 289, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.10/dist-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/django/db/backends/base/base.py", line 270, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/django/base.py", line 399, in get_new_connection
    cnx = mysql.connector.connect(**conn_params)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/pooling.py", line 293, in connect
    return CMySQLConnection(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/connection_cext.py", line 120, in __init__
    self.connect(**kwargs)
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/abstracts.py", line 1181, in connect
    self._open_connection()
  File "/usr/local/lib/python3.10/dist-packages/mysql/connector/connection_cext.py", line 296, in _open_connection
    raise get_mysql_exception(
django.db.utils.DatabaseError: (2003, "2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)", 'HY000')
root@80c6e906cf7e:/usr/src/app#

docker-compose.yml配置

version: "3.9"

services:
    db:
        image: db
        container_name: db
        restart: always
        ports:
          - 3306:3306
        volumes:
          - mysql-data:/var/lib/mysql
        environment:
            MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
            MYSQL_USER: ${MYSQL_USER}
            MYSQL_PASSWORD: ${MYSQL_PASSWORD}
            
    phpmyadmin:
        image: phpmyadmin
        container_name: phpmyadmin
        restart: always
        ports:
          - 8080:80
        depends_on:
            - db
        environment:
            - PMA_PORT=3306
            
    web:
        image: web
        container_name: web
        restart: always
        ports:
            - 80:80
        volumes:
            - ./web:/usr/src/app
        depends_on:
            - db
            
volumes:
    mysql-data:

Django数据库连接配置

DATABASES = {
    'default': {
        'NAME': 'caravan',
        'ENGINE': 'mysql.connector.django',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'myuser',
        'PASSWORD': 'mypass',
        'OPTIONS': {
          'autocommit': True,
          'use_oure': True,
        },
    }
}

排查与解决方法

核心问题

Docker容器内的127.0.0.1指向容器自身,而非宿主机或db容器。Docker Compose默认会为所有服务创建一个共享网络,容器之间可以通过服务名(即docker-compose.yml中定义的服务名称,这里是db)互相访问。

修复步骤

  1. 修改Django数据库配置的HOST
    将Django配置中的HOST: '127.0.0.1'替换为HOST: 'db':
DATABASES = {
    'default': {
        'NAME': 'caravan',
        'ENGINE': 'mysql.connector.django',
        'HOST': 'db',  # 替换为db服务名
        'PORT': 3306,
        'USER': 'myuser',
        'PASSWORD': 'mypass',
        'OPTIONS': {
          'autocommit': True,
          'use_unicode': True,  # 注意:原配置中的use_oure应为拼写错误,修正为use_unicode
        },
    }
}
  1. 额外检查点
  • 确认db容器服务就绪:depends_on仅保证容器启动顺序,不保证MySQL服务完全就绪。可查看db容器日志,确认出现ready for connections信息;也可在web容器中添加等待脚本,确保MySQL启动后再运行Django命令。
  • 检查MySQL用户权限:默认创建的MYSQL_USER可能仅允许从localhost访问,需在db容器中执行以下命令,允许用户从任意IP(容器网络内)访问:
    docker exec -it db mysql -uroot -p${MYSQL_ROOT_PASSWORD}
    # 进入MySQL后执行
    GRANT ALL ON caravan.* TO 'myuser'@'%' IDENTIFIED BY 'mypass';
    FLUSH PRIVILEGES;
    
  • 确认数据库存在:若db容器为首次启动,需手动创建caravan数据库,或在docker-compose.yml的db服务环境变量中添加MYSQL_DATABASE: caravan,让容器启动时自动创建数据库:
    db:
      # ...其他配置
      environment:
          MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
          MYSQL_USER: ${MYSQL_USER}
          MYSQL_PASSWORD: ${MYSQL_PASSWORD}
          MYSQL_DATABASE: caravan  # 添加此行
    
  • 核对环境变量一致性:确保docker-compose.yml中MYSQL_USER、MYSQL_PASSWORD与Django配置中的对应值完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:22:05