RenderでRails×Sidekiqをデプロイする

# はじめに
こんにちは！オンラインスクールに通うプログラミング初学者のくりと申します🐣

個人開発で指定した時刻にLINEプッシュ通知を送る機能を実装しました。
このLINEプッシュ通知をバックグラウンド処理を行うために**ActiveJob+ Sidekiq(Redis)**を使用しましたが、その後のRenderへのデプロイでつまずいてしまいました。

そこで、本記事ではRenderへのデプロイの手順と解決策を備忘録としてまとめます。


:::note warn
間違いやより良い方法がありましたら、コメント等で教えていただけますと幸いです🙇‍♀️
:::

# 概要
指定した時間にLINEプッシュ通知を送信する機能をバックグラウンド処理させるためにSidekiqを導入しました。
RenderでSidekiqを動かすための環境としてBackground WorkerとKey Value Instanceを作成する必要があったため、本記事ではその環境構築部分を紹介させていただきます。

:::note warn
本記事では、RenderのGUIを使って手動でデプロイする方法を紹介します
別の方法として、render.yml を作成してデプロイする方法もあります
:::

**参考：Use render.yaml to Deploy**

https://render.com/docs/deploy-sidekiq-worker#use-renderyaml-to-deploy

### 前提
ローカルの開発環境でのActiveJob + Sidekiq（Redis）を使用したLINEプッシュ通知機能の実装は完了している状態で進めます。
LINEプッシュ通知機能の実装方法については、他の方のとてもわかりやすい記事がありますので紹介させていただきます。

https://zenn.dev/yukimura_n/articles/4f492c85bc7b28


### 環境
- Docker
- Ruby 3.2.3
- Rails 7.2.1
- PostgreSQL
- Render

### 実装手順
1. RenderでKey Value Instanceを作成
2. RailsとWeb Serviceに環境変数を設定
3. RenderでBackground Workerを作成

:::note warn
既にWeb ServiceとPostgreSQLのデプロイが完了している前提で進めます
:::

# 1．RenderでKey Value Instanceを作成
DashboardからKey Valueを選択し、新しく作成します。
[![Image from Gyazo](https://i.gyazo.com/26f33f19d6a608f71df6d150fd4d1193.png)](https://gyazo.com/26f33f19d6a608f71df6d150fd4d1193)

ドキュメントに沿って以下を選択します。
 <table>
    <tr>
      <td>Maxmemory Policy</td>
      <td>noeviction (recommended for queues/persistence)</td>
    </tr>
    <tr>
      <td>Plan</td>
      <td>Starter($10)</td>
    </tr>
 </table>
 
公式によると`noeviction`は Key Value instanceのメモリがいっぱいになった際、タスクを削除しないようにする設定のようです。 

:::note warn
Sidekiqで使用するKey Valueの作成に課金が必要です
Free Planで作成した場合は、バックアップされず再起動するたびにそのデータがすべて失われてしまいます
:::

Free Planの制限についてはドキュメントの以下のページに記載がありました。

https://render.com/docs/free#free-key-value


必須項目を入力し「Create Key Value Instance」を押下すると、KeyValueが作成されます。

その後、`redis://red-xxxxxxxxxxxxxxxxxxxx:6379`のような形で「Internal Key Value URL」が発行されます。
後ほどWeb Service,Background Workerとの接続で使用します。


# 2．RailsとWeb Serviceに環境変数を設定
## Rails側の設定
### Sidekiqの設定ファイルを編集
Sidekiqの公式ドキュメントにあるように、Sidekiqはデフォルトでローカル環境のRedisの`redis://localhost:6379`に接続しようとするため、本番環境ではRender上で設定する環境変数を参照するように設定します。
```ruby:config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: Rails.env.production? ? ENV.fetch("REDIS_URL", nil) : ENV["REDIS_URL_DEVELOPMENT"] }
end

Sidekiq.configure_client do |config|
  config.redis = { url: Rails.env.production? ? ENV.fetch("REDIS_URL", nil) : ENV["REDIS_URL_DEVELOPMENT"] }
end

```
https://github.com/sidekiq/sidekiq/wiki/Using-Redis

## Render側の設定
### Web Serviceに環境変数を設定
RenderのWeb Serviceの環境変数に、Internal Key Value URLを設定します。

[![Image from Gyazo](https://i.gyazo.com/0434846d417db63b3d2734d80a92b72e.png)](https://gyazo.com/0434846d417db63b3d2734d80a92b72e)

# 3．RenderでBackground Workerを作成

:::note warn
Background Workerの作成には課金が必要です
:::

### Background Workerの作成
DashboardでBackground Workerを選択し、新しく作成します。
[![Image from Gyazo](https://i.gyazo.com/0a960e717db87bb54b838d6bc7d647f1.png)](https://gyazo.com/0a960e717db87bb54b838d6bc7d647f1)

ドキュメントに沿って以下を選択・入力します。
 <table>
    <tr>
      <td>Language</td>
      <td>Ruby</td>
    </tr>
    <tr>
      <td>Build Command</td>
      <td>bundle install</td>
    </tr>
    <tr>
      <td>Start Command</td>
      <td>bundle exec sidekiq</td>
    </tr>
 </table>

### 環境変数の設定
必要な環境変数を設定します。

- DATABASE_URL：接続しているDB(PostgresSQL等)のInternal Database URL
- RAILS_MASTER_KEY：config/master.keyの値
- REDIS_URL：先ほど作成したInternal Key Value URL
- その他必要な環境変数

[![Image from Gyazo](https://i.gyazo.com/462c5bb6244c922dd18a1b580bed38e6.png)](https://gyazo.com/462c5bb6244c922dd18a1b580bed38e6)

:::note warn
起動に必要な環境変数が不足している場合、正常に起動しません
:::
私は最初Background Workerが起動しない事象が発生しました。
Background WorkerのLogsに以下のログが出力されており、必要な環境変数が不足していることが原因でした。
```
Missing required arguments: aws_access_key_id, aws_secret_access_key
```
<details><summary>なぜAWSのアクセスキーが必要だったのか？</summary>
前提として、私のアプリではcarrierwaveというライブラリで画像をアップロードし、外部ストレージにAWS S3を使用していました。

carrierwaveの設定ファイル(config/initializers/carrierwave.rb)にて
本番環境ではAWSの環境変数を参照するように設定しているため、Renderでのデプロイ時にAWSの環境変数が必要になります。

Background WorkerではWeb Serviceと同じリポジトリを別サーバーでデプロイするため、
Web Serviceと同様にAWSの環境変数が必要でした。
</details>

### Background Workerをデプロイ
デプロイ後に正常に動作している場合、すでに設定したジョブがあればログ上で確認できます。

私の場合はリマインダー設定したタイミングでジョブを作成し、リマインダーで設定した時刻になったらジョブが実行するようにしているため、デプロイした時点では以下のように`Schedule empty!`と表示されています。
[![Image from Gyazo](https://i.gyazo.com/e6c04bd23f81ab3591c1566b4b801e29.png)](https://gyazo.com/e6c04bd23f81ab3591c1566b4b801e29)

本番環境でリマインダー設定の操作を行うことで、
ジョブ作成時はWeb ServiceのLogsで、
ジョブ実行時はBackground WorkerのLogsでそれぞれ確認できました。


# 最後に
RailsでSidekiqを導入し、バックグラウンド処理を実装する際、本番環境ではBackground Workerの設定が必要になります。今回、初めてのデプロイに少し手間取りましたが、その分多くの学びがありました。
Renderについて、まだまだ理解が浅いので、引き続き学習を深めていきます！

最後までご覧いただきありがとうございました🌷

# 参考・引用資料
### 引用
https://render.com/docs/deploy-rails-sidekiq

### 参考
https://render.com/docs/deploy-sidekiq-worker

https://zenn.dev/yukimura_n/articles/4f492c85bc7b28

https://zenn.dev/yukimura_n/articles/181c85d127fb10

https://zenn.dev/katsumanarisawa/articles/c9da48652f399d#sidekiq%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4

https://qiita.com/lemonade_37/items/296bc211cf3e781c5600

https://zenn.dev/yoiyoicho/articles/03863702867eb0

https://qiita.com/YutoYasunaga/items/67d611b367a45d4d42ea