Dockerizing a Python Django Web Application
Having many Django applications under my belt, either client or personal projects - I would like to publish them to the web to display to my future clients or employers. Not a coincidence that I learned Docker the other day, it will come in handy.
1 Create and Dockerize a Django Application
1.2 Create a Django app
If you don't want to setup basic Django app together - clone mine from here.
cd Documents mkdir djangodocker cd djangodocker django-admin startproject djangodocker cd djangodocker python3 manage.py runserver # visit http://127.0.0.1:8000/ # C-c C-c to kill the running process cd .. python3 -m venv venv source env/bin/activate cd djangodocker pip list pip install django pip freeze > requirements.txt
1.3 Create a Docker image
Create Dockerfile
(without any file extensions, and with the D being capital)
close to your manage.py file. This file will contain commands and instructions
to assemble our IMAGE
.
Whatever we put in it - docker will run through each of these commands and run through each them.
Result will be an image prepared and ready to be run on a Docker Container.
Dockerfile contents:
# remove ALL the comments if you want to use the code below. FROM python:3.8-slim-buster # OS from docker hub WORKDIR /app #working directory of the OS created above COPY requirements.txt requirements.txt #copy across from our local dir over to the image RUN pip3 install -r requirements.txt COPY . . #copy everything from current dir to working dir (/app) CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"] #m0000 making our app externally visible from outside of the container
Create .dockerignore
file to exclude any folders you want. .venv for
example.
.dockerignore contents:
*/venv
To build an image, run this command while inside of the folder in which manage.py and Dockerfile is present. –tag basically give a name to the image. Don't forget the . at the end.
docker build --tag python-django .
It will take up to ~30 seconds. The image will be visible in "Docker Desktop" app.
1.4 Create a Docker container
A single command will do it.
docker run --publish 8000:8000 python-django # or to run in detached(run in the background without occupying the terminal) mode docker run -d --publish 8000:8000 python-django
Open up Django Desktop - you will see the container we have just created in "Container tab".
So now we are running a django application in a docker container. Go
to a browser, 127.0.0.1:8000
to see your django app running.
2 Upload Docker Image to Docker Hub
- Go to Docker hub and create an account there.
- Setup the authentication on your own. Setting up gpg, password store manager
and etc is the most tricky part for me now. Somehow I made it work for
myself. Attaching some error messages and useful links.
- Login to docker in your terminal like so.
- Then do this.
- fix is this - https://www.biostars.org/p/9531985/ try logout, delete stuff, generate new gpg key, dont login through browser - login in terminal
Authentication should be ready and you should have cloned my django-docker-starter repository
First, after your login you have to tag your image before pushing:
docker tag image_name YOUR_DOCKERHUB_NAME/image_name
Then, you have to push it.
docker push YOUR_DOCKERHUB_NAME/image_name
For example:
docker tag django-docker-starter arvydasg/django-docker-starter docker push arvydasg/django-docker-starter
3 Deploy with Docker on Linode
3.1 Creating a platform to work on
Create the machine.
- Create a simple Linode node(choosing linode just because I have free credits for it, choose any other provider you want). In my case I have chosen Linode 2GB plan and a Docker image. ($10/month)
- When your Docker node is running, connect to it through SSH in it.
3.2 Run the container
Let's pull the container we have created and pushed to Docker Hub in the previous steps.
docker pull arvydasg/django-docker-starter:latest
Adding :latest tag at the end. It is basically a version. It's useful to be able to choose a different version.
To run this container(a web app), we do this.
docker run -t -d -p 9999:8000 arvydasg/django-docker-starter:latest
We have specified additional switch -p
which stands for ports
.
9999:8000.
- 8000 is the port of the django app (specified in Dockerfile)
- 9999 is the port on which we want to reach the
Basically saying match port 80 with port 80.
Now grab your IP address from your linode dashboard, enter it in the browser.
That container not only has all the cpu, memory etc, but also all the settings the creator has applied(debian, nginx, website files, etc), web configuration, all prerequisites, all dependencies.. packaged together in a neat little package. And you can run it on any linux machine.
3.3 Some other Docker commands
docker ps -a docker images -a docker start <name of the image or the ID> docker stop <name of the image or the ID> curl localhost:9999 -v docker rm -f <name of the image or the ID> docker rmi <name of the image> docker stats docker port <name of the container> # access the docker container's bash docker exec -it mycontainer bash # delete or remove all docker data like containers, images and volumes docker rm --force `docker ps -qa` docker rmi --force `docker images -aq` docker volume prune