Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker for Rubyists

Docker for Rubyists

Docker for Rubyists presentet at Meetup Porto on Rails #3 June

Patrício dos Santos

May 29, 2019
Tweet

More Decks by Patrício dos Santos

Other Decks in Programming

Transcript

  1. What is Docker Docker, as a technology, is a set

    of tools built around the idea of packaging and running software in small sandboxed environments known as containers.
  2. Containers vs Images Image is a ready-only template with instructions

    for creating a Docker container Container is a runnable instance of an image
  3. Why Docker? • Consistent environment for your entire team; •

    Don’t need to install a bunch of language environments on your machine. • Simulate production-like environments locally • Test easily app’s compatibility with the newer version of language or database • Ship fast
  4. Verify : $ docker version Client: Docker Engine - Community

    Version: 18.09.2 API version: 1.39 Go version: go1.10.8 Git commit: 6247962 Built: Sun Feb 10 04:12:39 2019 OS/Arch: darwin/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.2 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 04:13:06 2019 OS/Arch: linux/amd64 Experimental: false
  5. $ docker run ruby:latest ruby -e "puts 'Hello Docker'" Unable

    to find image 'ruby:latest' locally latest: Pulling from library/ruby 6f2f362378c5: Pull complete 494c27a8a6b8: Pull complete 7596bb83081b: Pull complete 372744b62d49: Pull complete 615db220d76c: Pull complete 3a6344df01c6: Pull complete 913337fffaae: Pull complete d23bf32949fe: Pull complete Digest: sha256:bde780c6c098a8104ef7a860592b83cff63252826520c5ca35d5865bed8e55be Status: Downloaded newer image for ruby:latest Hello Docker
  6. $ docker run ruby:latest ruby -e "puts 'Hello Docker’” –

    AGAIN! Hello Docker docker run [OPTIONS] <image> <command>
  7. $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS

    NAMES $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a27996cdde9a ruby:latest "ruby -e 'puts 'Hell…" 6 minutes ago Exited (0) 6 minutes ago tender_shockley a06859ee277b ruby:latest "ruby -e 'puts 'Hell…" 7 minutes ago Exited (0) 7 minutes ago nervous_mccarthy $ docker rm <container id> <container id2> $ docker run --rm ruby:2.7.0-preview1 ruby –e “puts ’Hello’”
  8. Generate Rails App without ruby installed $ cd ~/workspace $

    docker run -i -t --rm -v ${pwd}:/usr/src/app ruby:latest bash > root@144b4f99edab:/# …/# cd /usr/src/app …/usr/src/app# gem install rails …/usr/src/app# rails new superapp -T --skip-bundle …/usr/src/app# exit $ ls > superapp
  9. To run our Rails App we need a custom image

    • Dockerfile – Describes how a machine image is configured. • Dockerfile – Is made up of various instructions (FROM, RUN, COPY, and WORKDIR) Docker build [options] <PATH_TO_BUILD_DIRECTORY>
  10. Dockerfile FROM ruby:latest RUN apt-get update -yqq RUN apt-get install

    -yqq --no-install-recommends nodejs COPY . /usr/src/app/ WORKDIR /usr/src/app RUN bundle install
  11. $ docker build . Sending build context to Docker daemon

    138.8kB Step 1/6 : FROM ruby:latest ---> f1c13927d193 Step 2/6 : RUN apt-get update -yqq ---> Using cache ---> c2c436c9dd8a …. Removing intermediate container 05f34e1bc93b ---> 6c2873e62181 Successfully built 6c2873e62181
  12. $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none>

    <none> 6c2873e62181 47 seconds ago 1.02GB ruby latest f1c13927d193 30 hours ago 870MB
  13. Running Rails server using the new image $ docker run

    -p 3000:3000 6c2873e62181 bin/rails s -b 0.0.0.0
  14. Console Output => Booting Puma => Rails 5.2.3 application starting

    in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.12.1 (ruby 2.6.3-p62), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://0.0.0.0:3000 Use Ctrl-C to stop Started GET "/" for 172.17.0.1 at 2019-06-29 04:58:31 +0000 Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 Processing by Rails::WelcomeController#index as HTML Rendering /usr/local/bundle/gems/railties-5.2.3/lib/rails/templates/rails/welcome/index.html.erb Rendered /usr/local/bundle/gems/railties-5.2.3/lib/rails/templates/rails/welcome/index.html.erb (5.5ms) Completed 200 OK in 27ms (Views: 17.9ms | ActiveRecord: 0.0ms)
  15. Naming and Versioning Images $ docker tag 6c2873e62181 superapp $

    docker images REPOSITORY TAG IMAGE ID CREATED SIZE superapp latest 6c2873e62181 11 minutes ago 1.02GB ruby latest f1c13927d193 30 hours ago 870MB $ docker tag superapp superapp:1.0 $ docker build -t superapp -t superapp:1.0 . $ docker run -p 3000:3000 superapp bin/rails s -b 0.0.0.0
  16. Default Command FROM ruby:latest RUN apt-get update -yqq RUN apt-get

    install -yqq --no-install-recommends nodejs COPY . /usr/src/app/ WORKDIR /usr/src/app RUN bundle install CMD [“bin/rails”, “s”, “-b”, ”0.0.0.0”]
  17. Rebuild and Run again… $ docker build -t superapp .

    $ docker run -p 3000:3000 superapp ---- $docker run -p 3000:3000 superapp bin/rails -T
  18. Solving Caching issues | packages and Gems FROM ruby:latest RUN

    apt-get update –yqq && apt-get install -yqq --no-install-recommends nodejs COPY Gemfile* /usr/src/app/ WORKDIR /usr/src/app RUN bundle install COPY . /usr/src/app/ CMD [“bin/rails”, “s”, “-b”, ”0.0.0.0”]
  19. Label FROM ruby:latest LABEL maintainer=“[email protected]” RUN apt-get update –yqq &&

    apt-get install -yqq --no-install-recommends nodejs COPY Gemfile* /usr/src/app/ WORKDIR /usr/src/app RUN bundle install COPY . /usr/src/app/ CMD [“bin/rails”, “s”, “-b”, ”0.0.0.0”]
  20. Docker-composer output Creating network "myapp_default" with the default driver Building

    web Step 1/6 : FROM ruby:latest ---> f1c13927d193 Step 2/6 : RUN apt-get update -yqq ---> Using cache ---> c2c436c9dd8a … Removing intermediate container ef048eaae861 ---> ae266514c8b0 Step 6/6 : RUN bundle install ….. Removing intermediate container 7d8fe53a039a ---> baf5e19c6c94 Successfully built baf5e19c6c94 Successfully tagged myapp_web:latest WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating myapp_web_1 ... done Attaching to myapp_web_1 web_1 | Switch to inspect mode. web_1 | myapp_web_1 exited with code 0
  21. $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE myapp_web

    latest baf5e19c6c94 About a minute ago 1.02GB superapp latest 74a307638448 20 minutes ago 1.02GB <none> <none> 6c2873e62181 About an hour ago 1.02GB ruby latest f1c13927d193 31 hours ago 870MB
  22. Other commands and Options - Detached mode $ docker-compose up

    –d - List running containers $ docker-compose ps - Manage container life cycle $ docker-compose \ [start|stop|kill|restart|pause|unpause|rm] \ <service_name>
  23. Other commands and Options - 2 - View logs $

    docker-compose logs [-f] <service name> - Run a one-off command in a new throwaway container $ docker-compose run --rm <service name> <command> - Run a one-off command in an existing container $ docker-compose exec <service name> <command> - Rebuild an image $ docker-compose build <sevice name>
  24. Adding database - PostgreSQL version: ‘3’ services: web: … database:

    image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: secretpassword POSTGRES_DB: superapp_dev
  25. Connecting to Postgres from another container $ docker-compose run --rm

    database psql -U postgres -h database > Password for user postgres: psql (11.1 (Debian 11.1-1.pgdg…) Type “help” for help postgres=#
  26. Connecting de App to Postgres - Edit Gemfile, replace gem

    ’sqlite3’ with gem ‘pg’, then: $ docker-compose stop web $ docker-compose build web Change config/database.yml > Eg. host: <%= ENV.fetch(‘DATABASE_HOST’) %> Add Environment variables for web service:
  27. version: ‘3’ services: web: … environment: POSTGRES_HOST: database POSTGRES_USER: postgres

    POSTGRES_PASSWORD: secretpassword POSTGRES_DB: superapp_dev database: image: postgres environment: …
  28. Create database and run migrations $ docker-compose run --rm web

    bin/rails db:create $ docker-compose run --rm web bin/rails db:migrate Or $ docker-compose exec web bin/rails db:migrate
  29. Volumes for Database data version: ‘3’ services: web: … environment:

    … database: image: postgres environment: … volumes: - db_data:/var/lib/postgresql/data volumes: db_data:
  30. Debugging with pry-rails and run specs edit docker-compose.yml web: tty:

    true stdin_open: true Then attach to the process: $ docker attach $(docker-compose ps –q web) $ docker-compose run web bundle exec rspec [path_to_rspec]