The Container Configuration Manifest

My Problem

As a web developer working with docker i use the docker hub and many popular container distributions on a daily base.

While learning how to use many popular distributions like redis, solr, postgres or elasticsearch, i noticed a few painful steps in the process of configuring those images to my needs.

Most of those popular images come with a default configuration making them usable out of the box. This is great for basic usage but most of the time it’s not enough when it comes to optimization of the setup. When it comes to more advanced use but not as far as building a custom image, configuration through environment variables is a common practice.

Let’s take a look at some examples.

Examples

Postgres

The postgres configuration is pretty straight forward and documented. The first few times i used this image i still had to lookp up some environment variables by scrolling thru that endless docker hub readme-file.

version: "3"

services:
  db:
    image: postgres:10
    environment:
      POSTGRES_DB: docker
      POSTGRES_USER: docker
      POSTGRES_PASSWORD: docker
    volumes:
      - db:/var/lib/postgresql/data

Django Application

Now let’s have a look at a more complex example. The following service defines a Django applications environment definition.

version: "3"

services:
  backend:
    image: docker.team23.de/team23/periscope_backend:${CI_COMMIT_TAG}
    environment: &djangoenv

      ALLOWED_HOSTS: "backend.domain.com"
      FRONTEND_BASE_URL: "https://frontend.domain.com"
      PDF_GENERATION_ENDPOINT: 'http://pdf:3000/generate'

      DEBUG: NO
      ASSETS_DEBUG: NO
      SITE_ID: 1
      INTERNAL_IPS: "::1,127.0.0.1"
      SECRET_KEY: "abcdefghijklop12345"

      DATABASE_ENGINE: django.db.backends.postgresql_psycopg2
      DATABASE_NAME: docker
      DATABASE_USER: docker
      DATABASE_PASSWORD: docker
      DATABASE_HOST: db
      DATABASE_PORT: 5432

      CORS_ORIGIN_WHITELIST: "frontend.domain.com"
      CORS_ORIGIN_ALLOW_ALL: YES
      CORS_ALLOW_CREDENTIALS: YES

      # EMAIL_BACKEND: $EMAIL_BACKEND
      # EMAIL_HOST: $EMAIL_HOST
      # EMAIL_PORT: $EMAIL_PORT
      # EMAIL_HOST_USER: $EMAIL_HOST_USER
      # EMAIL_HOST_PASSWORD: $EMAIL_HOST_PASSWORD

If i give the project to a colleague or customer they might have a basic knowledge of what those variables mean - dependent on how i named them - and how there value effects the application. To be sure how to configure it they need configuration of those variables or at least a basic insight into the source code.

In this example this would still not be enough because besides being able to change the database engine used by django the application would still not work with a MySQL database because it uses fields that are not available in MySQL.

Some of you might say “why not just put comments next to your definition?”

My Solution

Definition

Manifests