Docker

The Good, The Bad, The Ugly

John Epperson

What are we going to talk about?

  • Developer Types
  • The good parts
  • The bad parts
  • How to make the bad parts better
  • Links to some stuff you can use

Opinions Ahead

Let's Talk about Shiplane

  • I wrote Shiplane
  • I tried various tools and was not happy with the ecosystem. So I made Shiplane.
  • I will mention Shiplane in this presentation because I truly believe it solves some problems. There are potentially alternatives that you have every right to love. Please continue doing so.
  • I am merely telling you what I think. Please enjoy Shiplane.

Developer Camps

  • Pioneers - Are the first to arrive at a new tech. Immediately abandon the tech as soon as other people think it is cool. Pioneers are probably already moved on from Docker at this point.
  • Settlers - Typically arrive earlyish and start making tools that help make the ecosystem better. Are advocates for the technology during it's early days. Settlers typically don't show up unless a technology has a good use case.
  • Townsfolk - Late arrivers. Wait until a technology is proven AND tools are in place.

The Good

  • Docker is amazing in development
  • Docker improves consistency across environments
  • Docker improves Resiliency and Robustness of infrastructure
  • Docker makes it fairly easy to divide work appropriately, removing sys-admin work from your developers' plates while still giving them the flexibility to choose their own dependencies
  • Docker is in. It's a hot technology. You should at least be familiar with it as an engineer.

The Bad

  • Development Docker is slower than non-Docker development
  • Aliases don't work
  • How do I? (deploy, provision production, test, etc)

The Ugly

  • We implemented Docker and we have this problem that we never had before. Docker is !@#$@#
  • We went the Docker path and now we have a DevOps team doing just as much work as we were doing before...just now they're doing Docker.
  • I'm a small shop. There's no way I can risk the work and effort involved in switching over while I am juggling so many things already.

Making the Bad Parts Better

  • Development is Slower
    • Yep. It is. I personally think the tradeoff is worth it.
    • Your setup might be too slow. I find that development is only slightly slower.
  • Aliases don't work
    • There are tools to fix this!
  • Learning how to deploy or provision with Docker is hard. There are tools for this.

Consistent Docker Environment

  • Extract Reusable portions into anchors
  • Extract any commonly changed files into volumes
  • Use some version of wait_for for any services that you need to wait on (e.g. any package manager)
base: &base
  build:
    context: .
    args:
      - APP_NAME=${APP_NAME}
      - GITHUB_TOKEN=${GITHUB_TOKEN}
      - RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
  tty: true
  stdin_open: true
  env_file: .env
  depends_on:
    - db
    - redis
  volumes:
    - ./:/var/www/example
    - /var/www/example/tmp/
    - bundle:/usr/local/bundle

app:
  <<: *base
  container_name: 'example-app'
  image: example_base:latest
  command: dockerize -wait http://bundler:23480 -wait http://yarn:23480 -timeout ${DEPENDENCY_TIMEOUT} bin/start_development_web_server
  ports:
    - '${HOST_PORT}:3000'

# workers:
# webpacker:
# test:
# bundler:
yarn:
  <<: *base

Extract Reusable portions into anchors

Extract any commonly changed files into volumes

services:
  base: &base
    ..
    volumes:
      - ./:/var/www/example
      - /var/www/example/tmp/
      - bundle:/usr/local/bundle

  app:
    <<: *base
    ..

  # workers:
  # webpacker:
  # test:
  # bundler:
  # yarn:

  db:
    image: postgres:11.3
    volumes:
      - postgresdata:/var/lib/postgresql/data
      - postgresconfig:/etc/postgresql
      - postgreslog:/var/log/postgresql
      - ./:/var/www/example

volumes:
  bundle:
  postgresdata:
  postgresconfig:
  postgreslog:

Use some version of wait_for for any services that you need to wait on (e.g. any package manager)

app:
  <<: *base
  command: >
    dockerize -wait http://bundler:23480 -wait http://yarn:23480
    -timeout ${DEPENDENCY_TIMEOUT} bin/start_development_web_server

workers:
  <<: *base
  command: dockerize -wait http://bundler:23480 -timeout ${DEPENDENCY_TIMEOUT} bin/start_sidekiq

webpacker:
  <<: *base
  command: dockerize -wait http://bundler:23480 -wait http://yarn:23480 -timeout ${DEPENDENCY_TIMEOUT} bin/start_docker_webpacker_server

test:
  <<: *base
  command: dockerize -wait http://bundler:23480 -wait http://yarn:23480 -timeout ${DEPENDENCY_TIMEOUT} bin/setup_test_env
  environment:
    - NODE_ENV=test
    - RAILS_ENV=test

bundler:
  <<: *base
  command: bin/update_bundle

yarn:
  <<: *base
  command: bin/update_yarn

Some More Docker Development Tips

  • Put ALL of your dependencies into your compose file
  • If you might need to interact with a debugger or runtime environment, enable tty in the appropriate container (probably your app container):
  • Make your service ports configurable:
services:
  app:
    tty: true
    stdin_open: true
services:
  db:
    environment:
      - POSTGRES_PASSWORD=${DATABASE_PASSWORD}
      - POSTGRES_USER=${DATABASE_USERNAME}
    ports:
      - '${HOST_POSTGRES_PORT}:5432'

  webpacker:
    ports:
      - '${HOST_WEBPACKER_PORT}:3035'

  app:
    ports:
      - '${HOST_PORT}:3000'

Addressing the Ugly

  • Bad Implementations
    • This isn't anything new. We deal with this all the time as developers. Refactor time. It's time to refactor processes and tools in this case, but you know how to do this!
  • We just created a new junk drawer!
    • I made Shiplane to solve this problem.
  • Small shop with no time to learn this new technology
    • It's the wild west. It's ok to be a townie and wait until things are more settled down.

Retrospecting

Who is this Guy?

Github:

Shiplane:

Twitter:

Email:

Charlotte Devs Slack:

kirillian

https://github.com/kirillian/shiplane

@kirillian

john.epperson@rockagile.io

@kirillian

HIRE US!

Questions

(With cute kid pics!)

Docker

By John Epperson

Docker

  • 226