Django with MySQL 8 Database using Docker

Django with MySQL 8 Database using Docker

Configure a Django database settings to an instance of MySQL 8 with docker-compose.yml and settings.py

Go to the profile of  Jonathan Banks
Jonathan Banks
3 min read
Time
45mins
Platforms
MacOS
Difficulty
Medium
Technologies
Docker, Django, MySQL 8

Setting up Django and MySQL 8 on a Docker instance presents a few configuration challenges.   This article  provides step-by-step guidance to set up and configure the Docker instance while avoiding potential pitfalls.

The official Docker tutorial for configuring Django w/Postgres provides the basis for this guide.  Download that tutorial here.

Dockerfile

Use this Dockerfile as the basis for the setup:

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

The Dockerfile creates a directory named 'code' on the instance. Docker then copies the Django project code in the current directory over to the target directory. The docker-compose file will always copy the content of that folder to the instance on initialization. If there is currently no Django code in that directory, place it there at a later time.

Requirements

Next, add the following requirements.txt file into the installation directory. The requirements.txt file installs the latest version of Django and the MySQL database connectors required by Django. Refer to the contents of the file:

Django>=2.0,<3.0
mysqlclient
mysql-connector-python

Docker-Compose

Create the docker-compose.yml file and add the following in it:

version: '3'

services:
  db:
    image: mysql
    restart: always
    command: --default-authentication-plugin=mysql_native_password --mysqlx=0
    environment:
      - MYSQL_HOST=localhost
      - MYSQL_PORT=3306  # cannot change this port to other number
      - MYSQL_DATABASE=test # name you want for the database
      - MYSQL_USER=user # change to whatever username you want
      - MYSQL_PASSWORD=pick_a_good_password #change to the password you want for user
      - MYSQL_ROOT_PASSWORD=pick_a_good_password #change to good root password
    ports:
      - "3306:3306"
    volumes:
      - "./db:/var/lib/mysql"
 
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

Key components of the database configuration:

  • command:
    • mysqlnativepassword: turns off the new authentication mechanism and sets the default to standard authentication in MySQL 8.
    • mysqlx=0: disables the X Protocol, source of authentication errors.
  • volumes: persists the database on docker shutdown. Create a directory in the current directory of the project named 'db'. The setting maps to '/var/lib/mysql' on the MySQL instance. As a result, the database directory will be persisted on the host machine.

Make sure to create the 'db' directory in the current project directory on the host machine.

Create Django Project

Run the following from the command line to create the Django project:

sudo docker-compose run web django-admin startproject testproject .

Django Settings

Navigate to the settings.py file in the testproject directory. Modify the DATABASES parameter to the configuration specified below. The USER, PASSWORD, and NAME parameter values are from the docker-compose.py file, configured in a previous step.

DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django',
        'USER': 'user',
        'PASSWORD': 'pick_a_good_password',
        'HOST': 'db',#'127.0.0.1',   # Or an IP Address that your DB is hosted on
        'PORT': '3306',
        'NAME': 'test',
    }
}

Setting the HOST to 'db' is the most important step. Most Django documentation on the internet specifies 'localhost' or '127.0.0.1' but these won't work for this configuration. Why?

Docker sets up a local network and can resolve 'db' to the proper container based on the configuration in docker-compose.py. That container is not located on localhost of the container running Django.

Run

Run the command 'docker-compose up' from the command line. If there are no errors, go to the URL http://localhost:8000 in a browser. This will result in the Django success page if there are no configuration errors.

If the host has an installed version of MySQL, validate connectivity from the host to the running instance of mysql. Run the following command, logging in with the same password defined in the docker-compose file.

mysql -u user -p -h 127.0.0.1

If that command generates any errors listed below, then there are configuration problems. Carefully review the steps in this article and ensure there are no typos or missed steps.

  • 'Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory'
  • django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
  • django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
  • django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")
  • django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")
  • django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")