Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Docker

Based Dev Envs

About me:

René Olivo

Has been around since GIFs were popular. Loves front-end development, learning, sharing, and beer (a bit too much).

Contents

Why you should be using

Docker

Your software stack can be quite complex

Python Logo PostgreSQL Logo Redis Logo Javascript Logo

And your team can be very diverse and specialized

Developer Developer Developer Developer

This can lead to a fractured development process

Fractured Development Team

And this is where Docker shines!

It can provide a group of containers with all the services required by the project, delivering a development environment that everyone in the team can benefit from.

Docker Container
Riding solo developer tumbleweed
PC Services bloat

Docker can help you reduce PC bloat!

How can teams, integrate Docker into their Development Process?

Running One Off commands:

  docker run -it --rm \
    --user "$(id -u):$(id -g)" \
    -v "$PWD":/usr/src/app \
    -w /usr/src/app \
    django django-admin.py startproject project_name

Defining our environemnts

We can define our environment with the help of these two types of files:

Dockerfile document

Dockerfile

Defines a container and sets it in an known state.
For example, install a service and configure its default values.

docker-compose.yml document

docker-compose.yml

Simplifies the startup process of all the containers, the ports bindings, and the disk volumes to synchronize locally.

Dockerfile

FROM      django:1.9.2
ADD       ./requirements.txt /usr/src/app/requirements.txt
WORKDIR   /usr/src/app
RUN       pip install -r requirements.txt
ADD       ./manage.py /usr/src/app/manage.py

docker-compose.yml

hello_django_app:
  build: .
  volumes:
    - ./hello_django:/usr/src/app/hello_django
  ports:
    - 8000:8000
  command: python manage.py runserver 0.0.0.0:8000

Creating and starting the services


docker-compose build
docker-compose up

Linking a Postgres DB

hello_django_app:
  build: .
  volumes:
    - ./hello_django:/usr/src/app/hello_django
  ports:
    - 8000:8000
  command: sh ./init.sh
  links:
    - hello_django_db

hello_django_db:
  image: postgres:latest
  ports:
    - 5432:5432
  environment:
    - POSTGRES_DB=hello_django_db
  extends:
    file: env-vars.yml
    service: hello_django_env_vars

Linking a Postgres DB

hello_django_app:
  build: .
  volumes:
    - ./hello_django:/usr/src/app/hello_django
  ports:
    - 8000:8000
  command: sh ./init.sh
  links:
    - hello_django_db

hello_django_db:
  image: postgres:latest
  ports:
    - 5432:5432
  environment:
    - POSTGRES_DB=hello_django_db
  extends:
    file: env-vars.yml
    service: hello_django_env_vars

Linking a Postgres DB

hello_django_app:
  build: .
  volumes:
    - ./hello_django:/usr/src/app/hello_django
  ports:
    - 8000:8000
  command: sh ./init.sh
  links:
    - hello_django_db

hello_django_db:
  image: postgres:latest
  ports:
    - 5432:5432
  environment:
    - POSTGRES_DB=hello_django_db
  extends:
    file: env-vars.yml
    service: hello_django_env_vars

Private environment file

# env-vars.yml
hello_django_env_vars:
  environment:
    - POSTGRES_USER=admin
    - POSTGRES_PASSWORD=super-secret-password

Python settings

# settings.py
from os import environ

# ...

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'hello_django_db',
    'USER': environ.get('HELLO_DJANGO_DB_ENV_POSTGRES_USER'),
    'PASSWORD': environ.get('HELLO_DJANGO_DB_ENV_POSTGRES_PASSWORD'),
    'HOST': environ.get('HELLO_DJANGO_DB_PORT_5432_TCP_ADDR'),
    'PORT': environ.get('HELLO_DJANGO_DB_PORT_5432_TCP_PORT'),
  }
}

When in doubt: printenv


docker-compose run hello_django_app printenv


* The container must be up when running this command

Linking a Postgres DB

hello_django_app:
  build: .
  volumes:
    - ./hello_django:/usr/src/app/hello_django
  ports:
    - 8000:8000
  command: sh ./init.sh
  links:
    - hello_django_db

hello_django_db:
  image: postgres:latest
  ports:
    - 5432:5432
  environment:
    - POSTGRES_DB=hello_django_db
  extends:
    file: env-vars.yml
    service: hello_django_env_vars

Waiting for other services to start

# init.sh
RUN until netcat -z -v localhost 5432; do
  echo "$(date) - waiting for postgres...";
sleep 1;

python ./manage.py makemigrations
python ./manage.py migrate auth
python ./manage.py migrate
python ./manage.py runserver 0.0.0.0:8000

Running commands inside services


docker-compose run hello_django_app python manage.py createsuperuser

Saving DB data outside the container

The data inside the DB container is stored there as long as the container is not rebuilt. If you need the data to persist, you can store it locally.

Saving DB data outside the container

# ./docker-compose.yml

hello_django_db:
  image: postgres:latest
  volumes:
    - ./db-data:/var/lib/postgresql/data
  ports:
    - 5432:5432
  environment:
    - POSTGRES_DB=hello_django_db
  extends:
    file: env-vars.yml
    service: hello_django_env_vars

Bringing in the front-end devs

We can add a container that provides Bower, SASS, and/or Gulp, etc.


# ./docker-compose.yml

node:
  image: digitallyseamless/nodejs-bower-grunt:0.12
  volumes:
    - ./bower.json:/data/bower.json
    - ./.bowerrc:/data/.bowerrc
    - ./hello_django/static/vendors:/data/hello_django/static/hello/vendors

Bringing in the front-end devs

And running it as such:



docker-compose run node bower install

Thanks for listening!

Questions: @rene_olivo