Skip to main content

How to Bootstrap a Django Application with Docker

In this tutorial, we will learn how to bootstrap a project to use Docker. I have loved to dockerize my application from the start because it gives me freedom from using a virtual environment. It saves you a lot if you are a DevOps person. You don’t have to install many dependencies every time for any programming language you are working on.

Before you can start any project, we need to create the following files, if you are looking to dockerize your environment.

  • Dockerfile
  • Docker-compose file
  • Makefile
  • Script to run WSGI processes.

# Dockerfile

A Dockerfile is a text document that contains all the commands a user could call on a command line to assemble an image. Examples of commands to use are FROM, RUN, CMD, WORKDIR, and COPY. I am using an example for a Django application.

# python base image. Get this from dockerhub
<strong>FROM python:3.11-slim</strong>

#set environment variables
<strong>ENV PYTHONUNBUFFERED=1</strong>

#set your working directory
<strong>WORKDIR /usr/src/app</strong>

# install dependencies required by the image you pulled above
<strong>RUN apt update && apt install -y g++ libpq-dev gcc musl-dev</strong>

#allow docker to cache installed dependencies between builds 
<strong>COPY requirements.txt .
RUN python3 -m pip install -r requirements.txt --no-cache-dir</strong>

# copy and mount the project to the working directory
COPY . .
# Script to run given instruction eg running production server.
<strong>CMD ["./run.sh"]</strong>

# Docker-compose file

A compose is a YAML file defining services, networks, configs,, secrets and volumes for the Docker applications.

An example of a docker compose file for Django application. Make sure you are saving with <mark style="background-color:#abb8c3" class="has-inline-color">.yaml or yml</mark> extensions.

version: "3.9"

services:
  app:
    image: <image_name>/myproject:latest
    working_dir: /usr/src/app
    ports:
      - 8000:8000
    depends_on:
      - db
    volumes:
      - .:/usr/src/app
    environment:
      - Env=local
      - DEBUG=1
      - ALLOWED_HOSTS=*
      - SECRET_KEY=
      - APP_PATH=/var/www/myproject
      - DATABASE_DB=dbname
      - DATABASE_USER=dbuser
      - DATABASE_PASSWORD=password
      - DATABASE_HOST=db
      - DATABASE_PORT=5432

    networks:
      - myproject_net

#specify database settings here
  db:
    image: postgres:14.5-alpine
    ports:
      - 5432:5432
    volumes:
      - myproject_pg:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=engineer
      - POSTGRES_USER=engineer
      - POSTGRES_DB=engineer
    networks:
      - myproject_net
volumes:
  myproject_pg:# databse volume
  myproject_app: #app volume

networks:
  myproject_net: #connection string

# Database settings

After you have specified your PostgreSQL seetttings on the compose file, make sure you go to settings to specify which db you are using. NB, this is for Django applications.

#settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.<strong>postgresql_psycopg2</strong>',
		'NAME': os.environ.get('DATABASE_DB'),
		'USER': os.environ.get('DATABASE_USER'),
		'PASSWORD': os.environ.get('DATABASE_PASSWORD'),
		'HOST': os.environ.get('DATABASE_HOST'),
		'PORT': os.environ.get('DATABASE_PORT'),

    }
}

# Makefile

Makefile defines sets of commands to run and a make utility runs them. An example of a Makefile for running a Django application.

IMAGE=<image_name> # specify how you want to save your image with a tag #name

build:
	docker build -t $(IMAGE) .

up:
	docker-compose up -d

ps:
	docker-compose ps

migrate:
	docker-compose exec app python manage.py migrate

makemigrations:
	docker-compose exec app python manage.py makemigrations

collectstatic:
	docker-compose exec app python manage.py collectstatic --noinput

createsuperuser:
	docker-compose exec app python manage.py createsuperuser

logs:
	docker-compose logs -f

rm: stop
	docker-compose rm -f

stop:
	docker-compose stop

# Running script

The last item is to specify the script to run your project in production. The script looks like this for a Django application. Make sure to give the permission to the <mark style="background-color:#abb8c3" class="has-inline-color">run.sh</mark>. Run this command <mark style="background-color:#abb8c3" class="has-inline-color">chmod +x run.sh</mark>

# run.sh
#!/bin/bash

# collect static because of the heavy state of static files in production
python manage.py collectstatic --no-input

# gunicorn for WSGI communication
exec gunicorn --bind 0.0.0.0:8000 project.wsgi:application -w 2

# Building the Application

To start using the application run the following commands.

#build from a makefile
$ make
#bring up the container 
$ docker-compose up
# running a container in the background
$ docker-compose up -d
# running django application tasks
$ docker-compose run --rm app sh -c "python manage.py runserver"

# Conclusion

From the above makefile, dockerfile and docker compose, you are now in a position to run your application anywhere, thanks to the Docker containers.