September 15, 2019

Minimal Timekeeping REST Service with Django, Postgres and Docker-Compose

I wanted to play around with the Django framework and with Docker-Compose. Here I note down the steps that I think are most relevant for this minimalistic example project. The project is on github under the name Thymely :)

I have read the following articles to start this project:

Start Project

pipenv install django
pipenv install djangorestframework
pipenv install psycopg2-binary
pipenv shell
django-admin startproject thymely

Edit settings.py and add 'rest_framework' to installed apps.

Switch zu Postgres

Edit settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db', # set in docker-compose.yml
        'PORT': 5432 # default postgres port
    }
}

Docker-Compose

Add Dockerfile

# Pull base image
FROM python:3.7-slim

# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /app

# Install dependencies
RUN pip install pipenv
COPY Pipfile Pipfile.lock ./
RUN pipenv install --system

# Copy project
COPY . .

Add docker-compose.yml

version: '3.7'

services:
  db:
    image: postgres:10.1-alpine
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data/
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - 8000:8000
    depends_on:
      - db

volumes:
  postgres_data:

Before starting the docker container I need to start my docker deamon, which I have disabled at times, because it interferes with the wifi on the german long distance train. See this post. The command is 'sudo systemctl start docker'. Also helpful is the option to debug into the docker container with 'docker exec -it <container name> /bin/bash'.

I also had problems with the docker-compose cache so the option to build the image without cache was helpful: 'docker-compose build --no-cache'. Don't forget to rebuild the docker image with docker-compose after adding any dependency. Like eg. the postgres driver.

Building with multi container project

docker-compose build

Migrating the database

docker-compose run web python manage.py migrate --noinput

Create superuser

docker-compose run web python manage.py createsuperuser

Starting the multi container project

docker-compose up -d

Stoping the project

docker-compose down

Work Hours App

An app in the context of Django can also be thought of as a module or component in other frameworks or architectures. Create a new app (module / component) with 'django-admin startapp work_hours'. The new app needs to be registered in the settings.py file. Create at least the following object in the app:

  • model
  • serializer
  • view
  • url

and register the url and the model of your app in the admin.py and the project url.

Run the makemigrations ('docker-compose run web python manage.py makemigrations') and migrate ('docker-compose run web python manage.py migrate --noinput') commands within the container.