🏠 Home
Building a Django Project with Docker: A Step-by-Step Guide

Building a Django Project with Docker: A Step-by-Step Guide

Introduction

In this step-by-step tutorial is designed for developers of all levels looking to harness the power of Docker in streamlining development environments and deployment processes. Through this guide, you’ll learn how to set up, develop, and deploy a Django application within Docker containers, ensuring a consistent and efficient workflow. Join us as we explore the seamless integration of Django with Docker, paving the way for scalable and portable web applications.

All the example code can be found here.

What You Will Learn

By the end of this tutorial, you’ll learn how to:

Prerequisites

Before starting the tutorial, make sure you have the following prerequisites installed and set up on your computer:

  1. Python 3.10+ (we’ll use 3.12):
  1. Docker:

Step 1: Setting Up Your Django Project

First, let’s create a folder to put our project inside:

mkdir django-docker-project
cd django-docker-project

Now, let’s run Python 3.12 to conver this folder into a Django project:

python3.12 -m pip install django
python3.12 -m django startproject server .

Now, within this folder, we should have the following files:

# Command: tree .
.
├── manage.py
└── server
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

We now have a proper Django project!

Step 2: Setting Up Your Vitual Environment

Now that our folder is a Django project, let’s setup a virtual environment and install the necessary dependencies!

A virtual environment is useful because it allows you to manage separate dependencies for different projects, preventing conflicts between package versions and ensuring consistency across development and production setups.

Let’s create and run a Python 3.12 virtual environment now:

python3.12 -m venv my-venv
source my-venv/bin/activate

You should now see (my-venv) in your terminal. This means your virtual environment is up and running!

Now, let’s add all the necessary dependencies to make Django run (in dev and production):

pip install django gunicorn psycopg2-binary
pip freeze > requirements.txt

We need to save the dependencies into requirements.txt becasuse the Dockerfile will need to download the dependencies too!

Step 3: Run Django locally

Since we have our Django Project set up, our Vitual Environment active, and our dependencies installed - we can now run Django locally.

python manage.py runserver

You should see the following website at http://127.0.0.1:8000/

Django up and running

Step 4: Add Production Settings

This is where it gets interesting: If you want to build and deploy Django using Docker, you want to set up your Django Project for production AND run a production version of your app in Docker.

Let’s setup both local and production settings in Django pick our runtime with environment variables.

First, lets create a ./server/settings folder and __init__.py, local.py and production.py.

  1. Copy the contents in server/settings.py and paste it into server/settings/local.py
  2. Copy the contents in server/settings.py and paste it into server/settings/production.py
  3. Delete server/settings.py
  4. Add the following code into server/settings/__init__.py:
import os

def get_secret(secret_id, backup=None):
    return os.getenv(secret_id, backup)

# Keep at the end
if get_secret('PIPELINE') == 'production':
    from .production import *
else:
    from .local import *

This will pull the environment variable PIPELINE and run local or production settings.

Next, lets re-write the following parts of server/settings/production.py:

# Change the SECRET_KEY to an environment variable
from . import get_secret
SECRET_KEY = get_secret('SECRET_KEY')

# Change DEBUG to False
DEBUG = False

# Change ALLOWED_HOSTS to all hosts
ALLOWED_HOSTS = ['*']

# Change DATABASES to connect to a real database
DB_NAME = get_secret("DB_NAME")
DB_USER_NM = get_secret("DB_USER_NM")
DB_USER_PW = get_secret("DB_USER_PW")
DB_IP = get_secret("DB_IP")
DB_PORT = get_secret("DB_PORT")
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': DB_NAME,
        'USER': DB_USER_NM,
        "PASSWORD": DB_USER_PW,
        "HOST": DB_IP,
        "PORT": DB_PORT,
    }
}

We’ll need to make sure we add these environment variables in our Docker Run commands, since values like SECRET_KEY are required for a Django Project to run.

Now, we have a production version of Django ready to be built and deployed!

Step 5: Writing Your Dockerfile

To build our Django Project with Docker, we need to create a Dockerfile. Below is our Dockerfile and a comment for why we need each line:

# Use Python 3.12.2 image based on Debian Bullseye in its slim variant as the base image
FROM python:3.12.2-slim-bullseye

# Set an environment variable to unbuffer Python output, aiding in logging and debugging
ENV PYTHONBUFFERED=1

# Define an environment variable for the web service's port, commonly used in cloud services
ENV PORT 8080

# Set the working directory within the container to /app for any subsequent commands
WORKDIR /app

# Copy the entire current directory contents into the container at /app
COPY . /app/

# Upgrade pip to ensure we have the latest version for installing dependencies
RUN pip install --upgrade pip

# Install dependencies from the requirements.txt file to ensure our Python environment is ready
RUN pip install -r requirements.txt

# Set the command to run our web service using Gunicorn, binding it to 0.0.0.0 and the PORT environment variable
CMD gunicorn server.wsgi:application --bind 0.0.0.0:"${PORT}"

# Inform Docker that the container listens on the specified network port at runtime
EXPOSE ${PORT}

Write this into a file called Dockerfile at the top-level of our project.

Step 6: Build and Run Commands

Now that our Dockerfile is written, lets build it and run it with our needed environment variables:

# Build the Dockerfile
docker build -t django-docker-project:latest .

# Run the Docker image
docker run -p 8000:8080 \
--env PIPELINE=production \
--env SECRET_KEY=your_value \
--env DB_NAME=. \
--env DB_USER_NM=. \
--env DB_USER_PW=. \
--env DB_IP=0.0.0.0 \
--env DB_PORT=5432 \
django-docker-project

Be sure to replace your_value with your secure production secret key.

You can now see this production Django Project running at http://localhost:8000/

Django up and running

(Test http://localhost:8000/admin to be sure.)

Conclusion

Great job setting up your Django project with Docker!

Ready to dive deeper? Check out my tutorials on connecting Django to AWS and GCP databases and deploying your applications serverlessly on these platforms. These guides will help streamline your workflow and enhance your app’s performance in cloud environments.

Keep learning, and take your web development skills to new heights!

Additional Resources:

  1. Django + Databases
  1. Django + AWS tutorials
  1. Django + GCP tutorials