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.