Slide 1

Slide 1 text

Deploying Rails with James Adam @lazyatom http://exciting.io

Slide 2

Slide 2 text

TL;DR It’s NOT EASY BUT it’s GETTING EASIER

Slide 3

Slide 3 text

Virtualisation Hypervisor / Host Kernel Actual computer (or VPS) Guest O/S App App App Guest Kernel OS Processes App Binaries Guest O/S App App App Guest Kernel OS Processes App Binaries Guest O/S App App App Guest Kernel OS Processes App Binaries

Slide 4

Slide 4 text

Containers Host O/S OS Processes Host Kernel with container technology Actual computer (or VPS) App App Binaries App App Binaries App App Binaries Service

Slide 5

Slide 5 text

Deployment benefits • Reliable behaviour between environments • Easier to isolate dependencies • Easy to scale … and containers in particular:! • Boot faster than VMs (seconds, not minutes) • Use less memory on host machine

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

# Dockerfile ! FROM stackbrew/ubuntu ! RUN apt-get update RUN apt-get install -y ruby

Slide 8

Slide 8 text

$ docker build -t lazyatom/demo .

Slide 9

Slide 9 text

Uploading context 2.56 kB Uploading context Step 0 : FROM stackbrew/ubuntu ---> 3aa646e4f1d2 Step 1 : RUN apt-get update ---> Running in 5c965759ddef Ign http://archive.ubuntu.com precise InRelease # ... etc .. Fetched 13.9 MB in 19s (727 kB/s) ---> 31720a59342f Step 2 : RUN apt-get install -y ruby ---> Running in af8e63489460 The following extra packages will be installed: libgdbm3 libreadline5 libruby1.8 ruby1.8 The following NEW packages will be installed: libgdbm3 libreadline5 libruby1.8 ruby ruby1.8 # ... etc ... Setting up ruby1.8 (1.8.7.352-2ubuntu1.4) ... Setting up ruby (4.8) ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place ---> 2fc06d92167e Successfully built 2fc06d92167e $

Slide 10

Slide 10 text

$ docker run lazyatom/demo which ruby => /usr/bin/ruby $ docker run lazyatom/demo \ ruby -e 'p ["hello", "world"].join(" ")' => "hello world"

Slide 11

Slide 11 text

$ docker run -i -t lazyatom/demo bash root@f531a20cc02b:/# echo 'HELLO' > hello.txt root@f531a20cc02b:/# ls *.txt hello.txt root@f531a20cc02b:/# exit ! $ docker run -i -t lazyatom/demo bash root@75c5024c8acd:/# ls *.txt ls: cannot access *.txt: No such file or directory

Slide 12

Slide 12 text

Uploading context 2.56 kB Uploading context Step 0 : FROM stackbrew/ubuntu ---> 3aa646e4f1d2 Step 1 : RUN apt-get update ---> Running in 5c965759ddef Ign http://archive.ubuntu.com precise InRelease # ... etc .. Fetched 13.9 MB in 19s (727 kB/s) ---> 31720a59342f Step 2 : RUN apt-get install -y ruby ---> Running in af8e63489460 The following extra packages will be installed: libgdbm3 libreadline5 libruby1.8 ruby1.8 The following NEW packages will be installed: libgdbm3 libreadline5 libruby1.8 ruby ruby1.8 # ... etc ... Setting up ruby1.8 (1.8.7.352-2ubuntu1.4) ... Setting up ruby (4.8) ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place ---> 2fc06d92167e Successfully built 2fc06d92167e $

Slide 13

Slide 13 text

$ docker build -t lazyatom/demo . Uploading context 2.56 kB Uploading context Step 0 : FROM stackbrew/ubuntu ---> 3aa646e4f1d2 Step 1 : RUN apt-get update ---> Using cache ---> 31720a59342f Step 2 : RUN apt-get install -y ruby ---> Using cache ---> 2fc06d92167e Successfully built 2fc06d92167e

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

FROM lazyatom/ruby-2.0 ! # Set up environment ENV RAILS_ENV production ENV PORT 5000 ! # Set up initial bundle; this should get cached RUN mkdir /docker-rails-app WORKDIR /docker-rails-app ADD Gemfile /docker-rails-app/Gemfile ADD Gemfile.lock /docker-rails-app/Gemfile.lock RUN bundle install ! # Install app ADD . /docker-rails-app ! EXPOSE 5000 ENTRYPOINT ["bundle", "exec"] CMD ["rails", "server", "-p", "5000"]

Slide 17

Slide 17 text

$ dockerapp build . Building as Dockerapp::Builder Moving ignored files out of the way running: docker build -rm -t lazyatom/build . Uploading context 528.4 kB Uploading context Step 0 : FROM lazyatom/ruby-2.0 ---> a7a5f987e587 Step 1 : MAINTAINER james@lazyatom.com ---> Running in c63d5ee22226 ---> 229a9370eb6f Step 2 : ENV RAILS_ENV production ---> Running in 98a138e0a7f4 ---> 629210201c8f Step 3 : ENV PORT 5000 ---> Running in eaa09e56eef6 ---> 9b55f80ffbc3 Step 4 : RUN mkdir /docker-rails-app ---> Running in 319947c0b6d8 ---> 8a001fb5a96f Step 5 : WORKDIR /docker-rails-app ---> Running in 6677861994d0 ---> cc3a91632970 Step 6 : ADD Gemfile /docker-rails-app/Gemfile ---> c9373bb90928 Step 7 : ADD Gemfile.lock /docker-rails-app/Gemfile.lock ---> 0023f2d2d3e4 Step 8 : RUN bundle install ---> Running in 0b498ceaef92 Installing rake (10.1.1)

Slide 18

Slide 18 text

Installing i18n (0.6.9) # … etc … Installing uglifier (2.4.0) Your bundle is complete! ---> e9cec88d8f8f Step 9 : ADD . /docker-rails-app ---> 3ecbf489366a Step 10 : EXPOSE 5000 ---> Running in af09bc405e0a ---> b5ce944c3189 Step 11 : ENTRYPOINT ["bundle", "exec"] ---> Running in dec03819c646 ---> 404edaeeca65 Step 12 : CMD ["rails", "server", "-p", "5000"] ---> Running in 576357f082ab ---> 3c52a1b8dd73 Successfully built 3c52a1b8dd73 Tagged as lazyatom/docker-rails-app Restoring ignored files $

Slide 19

Slide 19 text

# Set a name for the database container $ export DB_CONTAINER_NAME=test_app_db # Start the database container $ docker run -d \ -name $DB_CONTAINER_NAME \ -p 5432:5432 \ -e POSTGRESQL_USER=docker_rails_app \ -e POSTGRESQL_PASS=pa$$w0rd \ -e POSTGRESQL_DB=docker_rails_app_production \ orchardup/postgresql $ docker ps CONTAINER ID IMAGE PORTS NAMES c83f16772e56 postgresql 5432->5432 test_app_db

Slide 20

Slide 20 text

$ docker run -link $DB_CONTAINER_NAME:db \ lazyatom/docker-rails-app rake db:schema:load -- enable_extension("plpgsql") -> 0.0317s -- create_table("tacos", {:force=>true}) -> 0.0152s -- initialize_schema_migrations_table() -> 0.0075s $

Slide 21

Slide 21 text

# config/database.yml ! production: &default adapter: postgresql database: <%= ENV['DB_ENV_POSTGRESQL_DB'] %> username: <%= ENV['DB_ENV_POSTGRESQL_USER'] %> password: <%= ENV['DB_ENV_POSTGRESQL_PASS'] %> host: <%= ENV['DB_PORT_5432_TCP_ADDR'] %> port: <%= ENV['DB_PORT_5432_TCP_PORT'] %> $ docker run -link $DB_CONTAINER_NAME:db # etc

Slide 22

Slide 22 text

$ docker run -d \ -p 6789:5000 \ -link $DB_CONTAINER_NAME:db \ lazyatom/docker-rails-app

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

docker push lazyatom/docker-rails-app http://cactus.lazyatom.com:6789/ # then run all those commands on a VPS...

Slide 25

Slide 25 text

But what about… • Reverse proxying? • Private docker indexes? • Managing containers? • Deploying to more than one ‘server’?

Slide 26

Slide 26 text

LIKE I SAID It’s NOT EASY BUT… it’s GETTING EASIER

Slide 27

Slide 27 text

Things to keep an eye on • docker-osx • boot2docker (faster but not quite there yet) • fig & orchardup.com • flynn.io • quay.io Thanks! James Adam @lazyatom http://exciting.io