Glorious Future
Dockerizing Apps
We are in a time of great oppression, yet we sit at the doorstep of utopia. We, as the true heirs of the earth, must be the driving force that pushes this door open to the glorious future that is now within our reach.
- Joseph Stalin
Why Dockerize?
- Bundles an application and all it's dependencies in one place.
- Creates a standard unit for deployment, regardless of what kind of application.
Operating System
Runtime (Ruby/Java)
Libraries (Gems/Jars)
Application
Build
Run
Rules for App Dockerizability
- Accept configuration as environment variables
- Log to standard out
- Avoid writing to disk
Run
WORKERS=5
PORT=8080
App
Logs
Disk
How to Build the Image
- Create a Dockerfile
- Setup CircleCI to Build
- circle.yml
- Environment variables in CircleCI
my_app/
config/
lib/
spec/
circle.yml
Dockerfile
DOCKER_USER
DOCKER_EMAIL
DOCKER_PASSWORD
(DOCKER_REPOSITORY)
Dockerizing for Ruby
- Use `ENV.fetch('MY_ENV_VAR')` to read config
- Will fail if ENV doesn't have an entry and no default is given.
- Cast to the type you want `Integer(ENV.fetch('NUM'))`
- Specify a default ENV.fetch('NAME', 'bob')
- Write to standard out
- If Rails, include rails_12factor in your Gemfile
- Also allows rails app to serve static assets
- Tell your logger to user STDOUT
- If Rails, include rails_12factor in your Gemfile
- Add gz_release to Gemfile
- Load the rake tasks in your Rakefile
- Load the rake tasks in your Rakefile
logger = Logger.new(STDOUT)
require 'gz_release'
GzRelease::Tasks.install(image_name: 'gazelle/wit')
Use Foreman
- Add foreman to your Gemfile
- Add a Procfile with the command to start your app
- a
- Can now start the app with
web: puma -C ./config/puma.rb
foreman start web
Add a Dockerfile
FROM gazelle/ruby:2.2.3
MAINTAINER Gazelle
CMD foreman start web
ENV DATABASE_URL=--CHANGEME-- \
PORT=8080 \
WORKERS=5
FROM ruby:2.2.3
###### Create user
ENV user app
ENV home /home/app/
ENV group app
ENV PATH /home/app/bin:$PATH
RUN mkdir -p $home \
&& groupadd -r $group -g 777 \
&& useradd -u 666 -r -g $group -d $home -s /sbin/nologin -c "Docker image user" $user \
&& chown -R $user:$group $home
WORKDIR $home
###### App Setup
# gems may be cacheable, so do minimal work first to
# install gems to minimize cache bust.
ENV PORT 8080
ONBUILD COPY Gemfile $home
ONBUILD COPY Gemfile.lock $home
ONBUILD RUN bundle install --path=vendor/bundle --jobs=4 --retry=3 --deployment --binstubs
ONBUILD COPY . $home
ONBUILD RUN chown -R $user:$group $home
ONBUILD USER $user
EXPOSE 8080
CMD foreman start web
Add a circle.yml
machine:
services:
- docker
checkout:
pre:
- git config --global user.email "circleci@gazelle.com"
- git config --global user.name "Gazelle CircleCI Bot"
deployment:
all:
branch: /^(?!(master|dev)).*$/
commands:
- bundle exec rake release:build
- bundle exec rake release:push:branch
master:
branch: master
commands:
- bundle exec rake release:build
- bundle exec rake release:push:timestamp
- bundle exec rake release:push:release
dev:
branch: dev
commands:
- bundle exec rake release:build
- bundle exec rake release:push:latest
Setup Circle Project
The Building Blocks
-
Docker Ruby
- https://github.com/docker-library/ruby/blob/0cdec78d89e33750a4b796bd2c748f0d5a1ae654/2.2/Dockerfile
-
Docker Build Dependencies
- https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile
- https://github.com/docker-library/buildpack-deps/blob/master/jessie/scm/Dockerfile
-
Gazelle Ruby
- https://github.com/secondrotation/ruby_app
-
Gazelle Release
- https://github.com/secondrotation/gz_release
Ruby App Examples
- WIT
- https://github.com/secondrotation/where_is_tudor
- WAR
- https://github.com/secondrotation/war
- tutum_rewind
- https://github.com/secondrotation/tutum_rewind
Java Time
Questions?
Dockerizing Apps
By blatyo
Dockerizing Apps
- 819