Deploying Rails with Docker

Acd62030df551952268e84c8fff26a5b?s=47 lazyatom
February 26, 2014

Deploying Rails with Docker

Slides for a 5-minute lightning talk that actually lasted about 10 minutes, that I sped through way-too-fast at Austin on Rails in February 2014.

Acd62030df551952268e84c8fff26a5b?s=128

lazyatom

February 26, 2014
Tweet

Transcript

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

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

  3. 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
  4. 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
  5. 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
  6. None
  7. # Dockerfile ! FROM stackbrew/ubuntu ! RUN apt-get update RUN

    apt-get install -y ruby
  8. $ docker build -t lazyatom/demo .

  9. 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 $
  10. $ docker run lazyatom/demo which ruby => /usr/bin/ruby $ docker

    run lazyatom/demo \ ruby -e 'p ["hello", "world"].join(" ")' => "hello world"
  11. $ 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
  12. 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 $
  13. $ 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
  14. None
  15. None
  16. 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"]
  17. $ 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)
  18. 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 $
  19. # 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
  20. $ 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 $
  21. # 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
  22. $ docker run -d \ -p 6789:5000 \ -link $DB_CONTAINER_NAME:db

    \ lazyatom/docker-rails-app
  23. None
  24. docker push lazyatom/docker-rails-app http://cactus.lazyatom.com:6789/ # then run all those commands

    on a VPS...
  25. But what about… • Reverse proxying? • Private docker indexes?

    • Managing containers? • Deploying to more than one ‘server’?
  26. LIKE I SAID It’s NOT EASY BUT… it’s GETTING EASIER

  27. 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