Setup Django with Mysql using docker

I encountered some errors during mysql setup with django using docker. So, this is why I created a quick reference for myself.
Put this into your settings.py
file.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MYSQL_DATABASE', 'mysql-db'),
'USER': os.environ.get('MYSQL_USER', 'mysql-user'),
'PASSWORD': os.environ.get('MYSQL_PASSWORD', 'mysql-password'),
'HOST': os.environ.get('MYSQL_DATABASE_HOST', 'db'),
'PORT': os.environ.get('MYSQL_DATABASE_PORT', 3306),
}
}
Install mysql client package.
pip install mysqlclient
Or using poetry
poetry add mysqlclient
Create .env
file with corresponding content:
MYSQL_DATABASE=mysql-db
MYSQL_USER=mysql-user
MYSQL_PASSWORD=mysql-password
MYSQL_ROOT_PASSWORD=mysql-root-password
MYSQL_DATABASE_HOST=db
MYSQL_DATABASE_PORT=3306
Inside your project directory create docker/mysql
directory and create Dockerfile
and init_db.sh
files.

Dockerfile
FROM mysql/mysql-server:8.0
COPY ./docker/db/init_db.sh /docker-entrypoint-initdb.d/
RUN chmod +x /docker-entrypoint-initdb.d/init_db.sh
Workaround to get rid of errors when you are trying to run django tests.
init_db.sh
#!/bin/bash
mysql -u root --password="$MYSQL_ROOT_PASSWORD" << EOF
USE ${MYSQL_DATABASE};
GRANT ALL PRIVILEGES ON test_${MYSQL_DATABASE}.* TO '${MYSQL_USER}';
EOF
The script above is needed in order to allow executing tests becaues django creates database with prefix test
on each tests run. When you copy the file into your image the mysql image entrypoint executes files located in docker-entrypoint-initdb.d
directory.
Create docker-compose
file
version: "3.8"
services:
mysql-db:
build:
context: .
dockerfile: ./docker/mysql/Dockerfile
volumes:
- mysql_data:/var/lib/mysql
restart: unless-stopped
env_file: .env
ports:
- "3306:3306"
backend:
build:
context: .
dockerfile: docker/django/Dockerfile
env_file: .env
restart: always
volumes:
- .:/app/
depends_on:
- mysql-db
working_dir: "/app/mysql_example"
expose:
- 8000
ports:
- "8000:8000"
command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
volumes:
mysql_data: