Dockerizing a Python Django Web Application

What is Docker, Anyway?

“Docker is an open platform for building, shipping and running distributed applications. It gives programmers, development teams, and operations engineers the common toolbox they need to take advantage of the distributed and networked nature of modern applications.”

Prerequisites

Setting Up a Django web application

.
├── requirements.txt # < Python module list
└── martor_demo # < Django Project root
├── app # < App code
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ ├── models.py
│ ├── templates
│ ├── urls.py
│ └── views.py
├── manage.py # < Django management tool
└── martor_demo # < Django main settings
├── settings.py
├── urls.py
└── wsgi.py
$ python -m venv venv
$ echo venv/ >> .gitignore
$ source venv/bin/activate
$ echo martor >> requirements.txt
$ echo gunicorn >> requirements.txt
$ pip install -r requirements.txt
$ git add .gitignore requirements.txt
$ git commit -m "added martor and gunicorn"
$ git push origin master
$ cd martor_demo
$ python manage.py runserver
You have 18 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.
$ python manage.py makemigrations
$ python manage.py migrate

Testing in Django

# app/testPosts.py

from django.test import TestCase
from app.models import Post


class PostTestCase(TestCase):
def testPost(self):
post = Post(title="My Title", description="Blurb", wiki="Post Body")
self.assertEqual(post.title, "My Title")
self.assertEqual(post.description, "Blurb")
self.assertEqual(post.wiki, "Post Body")
$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Destroying test database for alias 'default'...
$ python manage.py check --deploy

Static vs Dynamic Files

# martor_demo/settings.py

. . .

STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
$ python manage.py collectstatic

Style checker

$ pip install flake8
$ flake8 . --max-line-length=127

Continuous Integration

$ git add martor_demo/settings.py app/testPosts.py
$ git add static
$ git commit -m "add unit test and static files"
$ git push origin master
sem-version python 3.9
checkout
mkdir .pip_cache
cache restore
pip install --cache-dir .pip_cache -r requirements.txt
cache store
sem-version python 3.9
checkout
cache restore
pip install --cache-dir .pip_cache -r requirements.txt
cd martor_demo
python manage.py makemigrations
python manage.py migrate
python manage.py test
cd martor_demo
python manage.py check --deploy
pip install flake8
flake8 martor_demo/ --max-line-length=127

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store