Share
Embed
Rails on Docker
【オンライン開催】銀座Rails#22 @リンクアンドモチベーション
https://ginza-rails.connpass.com/event/176491/
Takumi Shotoku
June 12, 2020
Transcript
74 slides
-
自己紹介 • 名前: 神速 • 会社: メドピア株式会社 • GitHub: @sinsoku
(画像右上) • Twitter: @sinsoku_listy (画像右下) • Rails歴: 約7年 みんな !" を飲みながら気楽に聞いて 2 -
Ansibleの例(playbook.yml) - hosts: all become: yes tasks: - apt: pkg:
- ruby - nodejs update_cache: yes 8 -
Ansibleの例(playbook.yml) - hosts: all become: yes tasks: - apt: pkg:
- ruby - nodejs - imagemagick update_cache: yes 9 -
例. シンプルなWEBrickサーバ # app.rb require "webrick" srv = WEBrick::HTTPServer.new srv.mount('/',
WEBrick::HTTPServlet::FileHandler, 'index.html') srv.start 23 -
Dockerfile FROM ruby:2.7.1 WORKDIR /app COPY index.html ./ COPY app.rb
./ EXPOSE 80 CMD ["ruby", "app.rb"] 24 -
ビルドと起動 $ ls Dockerfile app.rb ginza.html index.html • イメージのビルド $
docker build -t plain_server . • コンテナの起動 $ docker run -p 8080:80 plain_server 25 -
$ curl localhost:8080 <!DOCTYPE html> <html lang="ja"> <head> <title>Index</title> </head>
<body> <h1>Hello, Docker</h1> </body> </html> 26 -
ボリュームマウント $ 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 -
ここまでのまとめ • docker build -t <name> . でビルドする • Dockerfileがイメージの設計図
• $ docker run IMAGE でコンテナを起動する • コンテナの起動時にPortやVolumeを指定できる 28 -
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 -
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 -
# 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 -
dbとwebを起動 <key>はconfig/master.keyの中の値。 $ export RAILS_MASTER_KEY=<key> $ docker-compose up -d db
$ docker-compose run web bin/rails db:prepare $ docker-compose up web 35 -
レイヤーキャッシュ 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 -
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 -
マルチステージビルド 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 -
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 -
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 -
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 -
BuildKit2を使用する Docker 18.09から本体に統合されたツール。 • ビルドを並列に行い高速化 • キャッシュや機密情報に関する機能強化 • DOCKER_BUILDKIT環境変数を設定する •
$ DOCKER_BUILDKIT=1 docker build -t foo . 2 https://docs.docker.com/develop/develop-images/build_enhancements/ 45 -
本番 ! のまとめ • ビルド高速化 • レイヤーキャッシュ、BuildKit • 軽量化 •
マルチステージビルド、Alpine Linux 46 -
本番 ! との違い • インストールするgemが異なる • npm, node_modulesが必要 • eslint,
jest, ...etc • 開発用のツール(Chrome, curlなど)が必要 49 -
開発でCircleCIのイメージを使う $ docker pull circleci/ruby:2.7.1-node-browsers • Node.js, Yarnが入っている • ブラウザが入っている
• jqが入っている • CircleCIで落ちるテストを再現できる 51 -
# 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 -
Docker for Mac遅い問題 • MacのVolueマウントが遅い • bundle installが遅い • yarn
installが遅い • assets:precompileが遅い もう何もかも遅い 53 -
# 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 -
bibendi/dip3 DockerでRailsを開発するときに便利なツール。 • docker-composeのラッパー • dip.ymlにコマンドを記述する • dip rails s
• dip rubocop --parallel 3 https://github.com/bibendi/dip 55 -
# 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 -
本番 ! をローカルで動かす dip.ymlでdocker-compose.ymlを複数指定できる。 environment: COMPOSE_EXT: development compose: files: -
docker-compose.yml # db, redis - docker-compose.$COMPOSE_EXT.yml # web, worker 57 -
# 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 -
本番 ! をローカルで動かす $ COMPOSE_EXT=staging dip compose build $ COMPOSE_EXT=staging
dip rails db:prepare $ COMPOSE_EXT=staging dip rails s 59 -
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 -
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 -
どちらも課題が残る 1. Cache Mount • CodeBuildはDockerボリュームのキャッシュが効かない • ベースイメージの更新でキャッシュが使えなくなる 2. assets:precompileの省略
• manifest.jsonが無いとViewのレンダリングでエラー 71