【Docker x MySQL】出现“无法连接到本地MySQL服务器…”的错误原因和解决方法

简述

在使用Docker环境构建Django应用程序后,进入容器进行迁移和脚本执行时出现了以下错误。本文将记录解决此问题的方法。

django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)")

设定文件的前提

docker-compose.yml和settings.py的内容如下所示。

docker-compose.yml的内容如下。

version: '3'
services:
  mysite:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    volumes:
      - '../web:/mysite'
    ports:
      - "8080:8000"
    container_name: mysite_django
    tty: true
    working_dir: '/mysite'

  mysql:
    image: mysql:latest
    container_name: mysite_mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      MYSQL_DATABASE: mysite_db
    ports:
      - "3306:3306"
    volumes:
      - mysite-data-volume:/var/lib/mysql

volumes:
    mysite-data-volume:

settings.py中的DATABASES如下所示。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite_db',
        'USER': 'docker',
        'PASSWORD': 'docker',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'init_command':
                'SET character_set_connection=utf8,collation_connection=utf8_unicode_ci'
        }
    },
}

順便提一下,如果将’127.0.0.1’进行更改并尝试执行,

        'HOST': '127.0.0.1',

同样会发生“无法连接到…”错误。

django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")

造成这种情况的因素是什么?

原因是因为Django应用程序在寻找数据库服务器的设置不正确。
更确切地说,当启动MySQL服务器时,容器的惯例被忽略了。

如果使用’HOST’: ‘localhost’(或’127.0.0.1’),Django应用程序将尝试在自己的容器中查找MySQL服务器,但实际上,MySQL服务器是在另一个容器中(mysql)运行,正如在docker-compose.yaml中定义的一样。因此,发生了连接错误。

解决办法

在docker-compose.yml中定义了一个名为mysql的服务,所以Django应用程序可以将此服务名称指定为MySQL服务器的主机名,以便正确连接到MySQL。具体如下:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite_db',
        'USER': 'docker',
        'PASSWORD': 'docker',
        'HOST': 'mysql',  # Dockerコンテナ内でのMySQLサービス名を指定
        'PORT': '3306',
        'OPTIONS': {
            'init_command':
                'SET character_set_connection=utf8,collation_connection=utf8_unicode_ci'
        }
    },
}

通过这样做,Django应用程序将能够正确引用并连接到在容器内以服务名为mysql定义的MySQL服务器。

广告
将在 10 秒后关闭
bannerAds