概要
Djangoアプリケーションをdocker環境で構築後、コンテナの中に入ってマイグレートやスクリプト実行を行うと以下エラーが発生しました。本記事ではこちらの解決方法を記載します。
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',
同様にCan't connect to...
エラーになります。
django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")
原因
原因は、Djangoアプリケーションが探しに行くDBサーバの設定が不適切だったためです。
というより、MySQLサーバーをコンテナで起動させているときのお作法が抜けてしまっていました。
'HOST': 'localhost'
(または'127.0.0.1'
)を使用すると、Djangoアプリケーションは自身のコンテナ内でMySQLサーバーを探そうとしますが、実際にはdocker-compose.yaml
で定義している通り、MySQLサーバーは別のコンテナ内(mysql
)で動作しています。そのため、接続エラーが発生したのです。
解決方法
mysql
というサービス名をdocker-compose.yml
で定義していますので、このサービス名を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サーバーを正しく参照し、接続できるようになります。