Docker Django mysql
Here's folder structure:
📄 Dockerfile
📄 .env
📄 requirements.txt
📁 pr/
📁 static/
📄 app.js
📄 manage.py
📁 pr/
📄 wsgi.py
📄 __init__.py
📄 urls.py
📄 settings.py
📄 asgi.py
📄 docker-compose.yml
Here the important file's content
Dockerfile
---------
# Use an official Python runtime as a parent image
# syntax=docker/dockerfile:1
FROM python:3.11
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gcc \
libmariadb-dev \
&& rm -rf /var/lib/apt/lists/*
# Upgrade pip
RUN pip install --upgrade pip
# Set the working directory
WORKDIR /app
# Install Python dependencies
COPY requirements.txt /app/
RUN pip install -r requirements.txt
# Copy the project code into the container
COPY ./pr /app/
# Expose the Django development server port
EXPOSE 8000
requirements.txt
---------
psycopg2>=2.8
asgiref==3.8.1
Django==5.1.1
djangorestframework==3.15.2
mysqlclient==2.2.4
python-dotenv==1.0.1
sqlparse==0.5.1
pytz==2024.2
settings.py:
....
# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MYSQL_DATABASE'),
'USER': os.environ.get('MYSQL_USER'),
'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
'HOST': 'dj1_mariadb',
'PORT': 3306,
}
}
....
docker-compose.yml:
services:
dj1_mariadb:
image: mariadb:latest
container_name: dj1_mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: myrpass
MYSQL_DATABASE: dj1
MYSQL_USER: ab_usr
MYSQL_PASSWORD: mypass
volumes:
- ./data/mariadb:/var/lib/mysql
# apt-get update && apt-get install -y mariadb-client
networks:
- app-network
dj1_pma:
image: phpmyadmin/phpmyadmin
container_name: dj1_pma
restart: always
environment:
PMA_HOST: dj1_mariadb
PMA_USER: ab_usr
PMA_PASSWORD: mypass
ports:
- "8080:80"
depends_on:
- dj1_mariadb
networks:
- app-network
dj1_web:
build:
context: .
dockerfile: Dockerfile
container_name: dj1_web
command: >
sh -c "python3 manage.py collectstatic --noinput && python3 manage.py runserver 0.0.0.0:8000"
volumes:
- ./pr:/app
- ./pr/static:/app/static
ports:
- "8000:8000"
environment:
- MYSQL_DATABASE=dj1
- MYSQL_USER=ab_usr
- MYSQL_PASSWORD=mypass
depends_on:
- dj1_mariadb
networks:
- app-network
networks:
app-network:
driver: bridge
Can somebody help me? http://localhost:8080/ works well. But the docker django cannot connect the to the database:
my@host:~/dj1$ docker-compose run dj1_web python3 manage.py inspectdb
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
self.connect()
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
super().__init__(*args, **kwargs2)
MySQLdb.OperationalError: (2002, "Can't connect to server on 'dj1_mariadb' (115)")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/manage.py", line 22, in <module>
main()
File "/app/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 413, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 459, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/inspectdb.py", line 47, in handle
for line in self.handle_inspection(options):
File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/inspectdb.py", line 60, in handle_inspection
with connection.cursor() as cursor:
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 320, in cursor
return self._cursor()
^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 296, in _cursor
self.ensure_connection()
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 278, in ensure_connection
with self.wrap_database_errors:
File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 279, in ensure_connection
self.connect()
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
super().__init__(*args, **kwargs2)
django.db.utils.OperationalError: (2002, "Can't connect to server on 'dj1_mariadb' (115)")
A depends_on
relationship only requires the dependency be started, but its not necessary ready as the "Can't connect to server" would indicate in your case.
On way is to use the MariaDB healthcheck.sh script.
services:
dj1_mariadb:
image: mariadb:latest
container_name: dj1_mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: myrpass
MARIADB_DATABASE: dj1
MARIADB_USER: ab_usr
MARIADB_PASSWORD: mypass
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
volumes:
- ./data/mariadb:/var/lib/mysql
dj1_pma:
...
depends_on:
dj1_mariadb:
condition: service_healthy
dj1_web:
...
depends_on:
dj1_mariadb:
condition: service_healthy
If this isn't the case, look at the logs on dj1_mariadb
to see why it didn't start. Also see the FAQ.