My Day One

毎日東京の隅っこでコードを書いているエンジニアのブログです。

Herokuの代替サービスであるrender.com でRailsアプリをデプロイする

本記事の内容

  • Herokuの代替サービスになりうる render.com を使ったデプロイの方法をまとめています
  • Railsで作成した簡単なCRUD機能を搭載したアプリを render.com にデプロイするまでの手順を説明します
  • Redisなどを使った実装や設定は含まれていないので、ご了承ください

前提

  • 何らかのRailsアプリが開発環境で正しく動作するようになっている
  • RailsアプリのRDBMSPostgreSQLを使っている
  • render.com へのアカウント登録が済んでいる
  • 開発している言語やフレームワークのバージョンは、Ruby 3.1.2、Rails 6.1.6

render.com とは

Herokuと似た、WebアプリやWebサイトなどを簡単にWeb上に公開できるツールの1つです。render.com のサイトでは Render vs Heroku にあるように、Herokuをかなり意識したサービスになっています。 この比較のページでは、Herokuよりも簡単でフレキシブル、その上料金も安いよ!というような内容が書かれています。

後で詳しく書きますが、基本的にはアプリケーション側のコードを少し書き換えて、ポチポチと設定していくだけでアプリを本番環境に反映することができる素敵なサービスです。

細かいHerokuとの比較は、日本語で書かれたこちら の記事がとても詳しくて分かりやすいので、興味のある方はご覧ください。

render.com の料金体系

2022年9月時点での情報ですが、$0 (無料)から利用できます。 Webサイトや基本的な構成のWebアプリであれば、お金のことを気にせず個人開発のアプリのデプロイなどに使うことができます。

ただ、無料の場合はいくつか気を付けなくてはならない点があります。 1つ目は、アプリケーションが非アクティブの状態が15 分間続くと自動的に停止され、次の新しいリクエストが来た時に再開する、という仕組みになっており、これが起きると、ページにアクセスして20-30秒後にレスポンスが返ってくるようになってしまいます。これはさすがに遅すぎてよくないので、ひとまず個人開発のポートフォリオを作っていて、本番環境にデプロイを試したい、というレベルでなければ有料にした方が良いと思います。(特にユーザーがすぐについてほしいと思っている場合など)

2つ目は、デプロイまでにかかる時間が有料に比べて遅いということ。ちゃんと計測したわけではないですが、無料の場合、ものすごく簡素なRailsアプリをデプロイするのに4-5分かかるのに対して有料にすると2分程度でデプロイまでされていましたので、開発上のストレスという点でも有料の方が良いです。

3つ目は、これはデータベースを使うWebアプリに限った話になるのですが、PostgreSQLの無料期間は3ヶ月であり、それを超えると月$7 からの有料プランにアップグレードする必要があります。

無料でWebサイトやWebアプリを簡単にWeb上に公開できる!という点は確かにそうなのですが、いくつかの条件付きで、という観点は頭に入れておく必要があります。

有料プランを使った場合でも、2022年9月時点でのHerokuの有料版の最安値と比較すると、render.com の方が安いと思いますので、料金面でも若干お財布に優しいサービスであると思います。 (HerokuはDyno + Heroku Postgres、render.comは Services + PostgreSQLの最安値プランの合計値の比較)

Heroku render.com
$7 + $9 = $16 $7 + $7 = $14

と、ここまでは render.com の紹介を主にしてきましたが、次の節からはいよいよデプロイ手順を説明します。 基本的にはドキュメントの通りにやれば良いのですが、初心者の方でも分かりやすいようにできるだけ丁寧に説明していきます。

render.comを使ったデプロイ手順

ここからは、render.com にアカウント登録を済ませているという前提で話を進めていきますので、もしまだ登録されていない方がいましたら先に登録をお願いします。

render.com にWebアプリケーションをデプロイする場合、Web Serviceの作成とデータベースの作成をする必要があります。そのため、設定の内容を2つのパートに分けて説明します。

render.com 側の設定(Web Serviceの作成)

まずはWeb Serviceの作成です。

はじめに、render.com のDashboardに進みます。右上にある+Newのボタンを押して、Web Serviceを選択します。

すると、GitHubなどと連携するためのページに進むので、GitHubとの連携をして、対象のリポジトリを選びます。

対象のリポジトリについては全てを対象にすることもできますし、自分で選択したもののみを設定することもできます。 以下の画面は、私のGitHubのページの設定です。1つのリポジトリのみを設定しています。

対象のリポジトリを選択したら、いくつか必要な設定をすることになりますので、以下を参考に入力してみてください。

  • Name: 何でもいいですが、わかりやすい名前にしておきましょう。こちらは後から変更可能です
  • Environment: Railsのアプリをデプロイする前提なので、Rubyを選びます
  • Region: 現状、東京リージョンがないのでシンガポールを選びましょう。(2022年に東京リージョンも追加される予定とのこと)
  • Branch: デプロイしたいブランチを設定できます。mainで良いと思いますが、とりあえず別ブランチで試したいという方は別ブランチを設定すればOKです。あとから変更可)
  • Build Command: 一旦デフォルトのままで問題ありません。
  • Start Command: こちらも一旦デフォルトのままで問題ありません。
  • Advanced: 環境変数などの設定ができます。こちらも後から変更可能です。(最低限、master_keyの設定は後で必須となります)

設定画面のイメージは以下です。

いきなりお金がかかると嫌という方もいると思いますので、ひとまずfreeプランを選択して先に進みます。

問題なくWeb serviceが作成されたと思いますが、最後に、Railsのアプリケーションを本番環境でデプロイする際に必要な RAILS_MASTER_KEY を設定しておきます。

先ほどのAdvancedの箇所でも設定できるので、すでにやっている方は読み飛ばしてください。

Dashboardに戻ると、先ほど作成したWeb Serviceが一覧に表示されているかと思いますので、そちらをクリックします。

遷移した先のページの真ん中あたりにずらっとタブが並んでいて、その中のEnviromentをクリックします。

Environmentをクリックすると、本番環境用の環境変数の設定ができる画面に遷移するので、RAILS_MASTER_KEY の値に config/master.key に書かれている値を設定し、Save Changesをクリックします。(これを設定しておかないと、デプロイができません)

ひとまず、ここまでで、render.comのWeb Serviceの作成は終了となります。

render.com 側の設定(データベース作成)

続いて、データベースの作成と設定をします。こちらも先ほどと同様に render.com の画面から行います。

先ほどのWeb Serviceの作成と同様に、Dashboardの右上にある +New ボタンを押して、PostgreSQLを選択します。

すると、以下のような画面に遷移します。

入力項目は

  • Name: render.com 上で表示されるDBの名前です。後で変更できます。
  • Database: PostgreSQL の dbnameを設定します。
  • User: PostgreSQL接続時に必要なユーザー名です。
  • Region: Web serviceと同じ項目です。シンガポールを選択しましょう。
  • PostgreSQL Version: PostgreSQLのバージョンです。デフォルトで14になっていますが、必要に応じて変更しましょう。

注意事項として、Database, User、PostgreSQL Versionはあとから変更できないはずなので、設定時には気をつけましょう。もし間違えてしまった場合は、データベースを一度消して、再度作り直せば問題なく修正できます。

上記の必要な情報を入力していき、Create Database ボタンを押します。少し待つとstatusがAvailableになり、データベースが使えるようになります。

これで、データベースの作成も完了しました。

ここまでは、render.com側でRailsアプリをデプロイするための準備をしましたが、ここから先はRailsアプリ側に必要な設定を行なっていきます。一部コードを書き換える必要があるので、その点はご注意ください。

Railsアプリ側の設定

Railsアプリ側の設定については、ドキュメントを読みながら進めていくこともできます。

基本的にドキュメントを翻訳した形になりますが、この記事でもRailsアプリ側の設定内容を説明していきます。

1. config/database.ymlの編集

  • productionのセクションに行き、DATABASE_URLの環境変数を使うようにします。
production:
  # 他の記述がある場合はそれもそのまま残しておく
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

2.config/puma.rbの編集

  • workers ENV.fetch("WEB_CONCURRENCY") の記述を追記します。(コメントアウトを外して数値を4に変更します)
  • preload_app! の記述を追記します(コメントアウトを外します)
(中略)
workers ENV.fetch("WEB_CONCURRENCY") { 4 }
(中略)
preload_app!

3.config/environments/production.rbの編集

  • RENDER環境変数(これは常にRenderにある)が存在する場合、パブリックファイルサーバーを有効にします。
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? || ENV['RENDER'].present?

4.ビルド用のscriptを作成する

  • アプリのビルドに必要なコマンドを実行できるように設定します。
  • bin/render-build.sh を作成します(binフォルダ配下にrender-build.shというファイルを作成)
  • bin/render-build.sh の内容は以下の通りです。
#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
bundle exec rake assets:precompile
bundle exec rake assets:clean
bundle exec rake db:migrate
  • 以下のコマンドで、bin/render-build.sh の実行権限を設定しておきます。
chmod a+x bin/render-build.sh
  • 上記の内容を全て変更し、Gitリポジトリの対象ブランチにpushすれば、renderを使ってデプロイが始まります。

数分待ち、Dashboard内のWeb serviceの欄にDeploy Succeeded という表示があれば完了です!🎉

デプロイが失敗した時のエラー(私の場合)

私は最初にデプロイした時にエラーになり、 ! Unable to load application: LoadError: cannot load such file -- net/imap のようなエラーが出たのですが、こちら の記事と同じ対処法で解決しました。

Blueprintsを使ったデプロイについて

実は、render.com で Webアプリをデプロイするには、先ほど説明したダッシュボードを使用してサービスを手動で設定する方法と、render.yaml ファイルでリポジトリ内のサービスを宣言する方法との 2 つがあります。

この後者の方法を使うために利用されるのがBlueprintsという機能です。

これを使うメリットとしては

  • アプリケーションの構成をわかりやすくひとまとめにすることができる
  • Render.com にどのような構成のサービスを作成するかを管理することができる

という点が挙げられるでしょう。Infrastructure as code(IaC) を render.com で実現できるということですね。便利です。

Blueprintsを利用する手順は以下の通りで、とてもシンプルです。

  • ルートディレクトリに render.yaml という名前のファイルを作成する。(このファイルには、RailsのWeb サービスと、アプリケーションで使用されるデータベースに関する情報が含まれます)
  • render.yamlを以下のように編集して、mainブランチに pushしておく
databases:
# mysiteは設定した際の内容を確認して書き換える
  - name: mysite
    databaseName: mysite
    user: mysite

services:
  - type: web
    name: mysite
    env: ruby
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: mysite
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false
  • pushしたら render.com の DashboardからBlueprintのページに移動して、New Blueprint Instance ボタンをクリックします。

対象のリポジトリを選択し、デプロイ ウィンドウで、RAILS_MASTER_KEY の値を config/master.key ファイルの内容に設定した上で、Update Existing Resourcesをクリックするとデプロイがスタートします。

こんな感じで、単にデプロイするだけであればそんなに大きな労力を割くことなく進めることができるため、Herokuの代替サービスには確かになるなと思いました。

長くなってしまったので今回の記事はここまでにして、次回は render.com を使ったカスタムドメインの設定を書きたいと思います。