45mins
MacOS
Medium
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)")