Running MySQL/MariaDB in a Docker container:
docker run -p 3306:3306 --name $(DATABASE_NAME) -v /tmp/mysql:/var/lib/mysql -e MYSQL_DATABASE=$(DATABASE_NAME) -e MYSQL_USER=$(DATABASE_USER) -e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) -d mariadb:latest > /dev/null
And then running Django version 4 locally with:
manage.py runserver 127.0.0.1:8000
Error
django.db.utils.OperationalError: (2013, "Lost connection to MySQL server at 'reading initial communication packet', system error: 2")
I can successfully connect to the database with MySQL Workbench as well as the command:
mysql -h 127.0.0.1 -P 3306 -u root -p <database>
I am launching Django and the MySQL/MariaDB Docker container from a Makefile.
Makefile
SHELL := /bin/bash
.PHONY: dj-start-local
dj-start-local: start-mysql
PYTHONPATH=. django_project/src/manage.py runserver 127.0.0.1:8000
.PHONY: start-mysql
start-mysql:
docker run -p 3306:3306 --name $(DATABASE_NAME)
-v /tmp/mysql:/var/lib/mysql
-e MYSQL_DATABASE=$(DATABASE_NAME)
-e MYSQL_USER=$(DATABASE_USER)
-e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD)
-d mariadb:latest > /dev/null
2
Answers
The issue may be due to a race condition, where Django is attempting to connect to the database before it is ready. Try waiting a few seconds after starting the Docker container.
Simple Solution
Makefile
Better Solution using healthcheck.sh
In Dan Black's answer, he pointed out that the MariaDB docker container includes a script healthcheck.sh.
If you only want to check if the MariaDB container can receive connections, then
healthcheck.sh
can be run without specifying a user (avoiding authorization complications).The Makefile below will check for a database connection every second until the database is ready.
Makefile (advanced version)
Use the
healthcheck.sh
in the container. Use theMARIADB_MYSQL_LOCALHOST_USER=1
to create amysql@localhost
user that the script can use to access the database,The healthcheck waits until its fully started regardless of the time.
Makefile:
Test run:
Note: added
MARIADB_PASSWORD
otherwise the database/user wouldn’t be created.