Omonbude Emmanuel
Software Engineer
HTML/CSS/JAVASCRIPT
PYTHON
DJANGO/DJANGO REST FRAMEWORK
NODE JS
DOCKER, AWS, KUBERNATES
FIREBASE, PostgreSQL, MySQL,Mongo DB
FLUTTER
DART
ANGULAR
TYPESCRIPT

DOCKERIZE YOUR DJANGO APPLICATION

Omonbude Emmanuel | Nov. 7, 2023, 7:32 p.m.

867

Introduction

Hey there, fellow developer! Ever felt the frustration of deploying your Django app and running into issues because things work differently on different machines? Say goodbye to those headaches because we're about to dive into the wonderful world of Docker, a game-changer for developers like you.

Docker makes your life easier by wrapping up your entire Django project and all its necessities into a neat, portable box called a "container." It ensures that your app runs the same way everywhere, from your laptop to your colleague's computer and even in the cloud. 

In this article, we'll explore the process of dockerizing a Django application, enabling you to run your Django project seamlessly across different environments.

Prerequisites:

Before you begin, make sure you have the following installed on your system:

Docker: The platform for developing, shipping, and running applications in containers.
Docker Compose: A tool for defining and running multi-container Docker applications.

If you're using Ubuntu operating system, you can follow the link below to my previous posts on how to install docker and docker-compose.

https://www.budescode.com/details/how-to-install-docker-in-ubuntu-server

https://www.budescode.com/details/how-to-install-docker-compose-on-ubuntu-server

The project is already on github, you can clone it from  https://github.com/budescode/django-docker.git

 

Step 1: Setting Up Your Django Project:

to create the django project we run the command:

 

django-admin startproject project

 

and to create our app, we run the command:

python manage.py startapp index

 

Step 2: Dockerfile:

Create a Dockerfile in the root of your Django project. This file contains instructions for building a Docker image for your application. Here's a sample.

 

FROM python:3.8 # Set environment variables

ENV PYTHONUNBUFFERED 1 

#This means that as soon as a message is generated (e.g., by a print statement), it's immediately visible, making it easier to see real-time output and diagnose issues more quickly, especially in environments like Docker where log messages may be crucial for debugging.

ENV DJANGO_SETTINGS_MODULE project.settings

# Create and set the working directory

RUN mkdir /code

WORKDIR /code

 

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

# Install any needed packages specified in requirements.txt

RUN pip install -r requirements.txt

 

# Copy the entrypoint script and make it executable

COPY entrypoint.sh /code/entrypoint.sh

RUN chmod +x /code/entrypoint.sh

# Copy the entrypoint.sh script and set execute permissions

# Expose the port the application runs on

EXPOSE 8000


# Run Django development server

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

 

Step 3: Docker Compose:

Create a docker-compose.yml file to define your application's services, networks, and volumes. This file simplifies the process of running multiple Docker containers.

:

version: '3'

services:
  # Django web application
  web:
    container_name: my-django-app
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env
    ports:
      - "8000:8000"
    volumes:
      - .:/code
    depends_on:
      - db
    environment:
      - DEBUG=True  # Set your Django application environment variables here
    command: sh ./entrypoint.sh


  # PostgreSQL database
  db:
    image: postgres:14.1-alpine
    container_name: my-postgres-db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
          - "5432:5432"
    env_file:
      - .env # Include the environment file here

volumes:
  postgres_data:

 

Explanation:

1. Docker Compose Version:
version: '3': Specifies the version of the Docker Compose file format being used.
2. Services:

  • Django Web Application (web service):
    container_name: Specifies the name of the Docker container for the Django application.
    build: Specifies the build context and Dockerfile for building the custom Docker image.
    env_file: Includes environment variables from the .env file for the Django application.
    ports: Maps port 8000 on the host to port 8000 in the container.
    volumes: Mounts the current directory (.) to the /code directory in the container, facilitating code synchronization.
    depends_on: Declares a dependency on the db service, ensuring the PostgreSQL database starts before the Django application.
    environment: Sets additional environment variables for the Django application.
    command: Executes the entrypoint.sh script when the container starts.
  • PostgreSQL Database (db service):
    image: Specifies the PostgreSQL image and version to use.
    container_name: Specifies the name of the Docker container for the PostgreSQL database.
    volumes: Creates a named volume (postgres_data) to persist PostgreSQL data.
    ports: Maps port 5432 on the host to port 5432 in the container for PostgreSQL connections.
    env_file: Includes environment variables from the .env file for PostgreSQL configuration.

3. Volumes:
volumes: Defines a named volume (postgres_data) to persist data for the PostgreSQL database.

This setup file makes sure your Django web app and PostgreSQL database team up smoothly. It uses Docker Compose tricks like handling dependencies, adding environment stuff, and dealing with data storage to create a friendly space for your Django project. 

Step 4: Entry Point

The entrypoint.sh script in the context of a Dockerized Django application serves as the entry point or the initial command that runs when the Docker container starts. This script is often used to perform any necessary setup or configuration tasks before starting the main application.

 

#!/bin/sh

set -e

python3 manage.py migrate --no-input

python3 manage.py collectstatic --no-input

python manage.py runserver 0.0.0.0:8000

 

Step 5: .env file

The .env file is a configuration file commonly used to store environment variables for your application. It follows a simple key=value format, where each line represents a variable and its corresponding value. This file is particularly useful for managing sensitive information, configuration parameters, or anything that might change between different environments (e.g., development, testing, production). In this case, we'd be storing details for our postgres database

create a .env file in your main directory  and add the following details

POSTGRES_DB=mydb
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword

You can change it to your following details

 

Step 6: settings file

We need to configure our settings.py file to connect it to the postgres database 

 

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get('POSTGRES_DB'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST', 'db'),
        'HOST': 'db',
        'PORT': 5432,
    }
}

STATIC_URL = '/static/'

STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static')]

STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn')

MEDIA_URL = '/media_cdn/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media_cdn')

 

Step 7: Build and start the Docker containers:

  1. Build Docker Containers:

    • Run the following command to build the Docker containers defined in your docker-compose.yml file:
      docker-compose build 
      

    This command instructs Docker Compose to build the images specified in the services of your docker-compose.yml.

  2. Start Docker Containers:

    • Once the build process is complete, start the containers with the following command:
      docker-compose up 

    This command starts the services defined in your docker-compose.yml.

  3. Access Your Dockerized Django App:

    • After the containers are up and running, you should be able to access your Django web application. Open a web browser and go to http://localhost:8000 (or the port you specified in the docker-compose.yml if different).
  4. Stopping the Containers:

    • When you're done working, you can stop the containers using the following command:
      docker-compose down

 

Additional Tips:

  • If you want to run the containers in the background, you can add the -d flag to the docker-compose up command:
    docker-compose up -d

  • To see logs and monitor container output, you can run the following command in a separate terminal window:
    docker-compose logs -f

  • To run a command in django app inside the docker container run the command 
    docker-compose run web python3 manage.py createsuperuser 
    this command creates superuser in our web service.

  • To open terminal in web service
    docker compose exec -it web bash

 

Conclusion:

In conclusion, Dockerizing your Django application offers significant advantages in terms of reproducibility, portability, isolation, scalability, and manageability. By leveraging Docker's containerization technology, you can streamline your application development and deployment process, ensuring consistent performance and seamless operation across different environments.

May your containers run seamlessly, your deployments be effortless, and your Django endeavors be infused with the innovation and efficiency that Dockerization brings. Happy coding, and welcome to the era of Dockerized Django!

© 2024 Omonbude Emmanuel

Omonbude Emmanuel