Azure Web AppsでRails 6.1アプリをproduction環境で動かす(2021年7月版)

はじめに

Azure Web Appsの勉強をしているときに、実際に動かすアプリが欲しかったのでRailsでアプリを動かそうとしたら微妙にハマったので備忘録として記します。

前提事項

RubyRailsのバージョンは以下のバージョンで検証しました。

Azure Web AppsはRubyを動かす環境が用意されていますが、実際に動くバージョンが2021年7月24日時点で2.6と古いです。

f:id:miyohide:20210724210055p:plain

最新版で動かそうとしたらDockerイメージを動かす方が良いでしょう。

docs.microsoft.com

Dockerfileを作成する

Dockerfileの書き方のサンプルはDockerのドキュメントとして以下に記述があるのですが、これも扱っているバージョンが古いです。

docs.docker.jp

今はWebpackerを使う関係上Node.jsが必要なのですが、Node.jsが必要なのはイメージを作成するだけなのでマルチステージビルドという機能を使います。

docs.docker.jp

結果として、以下の記述となりました。

FROM node:14.17.0-slim as node
FROM ruby:3.0.2

# NodeとYarnのインストール
ENV YARN_VERSION 1.22.5
RUN mkdir -p /opt

COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn/bin/yarn /usr/local/bin/yarnpkg \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
COPY yarn.lock /app/yarn.lock
# developmentとtestのgemはインストールしない
RUN bundle config set --local without 'development test'
RUN bundle install
RUN yarn install

COPY . /app

RUN RAILS_ENV=production bin/rails assets:precompile

ENV RAILS_ENV=production

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD [ "rails", "server", "-b", "0.0.0.0" ]

許可するホスト名の設定

上記でRailsアプリをAzure Web Apps上で動かそうとするとBlocked host:と書かれたエラーメッセージが出ます。対応としては、以下のドキュメントにあるようにconfig.hostsにAzure Web Appsのドメインを追加するだけです。

guides.rubyonrails.org

具体的には、config/environments/production.rbRails.application.configure doの内側に以下の記述を追加します。

config.hosts << ".azurewebsites.net"

最初にピリオドをつけることで、すべてのサブドメインを許可することができます。

環境変数の設定

環境変数の設定も必要です。今回設定したのは以下のものです。

  • RAILS_LOG_TO_STDOUT
    • ログを標準出力に出力する。値は1でもtrueでも何でも良い。設定されていることが大事。
  • RAILS_MASTER_KEY
    • credentialファイルのマスターキー。ローカルにあるconfig/master.keyの中身の値を設定する。
  • RAILS_SERVE_STATIC_FILES
    • Railsに静的ファイルの配信をお願いする。値は1でもtrueでも何でも良い。設定されていることが大事。
  • WEBSITES_PORT
    • Railsアプリが開いているポート番号3000を指定。

少しハマったのは、RAILS_MASTER_KEYの設定です。これを設定してなかったので、アプリにアクセスしたときにAn unhandled lowlevel error occurred. The application logs may have details.と出てしばらく悩みました。credentialの設定はRails 4.1ぐらいからいろいろと変更されていたので、最新のRailsではどのような設定をするかよくわかりませんでした。

ここら辺は以下のRails Guideを参照するか

railsguides.jp

パーフェクトRuby on Rails 【増補改訂版】のP152ぐらいからの記述に詳しく書かれていますので、参照されることをお勧めします。

またWEBSITES_PORTは以下のドキュメントには指定する必要がある旨が書かれているので設定していますが、私の場合、設定しなくても動くことが多いです。必要な場合と不要な場合の条件についてはよくわかっていません。

docs.microsoft.com

結果としてAzure Web Appsの「アプリケーション設定」は以下のようになりました。

f:id:miyohide:20210724213006p:plain

上記の設定でRails 6.1で作られたアプリをAzure Web Appsで動かすことができました。