With the growing trend of containerization in web development, Docker has become an indispensable tool for developers. Docker allows for seamless management of dependencies and environments, enabling developers to focus on coding. In this article, we’ll guide you through setting up a Django development environment using Docker.
Prerequisites
Before starting, make sure the following are installed on your system:
- Docker: Visit Docker’s official website to download and install Docker Desktop.
- Docker Compose: Usually included with Docker Desktop, install separately if it’s not.
First, let’s create a folder for our project and configure the structure for the project:
/app
/docker # folder for docker conf files
nginx.conf # conf for nginx
python.Dockerfile # dockerfile for python
/pgdata # folder for postgres volumes, empty folder
/src # folder where the code of your site will be
.env # Configuration values for the project
docker-compose.yml # docker conf file with services
requirements.txt # a list of packages or libraries needed to work on a project
Step 1: Setup Python Docker Environment
Create a `.env` file using the following command:
touch .env
Enter values for your .env:
# .env
DOCKER_HTTP_PORT=80 # standart port for http
DOCKER_HTTPS_PORT=443 # standart port for https
DJANGO_PROJECT_NAME=project # the name of our Django project
NGINX_CONF_PATH='./docker/nginx.conf' # path to nginx conf file
# DATABASE CONF
DB_USER= # enter user name
DB_PASSWORD= # enter user password
DB_DATABASE= # enter database name
DB_HOST=postgres # the name of postgres service in docker-compose file
DB_PORT=5432 # standart port for postgres
ADMINER_DB_PORT=8081 # port for web gui admin panel for postgres
In the docker folder, create a file named python.Dockerfile. This file defines the configuration for our Docker container. Add the following content to your python.dockerfile:
# /docker/python.Dockerfile
FROM python:3.12-alpine
ENV PYTHONUNBUFFED 1
ENV PYTHONDONTWRITEBYTECODE 1
RUN apk upgrade && apk update \
&& apk add gcc python3-dev musl-dev \
jpeg-dev gettext zlib-dev py3-setuptools \
mariadb-connector-c-dev mariadb-dev
RUN apk del libressl
RUN apk add openssl
RUN apk fix
#libressl-dev
RUN apk add libffi-dev cargo
RUN mkdir /app
WORKDIR /app
COPY ./src /app
COPY ./requirements.txt /app/requirements.txt
# Install any required dependencies
RUN pip install --upgrade pip && pip install -r requirements.txt
# Expose port 8000 for Gunicorn
EXPOSE 8000
This python.dockerfile creates a Docker container with Python 3.12 and installs the necessary dependencies to run a Django project.
# requirements.txt
Django
gunicorn
psycopg2-binary
Step 2: Setup Nginx Docker Environment
Create an nginx directory at the root of your project. Within it, create a default.conf file and insert the following Nginx server configuration:
# /docker/nginx.conf
# Define the upstream server (Gunicorn)
upstream web { # name of service in docker-compose.yml
server web:8000; # name of service in docker-compose.yml
}
server {
listen 80;
server_name localhost;
client_max_body_size 50M;
client_body_buffer_size 50M;
location /static/ {
alias /static/;
expires 30d;
}
location /media/ {
alias /media/;
expires 30d;
}
location / {
proxy_pass http://web; # name of service in docker-compose.yml
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Step 3: Create a Docker Compose File
In the root directory of your project, create a docker-compose.yml file. This file allows us to define and manage multi-container Docker applications. Insert the following content:
# docker-compose.yml
services:
web:
build:
context: .
dockerfile: ./docker/python.Dockerfile
command: gunicorn ${DJANGO_PROJECT_NAME}.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./src:/app:delegated
expose:
- 8000
env_file:
- .env
restart: always
nginx:
image: nginx:latest
volumes:
- ${NGINX_CONF_PATH}:/etc/nginx/conf.d/default.conf
- ./src/static:/static:delegated
- ./src/media:/media:delegated
ports:
- "${DOCKER_HTTP_PORT}:80"
- "${DOCKER_HTTPS_PORT}:443"
env_file:
- .env
restart: always
depends_on:
- web
postgres:
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
adminer:
image: adminer
restart: always
ports:
- ${ADMINER_DB_PORT}:8080
volumes:
pgdata:
This docker-compose.yml file creates three services: one for Python (Django), one for PostgreSQL, and one for Nginx. It also defines a Docker network that the services use to communicate.
Step 4: Build the Docker Containers
Now, we’re ready to build our Docker containers. From the root directory of your Django project, run the following command:
docker compose build
Step 5: Create a Django Project
We need to create a new Django project where the project name is "project" (if you change the project name, update the DJANGO_PROJECT_NAME in the .env file). Navigate to the directory where you wish to create your project and run the following command:
docker compose run --rm web django-admin startproject project .
After running this command, the project code should appear in the src folder.
If you need to run Django management commands, you can use:
docker compose run --rm web python manage.py
Run the Docker Containers
docker compose up -d
You can verify if the project is working by opening the browser and adding the port specified in DOCKER_HTTP_PORT. For example, if it’s set to 80:
6. Configure Django
Add STATIC_ROOT and configure Postgres in settings.py:
# /src/project/settings.py
import os
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ.get('DB_HOST'),
'PORT': os.environ.get('DB_PORT'),
'NAME': os.environ.get('DB_DATABASE'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
}
}
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
7. Run Migrations
docker compose run --rm web python manage.py migrate
Rebuild the Project Using Docker Compose
docker compose up -d --build
Create the admin user:
docker compose run --rm web python manage.py createsuperuser
After running this command, you can access the admin panel at:
8. Handle Static Files
Add the lines for the ENTRYPOINT in the python.Dockerfile, which runs the command for static files:
# /docker/python.Dockerfile
COPY ./docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Create /docker/entrypoint.sh file
#!/bin/sh
python manage.py collectstatic --noinput
exec "$@"
Then, restart Docker:
docker compose up -d --build
Alternatively, you can run the following command:
docker compose run --rm web python manage.py collectstatic
Access the Full Project
For the full project, feel free to visit GitHub repository