Django REST Framework - 1. Dockerize Your  Project

Django REST Framework - 1. Dockerize Your Project

A step-by-step guide to set up Django Rest Framework Project with Docker and Github.

·

7 min read

Django projects not only depend on Python requirements but also many system requirements, such as a web server, database, operating system, etc. When developing a Django project, you need to ensure that all environments and all developers will have all the same requirements installed. One way to keep those dependencies in sync is to use Docker. With Docker, we can have different versions of the database, web, or other servers required individually for each project. To learn more about docker, you can refer Explore Docker.

What you’ll learn:

  • How to set up Django Rest Framework with Docker and GitHub.
  • How to use docker and docker-compose.
  • Create a project and set your app running.
  • Basic git commands.

Let's get started...

  1. Set up a new GitHub Project

    Before you get started, make sure you have a GitHub account and SSH authentication between your computer and GitHub.

    Log in to your GitHub, Now create a new repository of your choice, and clone the project to your system. Once you clone your project, Open your project in your favorite IDE.

    Screenshot from 2021-10-13 16-39-34.png

  2. Add Requirements file

    Create a new file, called requirements.txt, as shown below. It is used for specifying what python packages are required to run the project. Screenshot from 2021-10-13 16-39-51.png

  3. Create a Dockerfile

    Now that we have created our project on GitHub and cloned it to our local machine, we can go ahead and create a docker file.

    A Dockerfile is simply a file that contains a list of instructions or dependencies for Docker to build a docker image. Now let's create our Dockerfile. Simply create a new file at the root of our project called "Dockerfile". The file needs to begin with capital D and doesn't have any extension at the end. Screenshot from 2021-10-13 16-40-05.png

    The first line of the Dockerfile is the image, that you are going to inherit from your Dockerfile. So basically with Docker, you can build images on top of other images.

    We are going to create our Dockerfile with Python 3.7 image. You can visit https://hub.docker.com to find a list of available images. There are various images available Images, the one we are going to use is alpine3.7

    Create an empty folder called app, because this will be required by our Dockerfile, and enter the commands as shown below.

    Screenshot from 2021-10-13 16-35-20.png We'll go through the above commands one by one.

    1. FROM python:3.6-alpine - This is the Python image that we are going to inherit from our Dockerfile. Alpine image is a very lightweight and minimal image that runs Python.
    2. MAINTAINER Pradeep - This is optional, but it is used to know who is maintaining the project.
    3. ENV PYTHONUNBUFFERED 1 - This is recommended when running Python in docker containers. The reason for this is that it doesn't allow python to buffer the outputs. It just prints them directly, and this avoids any complications when running Python applications.
    4. COPY ./requirements.txt /requirements.txt - Copy our local requirements JSON, to our docker image.
    5. RUN pip install -r /requirements.txt - This will install our requirements from a .txt file using PIP.
    6. RUN mkdir /app - This creates an empty directory within our docker image to store our application's source code.
    7. WORKDIR /app - Switches to the default directory, unless we specify otherwise.
    8. COPY ./app /app - Copy the app folder from our local machine to our image, which consists of our project code.
    9. RUN adduser -D user - This will create a user that's gonna run our application on Docker. For security purposes, if we don't do this, then the image will run our application with a root account. If somebody compromises our application, they can get root access, which is very dangerous.
    10. USER user - Switch to that user.
  4. Docker Compose Configuration

    Docker-compose is a tool that allows us to run our docker images and manage services configuration (e.g. Postgres Service, Redis Service) for our project.

    Create a new file named "docker-compose.yml" on the root of your project and enter the commands as shown below. This is a .yml file that contains the configuration of all the services that make up our project.

    Screenshot from 2021-10-13 20-47-11.png

    • version: "3" - Version of the docker compose.
    • services: - Services that make up our project. Right now we only need one service for our python Django application.

      • app: - Service called app

        • build: - Build section of the configuration.
          • context: . - We are sending context to "." which is our current directory.
        • ports:
          • -"8000:8000" - Map our project on port 8000 on our host to 8000 on the image.
        • volumes: - Whenever you change something in your project, it automatically updates changes in the container in Real-Time, so you don't need to restart the containers to reflect the changes.
          • ./app/app - Maps app directory of our project to app the directory in our docker image.
        • command: > - Command that is used to run our application on our docker container.

          • sh -c "python manage.py runserver 0.0.0.0:8000" - shell command to run our application. This will start our development server on port 8000, available on all IP Address's that run on the container.
  5. Build Your Project:

    Once you are done, we will build our project. To do this, go to your terminal and run "docker-compose build". This will build our image using the docker-compose configuration as shown below.

     deep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ docker-compose build
     Building app
     Step 1/10 : FROM python:3.6-alpine
     3.6-alpine: Pulling from library/python
     a0d0a0d46f8b: Pull complete
     c11246b421be: Pull complete
     ef6741e6e9c4: Pull complete
     9d6fa827d5ce: Pull complete
     4fbd2be606d8: Pull complete
     Digest: sha256:410328ff242994d24bbea32cb0ddc4c4ffda5a7a4f6e2d2f29e6821cd6d85daf
     Status: Downloaded newer image for python:3.6-alpine
     ---> 427f9ac9663d
     Step 2/10 : MAINTAINER Pradeep
     ---> Running in eed76128e5b1
     Removing intermediate container eed76128e5b1
     ---> 81cba679f259
     Step 3/10 : ENV PYTHONUNBUFFERED 1
     ---> Running in f36a150c75ca
     Removing intermediate container f36a150c75ca
     ---> 19b400033946
     Step 4/10 : COPY ./requirements.txt /requirements.txt
     ---> cdc01c22d14d
     Step 5/10 : RUN pip install -r /requirements.txt
     ---> Running in 9a149ac56dc9
     Collecting Django<2.2.0,>=2.1.3
     Downloading Django-2.1.15-py3-none-any.whl (7.3 MB)
     Collecting djangorestframework<3.10.0,>=3.9.0
     Downloading djangorestframework-3.9.4-py2.py3-none-any.whl (911 kB)
     Collecting pytz
     Downloading pytz-2021.3-py2.py3-none-any.whl (503 kB)
     Installing collected packages: pytz, djangorestframework, Django
     Successfully installed Django-2.1.15 djangorestframework-3.9.4 pytz-2021.3
     Removing intermediate container 9a149ac56dc9
     ---> 173b54cb8ef7
     Step 6/10 : RUN mkdir /app
     ---> Running in f57bcbd80b0c
     Removing intermediate container f57bcbd80b0c
     ---> 521b28d021be
     Step 7/10 : WORKDIR /app
     ---> Running in 902c1d6ad910
     Removing intermediate container 902c1d6ad910
     ---> 4d7bb493337e
     Step 8/10 : COPY ./app /app
     ---> 4bd171515fcc
     Step 9/10 : RUN adduser -D user
     ---> Running in d93592b78136
     Removing intermediate container d93592b78136
     ---> b48d5204605e
     Step 10/10 : USER user
     ---> Running in a29b40457e7e
     Removing intermediate container a29b40457e7e
     ---> b82aab704169
     Successfully built b82aab704169
     Successfully tagged drf-guide_app:latest
    
     # You can also verify this by
     pradeep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ docker images
     REPOSITORY                                      TAG                 IMAGE ID       CREATED              SIZE
     drf-guide_app                                   latest              b82aab704169   About a minute ago   82.7MB
    
  6. Creating Django Project:

    Using Docker Compose, we executed commands on our image that contains the Django dependencies. Now we'll create the projects files that we need for our app. Let's create our project. Go to your terminal and execute ==> docker-compose run app sh -c "django-admin.py startproject app ."

     # Start Project
     deep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ docker-compose run app sh -c "django-admin.py startproject app ."
    Creating network "drf-guide_default" with the default driver
     # Start App
     deep@Latitude-5590:~/Desktop/DRF/DRF-Guide/app$ docker-compose run app sh -c "python manage.py startapp myapp"
    

    Add myapp to INSTALLED_APPS in settings.py

     INSTALLED_APPS = [
         'django.contrib.admin',
         'django.contrib.auth',
         'django.contrib.contenttypes',
         'django.contrib.sessions',
         'django.contrib.messages',
         'django.contrib.staticfiles',
         'myapp',
     ]
    

    Now that we have created our Django project, We can verify by running ==> " docker-compose run app sh -c "python manage.py runserver".

     deep@Latitude-5590:~/Desktop/DRF/DRF-Guide/app$ docker-compose run app sh -c "python manage.py runserver"
     Performing system checks...
     System check identified no issues (0 silenced).
     You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
     Run 'python manage.py migrate' to apply them.
     October 13, 2021 - 16:55:13
     Django version 2.1.15, using settings 'app.settings'
     Starting development server at http://127.0.0.1:8000/
     Quit the server with CONTROL-C.
    

    Screenshot from 2021-10-13 22-32-23.png

    Now that our setup is successful, We can go ahead and commit that to git.

     pradeep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ git add .
    pradeep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ git commit -am 'Setup Docker and Django Project'
    [main 3f9bac5] Setup Docker and Django Project
    8 files changed, 200 insertions(+)
    create mode 100644 Dockerfile
    create mode 100644 app/app/__init__.py
    create mode 100644 app/app/settings.py
    create mode 100644 app/app/urls.py
    create mode 100644 app/app/wsgi.py
    create mode 100755 app/manage.py
    create mode 100644 docker-compose.yml
    create mode 100644 requirements.txt
    pradeep@Latitude-5590:~/Desktop/DRF/DRF-Guide$ git push origin main
    Counting objects: 12, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (11/11), done.
    Writing objects: 100% (12/12), 3.12 KiB | 1.04 MiB/s, done.
    Total 12 (delta 0), reused 0 (delta 0)
    ceaa4f6..3f9bac5  main -> main
    

UPCOMING...

  • Setup continuous integration & deployment (CI / CD) with Travis CLI and Github.
  • Test-driven development and deployment following Pep 8 guidelines.

Thank you for Reading.

Did you find this article valuable?

Support Pradeep by becoming a sponsor. Any amount is appreciated!