Docker at MoneyBird
Edwin Vlieg
€
Why did we start?
• Managing development environments in a
growing team of software engineers
• Prevent issues with dependencies in different
environments (dev, staging, production)
• Traceability of dependencies: stay in control
when updating versions
Current state
• Late 2013: development environment on Docker
• Late 2014: staging environment on Docker
• 2015: Docker in production on AWS
Images
Ubuntu 14.04
MoneyBird base image
- Build essentials
- PG client
- Locale settings
- SSH keys
Ruby image
App 1 App 2
Image versioning
• Image name: ruby
• Image tag: Ruby version + image version
• Example: ruby:2.1-2
• Able to pinpoint both another Ruby version and
another build of the image
Dockerfiles
Central GIT repository with global Dockerfiles
base
buildkite-agent
consul
dns
elasticsearch
fluentd
go
haproxy
influxdb
java
mailcatcher
memcached
nginx
postgresql
redis
ruby
Dockerfiles
• Changes to global Dockerfiles are build
manually and pushed to private Docker
repository
• Docker repository hosted in AWS
Dockerfiles
• Each project has a Dockerfile in its Git repository
• Build by our continuous integration server on
each git push
• Source code added to image
• All tests are executed within the image
• Result is a tested and deployable image
Image versioning
• Each image is tagged with the git SHA
• After successful build, image is tagged with git
branch
CI with Docker
• We use Buildkite: https://buildkite.com
• Handles all Github pushes and statuses, great UI
• Local CI server runs daemons accepting jobs
• Executes each shell script you want
• Great with docker: hosted CI lacks docker image
cache, with own server no issues.
Building images
• Pull from project’s Git repository
• Fix mtime issues: 

https://gist.github.com/jeffery/1115504
• Build image from Dockerfile, think about layer
caching!
Building images
FROM base
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install -j7 --gemfile=/app/Gemfile
ADD app/assets/ /app/app/assets/
ADD config/locales/ /app/config/locales/
ADD bin/compile_assets /app/bin/
RUN (mkdir -p /app/public/assets && 
cd /app/ && bin/compile_assets --compress)
ADD ./ /app
Development env
• Vagrant box with all images running
• Docker image contains source code, a regular
“docker pull” keeps team up-to-date with work
from colleagues.
• boot2docker didn’t exist when we started, is
gaining interest from team
Development env
• Source code of project someone is working on is
local.
• Smart routing through haproxy: by default serve from
running container, unless local server is started.
• Main advantage: speed! Every millisecond counts
when running test suite.
• Issues with file change detection and automated test
suite (Guard) when running code from container.
Production
• No fancy techniques, keeping it simple!
• EC2 instances with predefined roles, defined as
a service in /etc/init.d
• Service reads SHA from revision file, pulls
images and runs docker image.
Production
• Deployment consists of changing revision file on
each server (through Capistrano)
• Restarting service on 50% of servers
• Waiting for health check
• Restart other 50% of servers
Questions?

Docker at MoneyBird

  • 1.
  • 2.
    Why did westart? • Managing development environments in a growing team of software engineers • Prevent issues with dependencies in different environments (dev, staging, production) • Traceability of dependencies: stay in control when updating versions
  • 3.
    Current state • Late2013: development environment on Docker • Late 2014: staging environment on Docker • 2015: Docker in production on AWS
  • 4.
    Images Ubuntu 14.04 MoneyBird baseimage - Build essentials - PG client - Locale settings - SSH keys Ruby image App 1 App 2
  • 5.
    Image versioning • Imagename: ruby • Image tag: Ruby version + image version • Example: ruby:2.1-2 • Able to pinpoint both another Ruby version and another build of the image
  • 6.
    Dockerfiles Central GIT repositorywith global Dockerfiles base buildkite-agent consul dns elasticsearch fluentd go haproxy influxdb java mailcatcher memcached nginx postgresql redis ruby
  • 7.
    Dockerfiles • Changes toglobal Dockerfiles are build manually and pushed to private Docker repository • Docker repository hosted in AWS
  • 8.
    Dockerfiles • Each projecthas a Dockerfile in its Git repository • Build by our continuous integration server on each git push • Source code added to image • All tests are executed within the image • Result is a tested and deployable image
  • 9.
    Image versioning • Eachimage is tagged with the git SHA • After successful build, image is tagged with git branch
  • 10.
    CI with Docker •We use Buildkite: https://buildkite.com • Handles all Github pushes and statuses, great UI • Local CI server runs daemons accepting jobs • Executes each shell script you want • Great with docker: hosted CI lacks docker image cache, with own server no issues.
  • 11.
    Building images • Pullfrom project’s Git repository • Fix mtime issues: 
 https://gist.github.com/jeffery/1115504 • Build image from Dockerfile, think about layer caching!
  • 12.
    Building images FROM base ADDGemfile /app/Gemfile ADD Gemfile.lock /app/Gemfile.lock RUN bundle install -j7 --gemfile=/app/Gemfile ADD app/assets/ /app/app/assets/ ADD config/locales/ /app/config/locales/ ADD bin/compile_assets /app/bin/ RUN (mkdir -p /app/public/assets && cd /app/ && bin/compile_assets --compress) ADD ./ /app
  • 13.
    Development env • Vagrantbox with all images running • Docker image contains source code, a regular “docker pull” keeps team up-to-date with work from colleagues. • boot2docker didn’t exist when we started, is gaining interest from team
  • 14.
    Development env • Sourcecode of project someone is working on is local. • Smart routing through haproxy: by default serve from running container, unless local server is started. • Main advantage: speed! Every millisecond counts when running test suite. • Issues with file change detection and automated test suite (Guard) when running code from container.
  • 15.
    Production • No fancytechniques, keeping it simple! • EC2 instances with predefined roles, defined as a service in /etc/init.d • Service reads SHA from revision file, pulls images and runs docker image.
  • 16.
    Production • Deployment consistsof changing revision file on each server (through Capistrano) • Restarting service on 50% of servers • Waiting for health check • Restart other 50% of servers
  • 17.