Setup Django with Mysql using docker

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: