2. 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
3. Current state
• Late 2013: development environment on Docker
• Late 2014: staging environment on Docker
• 2015: Docker in production on AWS
5. 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
6. Dockerfiles
Central GIT repository with global Dockerfiles
base
buildkite-agent
consul
dns
elasticsearch
fluentd
go
haproxy
influxdb
java
mailcatcher
memcached
nginx
postgresql
redis
ruby
7. Dockerfiles
• Changes to global Dockerfiles are build
manually and pushed to private Docker
repository
• Docker repository hosted in AWS
8. 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
9. Image versioning
• Each image 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
• Pull from 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
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
13. 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
14. 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.
15. 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.
16. 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