How to Dockerize a Django Application

This is a step-by-step tutorial that details how to configure Django to run on Docker with MySQL. For production environments, we’ll add on Nginx and Gunicorn. We’ll also take a look at how to serve Django static and media files via Nginx.

Prerequisites

  • docker/docker-compose installed
  • a bit of knowledge working with linux/unix systems

Step 1

Create new project

$ mkdir django-deploy-docker && cd django-deploy-docker
$ mkdir app && cd app
$ python3.8 -m venv env
$ source env/bin/activate
(env)$ pip install django==3.0.7
(env)$ django-admin.py startproject testapp .
(env)$ python manage.py migrate
(env)$ python manage.py runserver

pip freeze > requirements.txt

modify your application to allow it to read the information directly from the environment this will help you manage deployment on multiple sites without having to rebuild the image. For this use environs

modify your settings.py to

For testing create a .env file with the following parameters

DB_ENGINE=django.db.backends.mysql
DB_NAME=YOUR-DB
DB_USER=YOUR-USER
DB_PASSWORD=YOUR-PASSOWRD
DB_HOST=YOUR-HOST
DB_PORT=3306
DEBUG=True
PWD=plIJi2z3jyS2bGcz

Step 2 [ Setting Up Dockerfile]

First, we need to have a docker image that includes our project in order to achieve the deployment. So for that, we need a docker file that will do this for us. So here’s the docker file that will do the trick for us

# pull the official base image
# run app settings
FROM python:3.7.4-alpine
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set up packages required for mysql connector
RUN apk add –update –no-cache mariadb-connector-c-dev \
       && apk add –no-cache –virtual .build-deps \
       mariadb-dev \
       gcc \
       musl-dev \
       && pip install mysqlclient==1.4.2.post1 \
       && apk del .build-deps \
       && apk add libffi-dev openssl-dev libgcc
RUN apk add python python-dev py2-pip autoconf automake g++ make –no-cache
RUN apk add –no-cache jpeg-dev zlib-dev
RUN apk add gcc musl-dev
# pre install dependencies
RUN pip install –upgrade pip gunicorn
RUN pip install bcrypt==3.1.2
RUN pip install environs
COPY ./requirements.txt /usr/src/app/requirements.txt
# Install all packaged
RUN pip install -r requirements.txt
# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
# copy project
COPY . /usr/src/app/
# Give Permission and make executable
RUN chmod 755 /usr/src/app/entrypoint.sh
RUN [“chmod”, “+x”, “/usr/src/app/entrypoint.sh”]
# run entrypoint.sh
ENTRYPOINT [“/usr/src/app/entrypoint.sh”]

Step 3 [ Nginx Config ]

Nginx is used as a proxy and exposes the application assets to the outside network.

create an nginx folder, this will hold server configs and files.The final structure is as below

├── app
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── manage.py
│ ├── requirements.txt
│ ├── static
│ ├── testapp
│ └── web
├── docker-compose.yml
├── mysql
│ └── init.sql
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── README.md

Within the nginx folder create a nginx.conf file and add the following

upstream appsite {
          server web:3762;
}
server {
          listen 80;
          client_max_body_size 14M;
          location / {
               proxy_pass http://appsite;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header Host $host;
               proxy_redirect off;
          }
          location /static/ {
                alias /usr/src/app/static/;
          }
          location /media/ {
                alias /usr/src/app/media/;
          }
}

Create a docker file to define set up of the proxy image

FROM nginx:1.17.2-alpine

RUN rm /etc/nginx/conf.d/default.conf

COPY ./nginx.conf /etc/nginx/conf.d

Step 4 [ Deployment ]

For this step, you need to have both docker and docker-compose installed on your server or local computer.

You can find the tutorial on docker windows, docker mac, docker linux (Debian and Ubuntu) and docker-compose.

Create your MySQL folder within your project with init.sql file to create tables within the DB image.

define your docker-compose orchestration (docker-compose.yml)

If all this is set up then navigate to your project folder within your specific CLI and run

docker-compose up -d --build

the above command will build and deploy the image to the defined stack, once the container is up and running open http://{ your-ip }:1338/ to access your application

Note: Remember to run collectstatic command on your django project so as to generate all static files. This is because Nginx has an alias /static that points to the static folder within your app. This requires the folder to contain all your statically generated files beforehand.
Alternatively you can embed a RUN function within your Dockerfile so that all static files are automatically generated everytime the image is built.

Remarks

In this tutorial, we walked through how to containerize a Django web application with MySQL for development. We also created a production-ready Docker Compose file that adds Gunicorn and Nginx into the mix to handle static and media files. You can now test out a production setup locally.

For an actual production deployment site:

  • You may want to use a fully managed database service — like RDS or Cloud SQL — rather than managing your own MySQL instance within a container.
  • Non-root user for the db and nginx services

To help you manage your docker environment you can install Portainer a Docker GUI management center.

To get you started find the Full project on this @ https://github.com/adams-okode/django-docker-deployment

1 Shares:
You May Also Like