令和時代のRails運用

 令和時代のRails運用

A5e5ee2fb9e4ce3c728ed9e3ef6e916f?s=128

Tomohiro Hashidate

May 13, 2020
Tweet

Transcript

  1. 12.

    Rails のDocker イメージ作成 1 buildkit を使ったモダンなRails アプリケーションイメージの構成⽅法を紹介する。 # syntax =

    docker/dockerfile:experimental 後述するマウントキャッシュの活⽤のため冒頭に記述しておく
  2. 13.

    Rails のDocker イメージ作成 2 余計なレイヤーキャッシュ削除の⼯夫をしなくて済む様にnodejs はmulti stage ビルドで ⼊れる #

    Node.js ダウンロード⽤ビルドステージ FROM ruby:2.6.5 AS nodejs WORKDIR /tmp # Node.js のダウンロード RUN curl -LO https://nodejs.org/dist/v12.14.1/node-v12.14.1-linux-x64.tar.xz RUN tar xvf node-v12.14.1-linux-x64.tar.xz RUN mv node-v12.14.1-linux-x64 node
  3. 14.

    Rails のDocker イメージ作成 3 FROM ruby:2.6.5 # nodejs をインストールしたイメージからnode.js をコピーする

    COPY --from=nodejs /tmp/node /opt/node ENV PATH /opt/node/bin:$PATH # アプリケーション起動⽤のユーザーを追加 RUN useradd -m -u 1000 rails RUN mkdir /app && chown rails /app USER rails # yarn のインストール RUN curl -o- -L https://yarnpkg.com/install.sh | bash ENV PATH /home/rails/.yarn/bin:/home/rails/.config/yarn/global/node_modules/.bin:$PATH # ruby-2.7.0 でnew した場合を考慮 RUN gem install bundler
  4. 15.

    Rails のDocker イメージ作成 4 WORKDIR /app # Docker のビルドステップキャッシュを利⽤するため #

    先にGemfile を転送し、bundle install する COPY --chown=rails Gemfile Gemfile.lock package.json yarn.lock /app/ RUN bundle config set app_config .bundle RUN bundle config set path .cache/bundle # mount cache を利⽤する RUN --mount=type=cache,uid=1000,target=/app/.cache/bundle bundle install && \ mkdir -p vendor && \ cp -ar .cache/bundle vendor/bundle RUN bundle config set path vendor/bundle RUN --mount=type=cache,uid=1000,target=/app/.cache/node_modules bin/yarn install --modules-folder .cache/node_modules && \ cp -ar .cache/node_modules node_modules COPY --chown=rails . /app RUN --mount=type=cache,uid=1000,target=/app/tmp/cache bin/rails assets:precompile # 実⾏時にコマンド指定が無い場合に実⾏されるコマンド CMD ["bin/rails", "s", "-b", "0.0.0.0"]
  5. 17.

    基本: 環境変数化 # database.yml の例 production: &default adapter: mysql2 encoding:

    utf8mb4 charset: utf8mb4 collation: utf8mb4_bin pool: 5 timeout: 5000 username: <%= ENV["MYSQL_USERNAME"] || "app" %> password: <%= ENV["MYSQL_PASSWORD"] || "password" %> host: <%= ENV["MYSQL_HOST"] || "127.0.0.1" %> port: <%= ENV["MYSQL_PORT"] || "3306" %>
  6. 21.

    起動時に秘匿情報を取得するラッパー #!/bin/bash set -xe # AWS はファイルのメタデータとして暗号化情報を記録してあるため、何も指定せずに復号化しつつ取得できる # 鍵に対するアクセス権限が無ければ、エラーになる aws

    s3 cp s3://myapp-configs/secretdata.yml configs/secretdata.yml # exec を経由してプロセスを丸ごとRails のものに置き換える # シェルの⼦プロセスとして起動してしまうとシグナルの管理が煩雑になる exec bin/rails s -b 0.0.0.0
  7. 22.

    Parameter Store の活⽤ AWS ならKMS と連携したParameter Store やSecure Manager が利⽤できます。

    ⾃分は起動時にAPI を叩いて環境変数に設定するラッパーツールを書いたりしました。 https://github.com/joker1007/prmstore-exec
  8. 24.

    Logging Driver Docker のログドライバはコンテナアプリケーションの標準出⼒、標準エラー出⼒から ログを読み取ります。 なので、Rails のログを標準出⼒に出せる様にしておく必要があります。 # config/environments/production.rb #

    省略 # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] config.logger = ActiveSupport::Logger.new($stdout) $stdout.sync = true # sync を有効にしないと、バッファリングされてログが⼀定量溜まらないと出⼒されない