# One way to deploy python, django and friends.

My journey into the realm of docker started quite a while back. I was in a hurry. I needed something that just worked and I needed to deliver it *right now* - or preferably the day before.

So, naturally, I hacked together a build and deploy system. ...And then I just kept on using it.

Templates are a honking great idea
```sh
config/templates/
  docker-compose-template.yml
  docker-entrypoint-template
  Dockerfile-template
  gunicorn-template.conf
  nginx-template.conf
  nginx-template-local.conf
  project-variables-template
  tasks-template.py
  template-envs
```
And what do they look like? Basically like this:

```yaml
File: docker-compose-template.yml

version: '3.7'
services:
.
.
.
  ${APPSERVICE_NAME}:
    ${APPSERVICE_CONTAINER_NAME}
    entrypoint: /opt/services/${VOLUME_PREFIX}${VOLUME_NAME}/src/docker-entrypoint.sh
    command: gunicorn -c config/gunicorn/conf.py${RELOAD}--chdir ${APP_NAME} --bind :${APP_PORT} ${APP_NAME}.wsgi:application
    restart: unless-stopped
    build: .
    stdin_open: true
    tty: true
    security_opt:
      - seccomp:unconfined
    ports:
      - "${APP_PORT}"
    env_file:
      - project-variables.env
    volumes:
      - .:/opt/services/${VOLUME_PREFIX}${VOLUME_NAME}/src
      - ${VOLUME_PREFIX}static_volume:/opt/services/${VOLUME_PREFIX}${VOLUME_NAME}/static
      - ${VOLUME_PREFIX}media_volume:/opt/services/${VOLUME_PREFIX}${VOLUME_NAME}/media
    networks:
      default:
    depends_on:
      - ${MEMCACHED_NAME}
      - ${DBSERVICE_NAME}

```

*template-envs* provides the variables for substitution. This file is for the most part not checked into the VCS. If you do happen to check this file in you should take care to change the secrets in production.

And to write out the *docker-compose.yaml*? 
```sh
Contents of generate-deploy-files.sh
  source ./config/templates/template-envs
  .
  .
  .
  envsubst < "./config/templates/docker-compose-template.yml" > "docker-  compose.yml"
  .
  .
  envsubst '${WORKER_PROCESSES},${WORKER_RLIMIT_NOFILE},${WORKER_CONNECTIONS}' < "./config/templates/nginx-template.conf" > "./config/nginx/nginx.conf"
.
.
```
Finally, I've added a *Makefile* so that I don't have to type out the various build and clean commands.

```sh
Contents of Makefile
  #! /bin/bash
  .
  .
  define dev
        ./generate-deploy-files -r reload -d DEBUG
        docker-compose up -d --build $(c)
  endef
  .
  .
  debug: 
     $(write_rev)
     echo "debug" >> ${rev_path}/revision.txt
     $(dev)
  .
  .
  .
```

So, there it is - basically. Super easy, super flexible system that works well for single host environments. Maybe some day I'll extract the files out into a repo by them selves. 
