DOCKERIZE YOUR DJANGO APPLICATION
865
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:
-
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
. - Run the following command to build the Docker containers defined in your
-
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
. - Once the build process is complete, start the containers with the following command:
-
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).
- 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
-
Stopping the Containers:
- When you're done working, you can stop the containers using the following command:
docker-compose down
- When you're done working, you can stop the containers using the following command:
Additional Tips:
-
If you want to run the containers in the background, you can add the
-d
flag to thedocker-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!