Build an API System With Python Django Rest Framework — Part 1: Dockerize Python Django

Keith
The Startup
Published in
7 min readSep 13, 2020
Photo by Faisal M on Unsplash

It is a series of simple guide:

  1. Build an API System With Python Django Rest Framework — Part 1: Dockerize Python Django
  2. Build an API system with Python Django Rest Framework — Part 2 : Generate App & Create Models

I am planning to build a website to let me filter and search for some mobile game pets information, this web should provide below functions:

  • An admin panel for me to manage those “pets” data
  • A frontend to show list of these pets data
  • In frontend, a filter for me to search different pets by their attribute

In this article series, I will go through the steps to help us build up an API system. For other functionality, I will make some more articles later.

My career are all about C# / php / Java. So this time I hope to try something new (to me). So I plan to use python Django + Django Rest Framework. Because I heard that it is good and speedy for building API services, which will be consumed by frontend web client through JS.

These API services & some simple frontend pages by Django will be dockerized. Also I am thinking to try on swagger, which can help me to automate any API documentation things. But it will be included in my other articles in the future.

For frontend pages, I am still struggling on which JS lib I should try. Now my options are Reactjs, Angular, or vue.js. When I decided, I will make an article for it.

For databases, I would try graph DB such as neo4j, for storing the “pets” relationship. And sqlite or some NoSQL for storing each pets attributes.
(Updated on 2020–09–17: I would use MongoDB with Django. It will require some steps before integrating with Django, so I will make an article for it)

Let’s get started !

Prepare Docker Environment

In this part, we will prepare our docker things. It will be much easier for deploying to other hosting or cloud. And we don’t need to worry about the dependency on different platforms. Also docker can isolate the environment for the system we are going to develop.

First, create a folder somewhere in your local PC. I create a folder named tutor_medi.
Yes, maybe you aware, I am using windows, but it should be similar even you are using macOS or others.

Then, Create a file name Dockerfile inside the directory.

tutor_medi
└── Dockerfile

It is a file to indicate docker, how you want to build your image.

Then edit this Dockerfile with below content:

FROM python:3.8.5-alpineENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
RUN mkdir src
#prepare virtual env
RUN python3 -m venv venv
#install django and DRF
COPY requirements.txt /code/
RUN sh -c "source ./venv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt"#at last, copy the source code into image
COPY src/ /code/src/

In this Dockerfile, it tell the docker to do some tasks one by one. And after finish all command, it will generate an docker image.

RUN python3 -m venv venv

The line above is to create python virtual env. It is useful because all the dependencies of this projects will be stored inside. And in the future, you can create some other new projects with their owned virtual env, so that projects will not interfere with each others.

RUN sh -c “source ./venv/bin/activate && pip install — upgrade pip && pip install -r requirements.txt”

This line is to install any python lib listed in the requirements.txt by PyPI. We will need to create the requirements.txt.

Now, create requirements.txt in directory and put below content in the file:

djangorestframework

It is that simple! When installing the lib djangorestframework , prerequisite dependencies will be checked and installed if any.

PS: requirements.txt can also include other “requirements.txt”. This is useful if you want to put same set of dependencies together. You can check more info here.

At last, remember to create a folder src in side tutor_medi

Current file structure:

tutor_medi
├── src
├── requirements.txt
└── Dockerfile

You are now ready to build the docker image ! Make sure your docker daemon is up. And open a command prompt, enter the tutor_medifolder. And run below command to build it.

docker image build -t tutor-medi:v1 .

When you click enter, you would see a each command listed in Dockerfile is getting executed one by one. And the image is built with given name tutor-medi, and tagged with v1. You can check it by command :

docker images

You will see something like this:

REPOSITORY   TAG   IMAGE ID      CREATED           SIZE
tutor-medi v1 xxxxxxxxx 3 minutes ago 105MB

Startup the container with our image

Next step, lets fire up the container first. Then we can use python command to generate the project INSIDE our container environment.

docker run -v <yourpath>/tutor_medi/src:/code/src -it tutor-medi:v1 /bin/sh

Above command will use the image we built to start up a container. Meanwhile, mounting our tutor_medi/src in local storage toward /code/src in container storage(This folder was created inside our Dockerfile )

If successful, suppose now you are inside your container and start typing linux command.

Reminder: any files created or modified inside /code/src will be affecting our local file storage <yourpath>/tutor_medi/src

Generate Django project boilerplate code

Here, we will use the python Django helper to generate the project & app template. So we don’t need to create each file and content one by one.

If you are not inside the container, start it up again with our previous step. Once inside container, type below command:

/ # cd /code/src 
/code/src/ # source /code/venv/bin/activate
(venv) /code/src/ # django-admin startproject proj_medi

Be ensured you use 1st line to enter /code/src directory.

The 2nd line is very important, it change your current environment to use the one we created before. ( remember the venv we created through Dockerfile?) After changed, you can see the (venv) in front of your current command line.

The 3rd line command with django-admin is to use Django helper to generate a project boilerplate. Now you will see :

/code/src/proj_medi
├── proj_medi
│ ├── wsgi.py
│ ├── urls.py
│ ├── settings.py
│ ├── asgi.py
│ └── __init__.py
└── manage.py

manage.py is a helper same as django-admin EXCEPT it will use the environment / configuration within this project, when necessary.

urls.py and settings.py are the files we will play with in coming development.

Now, you can check your local file storage under <yourpath>/tutor_medi/src and you will see those files generated by django-admin, is persistent in this directory, even after you exit the container.

Prepare docker-compose for startup the container in the future

Now we have our Dockerfile, docker image and django boiletplate prepared. Next we will setup the basic docker-compose.yml , which is for starting up container with all the necessary configuration.

It is especially useful because we don’t need to type a long command with argument to startup the container each time. Also we may combine various other images and startup together, so we need docker-compose.

Create a file docker-compose.yml inside our working directory tutor_medi

tutor_medi
├── src
│ └── ...
├── requirements.txt
├── docker-compose.yml
└── Dockerfile

Edit docker-compose.yml with below content:

# Specifies which syntax version of Docker compose
version: '3'
services:
web:
build: .
container_name: tutor_medi_web
working_dir: /code/src/proj_medi
volumes:
- ./src:/code/src
ports:
- "9090:8000"
command: >
sh -c "source ../../venv/bin/activate &&
python manage.py makemigrations &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"

Make sure the working_dir: /code/src/proj_medi matching the project name you created with django-admin

python manage.py makemigrations &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000

The commands above do 3 things.

  1. Ask django to check any new changes in our model files ( we don’t have any at this moment)
  2. Ask django to apply the changes to our database if any
  3. Startup the python hosting with 8000 port

One thing to be careful is, manage.py runserver is only suitable for our development. DO NOT use in production environment according to the info here:

Ok, now our docker-compose.yml is ready, let’s give it a try. Make sure you already install docker compose, please find more information here:

Ensure you are now in same directory of docker-compose.yml, and execute below command:

docker-compose up

It will startup a container and the python hosting should be already started after a while. We can try to access it through web browser in http://localhost:9090/

You will see the django default homepage now!

Next article I will start to dive into django & its database configuration.

It is my first time writing article for coding, please feel free to let me know any reference missed or better way to do the coding above!

Modified on 2020–09–17:

I change the Dockerfile, docker-compose.yml to ensure those command using venv . Also for the command related to django-admin, I added a step to change to our created venv first.

--

--