Setting Up a Django Development Environment Using Docker

Vitalii Shloda
4 min readJun 28, 2024

--

Access the Full Project

For the full project, feel free to visit GitHub repository.

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:

Step 1: Setup Python Docker Environment

Create a `.env` file using the following command:

touch .env

Enter values for your .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.dev.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:

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.

Create requirements.txt

Django
gunicorn
psycopg2-binary

Step 2: Setup Nginx Docker Environment

Create an nginx.dev.conf at the docker folder and insert the following Nginx server configuration:

# Define the upstream server (Gunicorn)
upstream web {
server web:8000;
}

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:

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:

http://localhost

6. Configure Django

Add STATIC_ROOT and configure Postgres in 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:

http://localhost/admin

8. Handle Static Files

Add the lines for the ENTRYPOINT in the python.Dockerfile, which runs the command for static files:

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

If you’re interested in similar articles, you might want to explore more on this site.

--

--

Vitalii Shloda
Vitalii Shloda

Written by Vitalii Shloda

Software Engineer. I write about backend, data and other amazing stuff

No responses yet