Dockerizing Django With Postgres, NGINX, and Gunicorn (PART-1)
We will be discussing about the Dockerizing Django project for the deployment
Table of contents
Running a Django application in a production environment requires a server that can handle traffic, ensure stability, and provide scalability. Gunicorn is a widely used and trusted server for running Django applications in such an environment. In this article, we'll be deploying a Django application with docker, postgres, gunicorn and nginx configurations. So, Let's start and understand everything in more detail step by step
Prerequisites
Before we begin, make sure that you have the following installed on your local machine:
Python 3.7 or higher
Django
Django Rest Framework
Docker and Docker-compose
Make sure to set up your Django project and run it locally. After everything is ready, let's make your Django application ready for deployment.
Create a Dockerfile
The Dockerfile is a script that contains instructions on how to build a Docker image for your application. Create a new file named Dockerfile
in the root directory of your Django project with the following content:
# official base image
FROM python:3.10.9-alpine3.17
#set work directory
RUN mkdir /app
WORKDIR /app
#set environment variable
ENV PYTHONDONTWRITEBYCODE 1
ENV PYTHONUNBUFFERED 1
#install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# copy project
COPY . .
Let's understand the code Line by Line,
So basically, The first line specifies the official base image to use, which is the Python 3.10.9-alpine3.17 image. This image is a lightweight version of Python that runs on Alpine Linux, which is a small, secure, and efficient Linux distribution.
Next, the working directory is set to /app
, which is where the application code will reside inside the container.
Two environment variables are set to ensure that the Python application runs correctly in the container. The PYTHONDONTWRITEBYCODE
environment variable is set to 1, which instructs Python not to write bytecode files to disk. The PYTHONUNBUFFERED
environment variable is also set to 1, which disables the buffering of standard output and standard error streams by Python.
The dependencies for the Django application are installed via pip. First, pip is upgraded to the latest version, and then the contents of requirements.txt
are copied into the container and installed using pip.
Finally, the entire contents of the application's directory are copied into the Docker image. This includes the Django project files, any static files, templates, or media files, as well as any other necessary files for the application to run.
This Dockerfile sets up the basic environment required to run a Django application in a containerized environment and is a good starting point for building more complex Docker images for Django applications.
Let's go on more,
Docker Compose
Docker Compose is a tool that allows you to define and run multi-container Docker applications. With Compose, you can define the services that make up your application, how they should be configured, and how they should interact with each other.
A Docker Compose file is a YAML file that defines the services, networks, and volumes required for your application. In a typical Django application, you might have several services, such as the Django web server, a database service like Postgres, and a web server like Nginx.
In a Docker Compose file, you would define each of these services as a separate container, along with their configuration options. You can also define networks and volumes that are shared between the containers.
So Let's Make a docker-compose.yml file to the root project
version: '3.10'
services:
app:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- static_data:/app/static
ports:
- "8000:8000"
env_file:
- ./.env
Let's understand the code line by line,
The command
instruction specifies the command to run when the container starts up. In this case, it's running the runserver
command for Django, which starts a development server that listens on all available network interfaces (0.0.0.0
) on port 8000
.
The volumes
instruction creates a named volume named static_data
that will be mounted inside the container at the path /app/static
. This allows the container to access static files that are generated by Django and stored outside of the container.
The ports
instruction maps port 8000
on the host machine to port 8000
inside the container, so that the Django application can be accessed by visiting http://localhost:8000
in a web browser.
Finally, the env_file
instruction specifies a path to a file containing environment variables that should be loaded into the container. In this case, the file is located at ./.env
.
Now, create a .env
file in the project root to store environment variables for development:
SECRET_KEY=
ALLOWED_HOSTS= localhost 127.0.0.1 [::1]
DEBUG=True
You need to change the SECRET_KEY, ALLOWED_HOST and DEBUG in your project Setting file. Make sure to add import os
in your setting file
import os
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())
Now, Build the image:
$ docker-compose build
Once the image is built, run the container:
$ docker-compose up -d
Now Go to http://localhost:8000/ to see the project running.
Summary:
Up to now We built a Docker image of our application and run into a container that is running successfully. In the next part, We'll see how to integrate PostgreSQL with your application and dockerize further until then have a great time. Bye!
Part-2: Dockerizing Django With Postgres, NGINX, and Gunicorn (PART-2)