Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Rails on Docker

Rails on Docker

【オンライン開催】銀座Rails#22 @リンクアンドモチベーション
https://ginza-rails.connpass.com/event/176491/

Takumi Shotoku

June 12, 2020
Tweet

More Decks by Takumi Shotoku

Other Decks in Technology

Transcript

  1. 自己紹介 • 名前: 神速 • 会社: メドピア株式会社 • GitHub: @sinsoku

    (画像右上) • Twitter: @sinsoku_listy (画像右下) • Rails歴: 約7年 みんな !" を飲みながら気楽に聞いて 2
  2. Ansibleの例(playbook.yml) - hosts: all become: yes tasks: - apt: pkg:

    - ruby - nodejs - imagemagick update_cache: yes 9
  3. 11

  4. 12

  5. 15

  6. ビルドと起動 $ ls Dockerfile app.rb ginza.html index.html • イメージのビルド $

    docker build -t plain_server . • コンテナの起動 $ docker run -p 8080:80 plain_server 25
  7. ボリュームマウント $ docker run -p 8080:80 \ -v `pwd`/ginza.html:/app/index.html \

    plain_server $ curl localhost:8080 <!DOCTYPE html> <html lang="ja"> <head> <title>Index</title> </head> <body> <h1>Hello, Ginza.rb</h1> </body> </html> 27
  8. ここまでのまとめ • docker build -t <name> . でビルドする • Dockerfileがイメージの設計図

    • $ docker run IMAGE でコンテナを起動する • コンテナの起動時にPortやVolumeを指定できる 28
  9. production用Railsの復習 DBを起動しておく。 $ brew services start postgresql rails newからこんな感じ。 $

    rails new foo --database postgresql && cd foo $ RAILS_ENV=production BUNDLE_WITHOUT=development:test bundle install $ RAILS_ENV=production bin/rails assets:precompile $ RAILS_ENV=production bin/rails db:prepare $ RAILS_ENV=production RAILS_SERVE_STATIC_FILES=1 bin/rails s 31
  10. Dockerfile v1 FROM ruby:2.7.1 WORKDIR /app ENV RAILS_ENV production ENV

    BUNDLE_WITHOUT development:test RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -y yarn COPY . . RUN bundle install RUN SECRET_KEY_BASE=dummy bin/rails assets:precompile EXPOSE 3000 CMD ["bin/rails", "server"] $ cp .gitignore .dockerignoreも要る 33
  11. # docker-compose.yml version: '3.7' services: db: image: postgres:11.6-alpine volumes: -

    db:/var/lib/postgresql/data web: build: . depends_on: - db ports: - "3000:3000" stdin_open: true tty: true environment: DATABASE_URL: 'postgres://postgres:@db' RAILS_LOG_TO_STDOUT: 1 RAILS_SERVE_STATIC_FILES: 1 RAILS_MASTER_KEY: volumes: db: 34
  12. レイヤーキャッシュ FROM ruby:2.7.1 WORKDIR /app ENV RAILS_ENV production ENV BUNDLE_WITHOUT

    development:test RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -y yarn COPY . . RUN bundle install RUN SECRET_KEY_BASE=dummy bin/rails assets:precompile EXPOSE 3000 CMD ["bin/rails", "server"] 38
  13. Dockerfile v2 FROM ruby:2.7.1 WORKDIR /app ENV RAILS_ENV production ENV

    BUNDLE_WITHOUT development:test RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -y yarn COPY Gemfile . COPY Gemfile.lock . RUN bundle install COPY package.json . COPY yarn.lock . RUN yarn install COPY . . RUN SECRET_KEY_BASE=dummy bin/rails assets:precompile EXPOSE 3000 CMD ["bin/rails", "server"] 39
  14. マルチステージビルド FROM ruby:2.7.1 as builder COPY Gemfile COPY Gemfile.lock .

    RUN bundle install FROM ruby:2.7.1 COPY --from=builder /usr/local/bundle /usr/local/bundle EXPOSE 3000 CMD ["bin/rails", "server"] 40
  15. Dockerfile v3 FROM ruby:2.7.1 as base WORKDIR /app ENV RAILS_ENV

    production ENV BUNDLE_WITHOUT development:test FROM base as builder RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -y yarn COPY Gemfile . COPY Gemfile.lock . RUN bundle install COPY package.json yarn.lock . RUN yarn install COPY . . RUN SECRET_KEY_BASE=dummy bin/rails assets:precompile # ଓ͘ 41
  16. Dockerfile v3 FROM base COPY . . COPY --from=builder /usr/local/bundle

    /usr/local/bundle COPY --from=builder /builder/public/assets ./public/assets COPY --from=builder /builder/public/packs ./public/packs EXPOSE 3000 CMD ["bin/rails", "server"] サーバの起動時にNode.jsとnode_modulesは不要 42
  17. Dockerfile v4 FROM ruby:2.7.1-alpine as base WORKDIR /app ENV RAILS_ENV

    production ENV BUNDLE_WITHOUT development:test FROM base as builder RUN apk update && apk-add --update \ build-base postgresql-dev yarn tzdata git COPY Gemfile . COPY Gemfile.lock . RUN bundle install COPY package.json yarn.lock . RUN yarn install COPY . . RUN SECRET_KEY_BASE=dummy bin/rails assets:precompile # ޙ൒͸ಉ͡ͳͷͰলུ 44
  18. 本番 ! との違い • インストールするgemが異なる • npm, node_modulesが必要 • eslint,

    jest, ...etc • 開発用のツール(Chrome, curlなど)が必要 49
  19. # docker-compose.development.yml services: web: image: circleci/ruby:2.7.1-node-browsers stdin_open: true tty: true

    volumes: - .:/app environment: BOOTSNAP_CACHE_DIR: '/usr/local/bundle' HISTFILE: '/app/log/.bash_history' EDITOR: vi DATABASE_URL: 'postgres://postgres:@db' depends_on: - db command: ["bin/rails", "server", "-b", "0.0.0.0"] expose: ["3000"] ports: - "3000:3000" working_dir: /app user: root 52
  20. Docker for Mac遅い問題 • MacのVolueマウントが遅い • bundle installが遅い • yarn

    installが遅い • assets:precompileが遅い もう何もかも遅い 53
  21. # docker-compose.development.yml services: web: image: circleci/ruby:2.7.1-node-browsers stdin_open: true tty: true

    volumes: - ..:/app:cached - rails_cache:/app/tmp/cache - bundle:/usr/local/bundle - node_modules:/app/node_modules - packs:/app/public/packs - packs_test:/app/public/packs-test environment: BOOTSNAP_CACHE_DIR: '/usr/local/bundle' HISTFILE: '/app/log/.bash_history' EDITOR: vi DATABASE_URL: 'postgres://postgres:@db' depends_on: - db command: ["bin/rails", "server", "-b", "0.0.0.0"] expose: ["3000"] ports: - "3000:3000" working_dir: /app user: root 54
  22. # dip.yml version: '4.1' interaction: rails: description: Run Rails commands

    service: web command: bundle exec rails subcommands: s: description: Run Rails server at http://localhost:3000 service: web compose: run_options: [service-ports, use-aliases] provision: - dip compose down --volumes - dip compose up -d db redis - dip bash -c ./bin/setup 56
  23. # docker-compose.staging.yml services: web: &web build: . image: ginza-rails:staging stdin_open:

    true tty: true environment: BOOTSNAP_CACHE_DIR: '/usr/local/bundle' HISTFILE: '/app/log/.bash_history' EDITOR: vi RAILS_ENV: staging DATABASE_URL: 'postgres://postgres:@db' REDIS_URL: 'redis://redis' RAILS_LOG_TO_STDOUT: 1 RAILS_SERVE_STATIC_FILES: 1 depends_on: - db - redis ports: - "3000:3000" sidekiq: <<: *web command: ['bundle', 'exec', 'sidekiq'] expose: [] ports: [] 58
  24. 62

  25. 63

  26. buildspec.ymlから抜粋 # Upload assets to s3 - CONTAINER_ID=$(docker create $REPOSITORY_URL:$IMAGE_TAG)

    - docker cp $CONTAINER_ID:/app/public/packs public/packs - aws s3 sync public/packs s3://${s3_bucket}/packs - docker rm $CONTAINER_ID 64
  27. 65

  28. Dockerfileでassets:precompileしない $ docker build -t <IMAGE> . $ docker run

    -v `pwd`/public/assets:/app/public/assets \ -v `pwd`/public/packs:/app/public/packs \ <IMAGE> bin/rails assets:precompile $ aws s3 sync public/assets s3://<bucket>/assets $ aws s3 sync public/packs s3://<bucket>/packs 70