【誰でも簡単】RailsアプリをRender.comでデプロイする手順まとめ



# はじめに
こんにちは

普段herokuを使うことが多いのですが、この前のGithubアクセストークン流出問題もあり、herokuに代わるサービスとして気になっていたRender.comを触ってみたので、簡単な手順やポイントなどを書き留めておこうと思います📝

Render.comを使ってみたい人の一助になれば嬉しいです

↓トークン流出問題の記事

https://gigazine.net/news/20220418-github-heroku-travis-ci-npm-oauth/

（ターゲットは初心者〜中級者向けを意識しています）



# 取り上げる内容（取り上げない内容）

本記事で説明するのは以下についてです。
* Render.comでのRailsアプリのデプロイ方法
* 上記にあたり少し注意する点など（初見では気づきにくい部分）



以下については説明しません（後ほど別記事などで追加するかもしれません）
* Railsアプリの作り方
* Rails以外のアプリでのデプロイ方法
* Dockerを使ったデプロイ方法
* redisの設定
* cronの設定
* CI/CDの設定
* 独自ドメインの設定方法
* 最適な料金プランの選び方

（全部書くとキリがないのでこの辺で）


# 環境
ローカルで使用した各環境は以下のとおりです

* アプリケーション関連
    * Ruby on Rails 7.0.2.2
    * Ruby 3.1.0
    * PostgreSQL 14.2
    * Bundler 2.3.4
    * yarn 1.22.18
    * node.js 16.14.2
* ハード関連
    * macOS Monterey 12.3.1
    * Apple M1 Pro


サンプルアプリはGithubのリンクを載せておくので、この記事どおりに試したい方は適当にcloneして使ってください
https://github.com/koki-73/rails7_sample


# デプロイ手順

デプロイ手順は公式のガイドがあるので基本的にはそちらを参照するようにしてください

https://render.com/docs/deploy-rails

あとはドキュメント見ればデプロイできますよーで終わってしまうと記事にする意味がないので、多少のアレンジした箇所も含めて少し詳しめに書いていきます

## デプロイ手順 その0. Railsアプリの作成
当たり前ですが、デプロイしたいアプリを作成する必要があります。
作成できたらGithubにpushしておきます（リポジトリはprivateでもpublicでもOKです）

アプリを作る上での注意事項としては
* DBはPostgreSQLを使うこと

ぐらいでしょうかね
（MySQLも使えるらしいのですが、ぱっと見やり方がわからなかったので基本ポスグレと考えてください）

あとはnodeのバージョン依存などがあるとうまくいかない場合があるかもしれません。
デフォルトでは`v14.17.0`が使われるようですが、自分で指定もできるようなので必要であれば`.nvmrc`を使うなり、`package.json`に書くなり適宜設定してもらえれば良いかと思います

https://render.com/docs/node-version


## デプロイ手順 その1. `Render.com`でポチポチ

### アカウント登録
まずはRender.comのアカウント登録をします
トップページの`GET STARTED`からアカウント登録しましょう

https://render.com/

### Webサービス作成
ログインしたらダッシュボードからwebサービスを作成します
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/e32ceabb-63b3-5f00-6362-d3c33d128403.png">

privateリポジトリを使う場合は事前にGithub連携させておく必要があります。その場合は説明にあるリンクを踏んで連携しておきましょう。
publicを使うならそのままリポジトリのURLを貼れば大丈夫です
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/28068b55-094e-e144-a34b-40469053fb11.png">

Github連携するかURLを入力すると、リポジトリ情報が入力フォームの下に現れるので、何も迷わずクリックすればOKです

続いていろいろ入力したり選んだりする画面になるので、好きなように設定します。（何もわからない方は以下ご参考まで）
* Name: サービスの名前になるのでわかりやすい名前にしておきましょう（あとから変更可）
* Environment: Rails使うなら当然のようにRubyを選びます
* Region: 一番日本に近いシンガポールを選んでおきましょう（将来東京リージョンも追加される予定らしいです）
* Branch: デプロイしたいブランチです。とりあえずmainで良いでしょう（あとから変更可）
* Build Command: あとから変更可なのでとりあえずデフォのままでOKです
* Start Command: これもあとから変更可なので適当で
* Plans: とりあえずFreeを選びます
* Advanced: 環境変数などの設定ができますが、あとからでもできるのでスルーで大丈夫です

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/c63792ea-02d7-89b8-f6b6-f7a2adae2919.png">
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/b4af85b4-10de-2675-8b12-e05a7626fa55.png">

全て入力できたら`Create Web Service`をクリックします。
問題なければデプロイが開始されますが、現時点で設定してないファイルなどがあるのでデプロイは失敗しますが一旦スルーしてください

この時点で`RAILS_MASTER_KEY`の環境変数も設定しておきましょう（設定忘れると後々デプロイでこけます）

あとは`TZ`の環境変数を`Asia/Tokyo`にしておきましょう。
これをしておかないと、DatabaseのtimespampがUTC時刻で記録されるため、少し扱いにくくなってしまいます。

マスターキーの設定は、ダッシュボードから作成したWeb Serviceを選択して、サイドバーのEnvironmentから設定すればOKです。
（サンプルアプリをクローンした方はmaster.keyを再作成して設定してください）
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/d0a93cfb-8486-28ac-a913-1ac061b7b4d0.png">



### Database作成
同じようにDBも準備します
`Database`, `Username`, `Version`はあとから変更できないので、少しだけ気をつけましょう（間違えたとしても作り直せば良いだけなので心配は無用です）

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/5dc689aa-15a5-3e78-cb24-8c3e40ff7764.png">

全て入力できたら`Create Database`をクリックすればDB作成が開始します。しばらくするとstatusがAvailableになるかと思います

ℹ️ 余談
後述するblueprintによるデプロイを使えば、ここで説明した手動でポチポチやる手順は不要なのですが、それだとdatabaseのfreeプランが使えないためこのようなやり方にしています。
ただ、databaseのfreeプランは90日までしか使えないみたいなので、無料で使うには限界がありそうです^^;


## デプロイ手順 その2. デプロイ用のファイルを用意など
ここは基本的に公式ドキュメントに則って進めます

### Render.comデプロイ用のファイル作成
続いて`bin/render-build.sh`を作成します。
このファイルはデプロイ時に実行されるスクリプトです。
`bundle install`やフロントのビルドコマンドなどはここに記載しておくと良いでしょう

ちなみにサンプルアプリでは以下のようにしています。

```sh:bin/render-build.sh
#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
yarn install
yarn build # jsファイルをesbuildでバンドルしているため
bundle exec rake assets:precompile # cssはsprocketsを使っているため
bundle exec ridgepole -c config/database.yml -E production --apply -f db/schemas/Schemafile # migrateはridgepoleを使っているため（標準のmigrateを使うならbundle exec rails db:migrateで良いかと思います）
```

ファイルの実行権限がないとスクリプト実行できないので一応以下のコマンドで権限設定しておくと良いです
```bash
$ chmod a+x bin/render-build.sh
```

次にrender.yamlを用意します（パスはRailsアプリ直下）
これを使うとBlueprintという機能を使ってデプロイすることができ、デプロイ周りの設定をまとめておけるので楽ちんです

最低限のサンプルを載せておきます
（name, userの部分は作成したwebサービス、DBで設定した値を設定すればOKです）
```yaml: render.yaml
databases:
  - name: rails7_sample_staging
    databaseName: rails7_sample_staging
    user: rails7_sample
    region: singapore

services:
  - type: web
    name: rails7-sample-staging
    env: ruby
    region: singapore
    plan: free
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: rails7_sample_staging
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false

```

### その他
Bundler 2.2.x以降を使用している場合は、適切なplatformを明示しておく必要があります。
（これをしないとデプロイ時のbundle installでこける）
```bash
$ bundle lock --add-platform x86_64-linux
```

あとはRender.com以外のホスティングでも同様ですが、hostの指定を設定しておく必要があります（Rails6以降から必須だっけかな）
```diff_ruby: config/application.rb
module AppName
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0
    # ...

    # デプロイするサービスのホストを追加する
+   config.hosts << 'xxx.onrender.com'
  end
end
```

## デプロイ手順 その3. push
ここまでできたらmainブランチにpushします。
pushするとrender.yamlの内容どおりに設定されてデプロイが自動で実行されます。
（RAILS_MASTER_KEYの設定を忘れていると落ちますので、失敗したら確認してみてください）

デプロイが成功したら実際にアクセスして確認しましょう！

ダッシュボード上のWeb Service詳細画面にURLが記載されているので、そこからアクセスすると良いでしょう
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/82e17e7c-ba48-daca-cdc0-dabd7b0cc3bc.png">

問題なく動いていれば成功です🎉

# 少し発展
普通はstaging環境とproduction環境を用意するので、そのへんの話を少しします。
databaseは使えるfreeプランが1つまでなので、ここから先はお金がかかります💰（$7 / month）
お試し用に作成してすぐ消せばたぶん10円ぐらいで済むので、やるだけやってみても損はないかと思います

### DB用意
片方freeプランのDBを使っていると、render.yamlに追記しただけではDBを勝手に作ってくれなかったので、production用のDBは手動で事前に用意します。（freeプラン使わなければここの手順は不要かもしれません）

一度作成したときと基本的には同じですが、クレカ登録が必要なのとstarterプラン以上のプランを選択する必要があるぐらいです

### render.yamlに追記
本番用DBを作成できたら`render.yaml`を編集します。
基本的にstagingと同様の項目でproduction用の設定を追加する感じです。

```yaml: render.yaml
databases:
  - name: rails7_sample_staging
    databaseName: rails7_sample_staging
    # ...
  # 以下追加
  - name: rails7_sample_production
    databaseName: rails7_sample_production
    user: rails7_sample
    region: singapore

services:
  - type: web
    name: rails7-sample-staging
    env: ruby
    # ...
  # 以下追加
  - type: web
    name: rails7-sample-production
    env: ruby
    region: singapore
    plan: free
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: rails7_sample_production
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false
    autoDeploy: false
```

ℹ️ 補足: productionの`autoDeploy: false`について
デフォルトだとmainブランチにpushされたタイミングでデプロイが実行されるようになっていますが、本番環境で自動デプロイされてしまう状況は少し怖いものです。

ダッシュボードからAuto Deployはオフにできますが、blueprintを使っており、かつblueprintのAuto Sync設定がYesになっている場合は、`render.yamlの変更を検知して設定を反映` → `autoDeployの記述がないとデフォ値のtrueで設定更新` → `本番環境のAuto DeployがYesになりデプロイが走る`ということになります。

一応Blueprintの設定でAuto Syncを`No`に設定しておけば回避できるのですが、念の為render.yamlでも明示的にオフにしておくことをオススメします

### push
render.yamlを修正したらpushします。
pushするとrender.yamlの内容どおりに本番環境が作成されます。（初回のみ自動でデプロイが走る）
ただし、RAILS_MASTER_KEYの環境変数を設定しておかないとデプロイで落ちるので、設定後に手動デプロイすると良いでしょう。
（もしくはenvironment groupsを使えば事前に共通の環境変数を設定できそうです　←すみません、試してません）

# その他
### ログ
ログを覗きたいときはダッシュボードのLogsから見れます。
検索もできるので割と使いやすいと思いますが、フィルターができないのでちょっと微妙かもしれません。
過去ログの保管をしたい場合は別サービスを使う必要があるので、ちょっと面倒でしょうか

### DBアクセス
TablePlusを使ってDBを覗きたい場合は、ダッシュボードのDB詳細にある`External Connection String`をコピーして、`import from URL`から貼り付ければ接続できます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/d0707e81-9411-065e-b19c-34770e9fc038.png">
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/fa416032-b615-a801-6d4d-033cd073d3cf.png">

### Github連携
privateリポジトリを使うにはGithubアカウントと連携する必要があるのですが、1つのGithubアカウントに連携できるRender.comアカウントは1つのみのようです。

herokuではアカウントを増やしてGithub連携すれば、privateリポジトリでも無料枠で複数稼働できたのですが、Render.comでは難しそうです（何か知見がある方いればコメント待ってます）

# 無料枠について
今回の記事を作るにあたり、なるべく無料でできる方法で試してみたのですが、無料のプランだといろいろ制限があるのでわかる範囲で書いておきます。
詳しくて正確な話は公式をご覧ください

https://render.com/docs/free

### Web Service

* アカウントに紐づく全てのサービスで、月ごとに合計750時間まで使用可能
* 15分アクセスがなければ停止し、停止後にアクセスがあると再起動に約30秒かかる
* 750時間に達すると、プランをアップグレードするか、制限時間リセット（毎月1日）されるまで停止状態になる


停止を回避する手段をいろいろ模索してみましたが、herokuみたいに定期実行を無料でできないので、無料でやるなら以下の方法ぐらいでしょうか（cron機能が有料なので。有料といえどかなり安いですが）
* 他で使っているアプリのherokuスケジューラで定期アクセスさせる
* AWS lambdaで定期アクセスする

他に何か方法あればコメントくださいませ

### Database

Datebaseに関しては以下の制約です（うーん厳しい。。）
* 90日で自動的に有効期限が切れ、アップグレードしない限り停止されて使えなくなる
* 90日のあと14日間の（アップグレードのための）猶予期間があり、それを過ぎると削除される
* 期限が近づくとメール通知される
* 1度にアクティブにできる無料DBは1つのみ

stagingはherokuでDBのみ作成して、DBはherokuを使うみたいなことは可能かもしれません。
（本末転倒感が否めないですが）

本番環境でも安く提供してるんだから、無料で済まそうとしないでねってことかなー笑
変にいろいろ設定して無料で頑張るよりも、多少お金払った方がお互いwin-winかもしれませんね

# 所感
ドキュメントが割と充実していたので、初見でもそこまでハマることなく使えました。
以下、herokuと比較してどうだったか、個人的感想を書いておきます

**料金**
無料で使うならherokuのほうがいろいろできます。
ただ、本番運用まで考えるとRender.comのほうが安いっぽいので状況によりけりでしょうかね。
一応herokuからのお引越しも簡単にできるっぽいので、まずは無料でherokuを使い、本番運用が見えてきた段階で移行するというのもありかもしれません。

**使い勝手**
以下の点でherokuのほうが使い勝手は上かなーと感じました。
* sentryやpapertrailなどのアドオンをサクッと用意できる
* パイプラインを使って、staging → 本番の反映が簡単

**その他**
名前はherokuのほうが伝わりやすいですね（renderだとrenderingの意味か固有名詞かわかりにくい）


上記勝手なことをいろいろ書きましたが、まだまだ試していない機能があるのでどっちがオススメとかは断定できないです😅

AWSで環境用意するよりは遥かに楽なので、一度使ってみてはいかがでしょうか
それではみなさま、良いインフラ管理ライフを〜


# 参考にした記事など
以下の記事を参考にさせていただきました。執筆者の方ありがとうございました。

https://zenn.dev/mc_chinju/articles/compare_render_and_heroku

https://zenn.dev/katsumanarisawa/articles/c9da48652f399d