How to Containerize and Deploy Django Web App on Azure - Single Host
Docker, Django, Azure.... we hear about these terms in our daily day to day job. I would assume we all have a little understanding as to what these
terms are. If not that is ok. Check the links below to read about them.
This is a follow up from one of our previous tutorial, How to Create and Deploy Django Web App on Azure . In the
previous tutorial, we created a django app and deployed it on a full VM on azure. However, in this tutorial we will be packaging the django app
using docker and deploying it onto azure. Later on, I will be creating a blog-post showing the benefits and benchmark test between using a full VM or container to deploy a webapp.
Let's get started
Tools Needed
# | Components | Link | Necessary |
---|---|---|---|
1 | Azure Account | Free $200 Azure Credit on Sign Up. | Yes |
2 | Azure VM | Create VM | Yes |
3 | Docker | Download Docker | Yes |
4 | Your Time | Roughly 20 mins | Yes. So you can learn to build web app. |
Please follow this tutorial to create a VM on Azure if you haven't created one already.
Once you are done creating your Azure Account and creating your VM, you are golden to follow through the tutorial.
Installing Docker and Docker-Compose
Install packages
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
Add Docker GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Add Docker repository
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
Install Docker
$ sudo apt install docker-ce
Add current user to run Docker without sudo
$ sudo usermod -aG docker ${USER}
Log user out/in of system
$ su - ${USER}
Install Docker-Compose
$ sudo curl -L \
https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64\
-o /usr/local/bin/docker-compose
Change Docker-Compose permission
$ sudo chmod +x /usr/local/bin/docker-compose
Congratulations you now have docker and docker-compose installed
Setting Up Django Project
Create django directory
$ mkdir django && cd django
Create a python virtual environment
$ virtualenv .
Setup DB
$ mkdir db && cd db
Create a docker-compose
file to create postgres
db running in a container
$ vi docker-compose.yml
Paste the following lines into the file
version: '3.5'
services:
django-db:
image: postgres
restart: always
container_name: django_db
environment:
POSTGRES_PASSWORD: root
POSTGRES_USER: root
PGDATA: /var/lib/postgresql/data
ports:
- 5432:5432
This will create a postgres db ruining in container
Bring the postgres container up
docker-compose up -dWe will be using the default
postgres
db and root
user. Please don't do this in production environment.
Change back to django directory
cd ..
Activate the virtual environment
$ source bin/activate
Install django and and postgres binary
$ pip install django psycopg2-binary
Start django Project
$ django-admin startproject djangoappYou should have a directory structure like this
Change directory into Project
$ cd djangoapp
You directory structure should look similar to this
~/django/db/: should contain docker-compose file for postgres db
~/django/djangoapp/: should contain djangoapp (project) and manage.py (dango project management script).
~/django/djangoapp/djangoapp: should contain __init__.py, asgi.py, settings.py, urls.py, wsgi.py.
Adjusting the project settings
First change the ALLOWED_HOSTS section to allow the your Host and other hosts you want
$ vi settings.py
Next change the DATABASES section to look like this
Use you Vm's ip as theHOST
Lastly, create a STATIC_ROOT variable to store all static files from your projects and apps
Change to the directory where we have the manage script
$ cd ..
Migrate the changes to the database
$ python manage.py makemigrations
$ python manage.py migrate
Create a super user in the database
$ python manage.py createsuperuser
Collect all the static files in your project
$ python manage.py collectstatic
Packaging the project into Docker
Change directory to where the project root folder
Create a requirements.txt
file using pip
$ pip freeze > requirements.txt
This will create a requirement.txt file that will contain all the needed dependencies to run the app int the contanier.
Due to an issue withbackports.zoneinfo
library in python images from docker. We will have to remove it from our requirements.txt
file.
$ vi requirements.txt
Your file should look something like this
asgiref==3.5.0
backports.zoneinfo==0.2.1
Django==4.0.2
psycopg2-binary==2.9.3
sqlparse==0.4.2
If your requirements.txt
doesn't have the backports.zoneinfo
ignore the next step.
delete the backports.zoneinfo==0.2.1
line and save the file
Your requirements.txt
should look something like this, unless you added other libraires for your app
asgiref==3.5.0
Django==4.0.2
psycopg2-binary==2.9.3
sqlparse==0.4.2
Create a Dockerfile
$ vi Dockerfile
Paste the following lines into the file
# syntax=docker/dockerfile:1
FROM python:3.9.6-alpine
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code/
COPY requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . /code/
This dockerfile will use the python image as the base image on which to build the django app. It will also use the requirement.txt
file to install the
necessary dependencies on the python image. It will also copy all the django project file into the python image.
Create a docker-compose.yml
file
$ vi docker-compose.yml
Paste the following lines into the file
version: "3.9"
services:
web:
build: .
container_name: django_app
command: python djangoapp/manage.py runserver 0.0.0.0:80
volumes:
- .:/code
ports:
- "80:80"
This docker-compose.yml
file will create a container based on the Dockerfile and will start the django app. It will also map the
port 80
from the container onto the port 80
on the vm.
80
on the VM isn't mapped to any application Bring the django-web-app
container up
docker-compose up -d
Confirm all container is up an running
docker-compose ps -a
Open up a browser to check if django is up
Use the VM's ip without any IP
http://vm-IP/
Congratulations, we now have the Django running in a container on our vm
Conclusion
We just learnt how to package our django-app and it's db into a container. This scenario would help you deploy your app onto any environment without any worries about infrastructure,
O.S or other problems faced with deploying traditional apps. There will be a follow up tutorial on using minikube
- a single host kubernetes cluster, to demonstrate
scalability with our django-app. Also, we will do a benchmark test on a django-app running in a container and a vm to weigh out our options.