Skip to content
Related Articles
Open in App
Not now

Related Articles

How to Dockerize django application for production deployment with Gunicorn and Nginx

Improve Article
Save Article
  • Last Updated : 27 Jan, 2023
Improve Article
Save Article

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/static
     - 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.

 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!