How to Dockerize django application for production deployment with Gunicorn and Nginx
Last Updated :
22 Apr, 2023
Docker is an open-source containerization platform used for building, running, and managing applications in an isolated environment. A container is isolated from another and bundles its software, libraries, and configuration files. Django is an open-source Python web framework that can be used to quickly develop fully functional web applications. In this article, we will discuss how to dockerize a Django app for deployment purposes.
Note: You can visit Dockerizing a simple Django app if you are interested in dockerizing your project for the development phase.
Prerequisites: Before continuing any further, please ensure that node and docker are installed on your machine. If required, visit the Python Installation Guide or the Docker Installation Guide.
Setting up our Application
For this tutorial, we will create a minimal Django application. Initialize a new Django project by running the following commands:
$ mkdir docker-django
$ cd docker-django
$ pip3 install Django
Use the django-admin utility to create a new project
$ django-admin startproject web
$ cd web
Create a new application by running
$ python3 manage.py startapp api
Create a very basic view in the api/views.py file.
api/views.py
Python3
from django.http import HttpResponse
def index(request):
return HttpResponse( "Dockerizing Django Application" )
|
Create a urls.py file in the API directory and match baseurl to our newly created route.
urls.py
Python3
from django.urls import path
from . import views
urlpatterns = [
path(' ', views.index, name=' index'),
]
|
Lastly include the newly created url file into the main application
manage.py
Python3
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path(' ', include(' api.urls')),
path( 'admin/' , admin.site.urls),
]
|
Start the application by running:
$ python3 manage.py runserver
Now, if you go to the URL http://127.0.01:8000 you’ll see the below output:
Below is the project structure shown in the output screenshot.
Dockerizing our Application
Step 1: Dockerfile for a web application
At the root of our react project create a Dockerfile for the Django app.
$ touch Dockerfile
Paste the following into the Dockerfile
# Fetching official base image for python
FROM python:3.9-alpine as web
# Setting up the work directory
WORKDIR /home/app/
# Preventing python from writing
# pyc to docker container
ENV PYTHONDONTWRITEBYTECODE 1
# Flushing out python buffer
ENV PYTHONUNBUFFERED 1
# Updating the os
RUN apk update
# Installing python3
RUN apk add python3-dev
# Copying requirement file
COPY ./requirements.txt ./
# Upgrading pip version
RUN pip install --upgrade pip
# Installing dependencies
RUN pip install gunicorn
# Installing dependencies
RUN pip install --no-cache-dir -r ./requirements.txt
# Copying all the files in our project
COPY . .
Step 2: Dockerfile for the webserver
Now, we need to set up Nginx to serve up reverse proxies and load balancers for Gunicorn. In the root directory of the application, create a new folder for the Nginx web server. Now create an Nginx configuration file for the Django application
$ touch nginx.conf
Paste the following content into the conf file.
upstream django_app {
server web:8000;
}
server {
listen 80;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://django_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/staticfiles/;
}
location /media/ {
alias /home/app/web/mediafiles/;
}
}
Here, we are configuring our server to listen to port 80 and forward requests received to port 8000.
Next, create a new Dockerfile for the web server.
$ touch Dockerfile
Paste the following commands:
# Fetching the latest nginx image
FROM nginx:1.23-alpine
# Removing default nginx.conf
RUN rm /etc/nginx/conf.d/default.conf
# Copying our nginx.conf
COPY nginx.conf /etc/nginx/conf.d
Step 3: Configuring docker-compose
Now we are gonna use a docker-compose plugin to maintain the docker container. Compose is a technique to define and execute multi-container Docker applications. To install docker-compose run the following commands.
$ DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
$ mkdir -p $DOCKER_CONFIG/cli-plugins
$ curl -SL https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
Change file permissions for the current user.
$ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
Verify the installation by performing a version check
$ docker compose version
Lastly, create the docker-compose.yml file at the root of the application.
$ touch docker-compose.yml
Paste the following commands into the file.
docker-compose.yml
version: '3.9'
# Defining the compose version
services:
# Nginx server
nginx:
# Build context
build: ./nginx
# Mapping machine and container ports
ports:
- 1337:80
# Storage volumes
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
depends_on:
- web
restart: "on-failure"
# Django application
web:
# Build context
build: ./web
# Build commands
command: sh -c "python manage.py makemigrations &&
python manage.py migrate &&
python manage.py collectstatic &&
gunicorn web.wsgi:application --bind 0.0.0.0:8000"
# Storage volumes
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
# Exposing port 8000
expose:
- 8000
restart: "on-failure"
volumes:
postgres_data:
static_volume:
media_volume:
Project Structure: This is how the project structure should look at this point:
Create docker containers for the project by running
$ docker compose build
Start the application by launching the containers.
$ docker compose up
Open your browser and navigate to http://localhost:1337/ in your browser to view the homepage of the application.
Share your thoughts in the comments
Please Login to comment...