Madogiwa Blog

主に技術系の学習メモに使っていきます。

Heroku:Free DynoでRailsアプリケーションとSidekiqを動かすMEMO📝

HerokuでRailsアプリケーションを運用しているのですが、Sidekiqを導入するときにredisを構築したり、sidekiqのプロセスを立ち上げたり、色々と調べることがあったので、そのあたりの内容をメモしておきます📝

pumaからhookしてsidekiqのプロセスをwebのdynoのインスタンス上で立ち上げる方法もあるようですが、今回はsidekiq用のプロセスタイプを別に定義して構築する方法を記述しています。

bilalbudhani.com

freeプランでもプロセスタイプ数は2つまで無料のようなので・・・!

jp.heroku.com

Heroku Redisの導入

Sidekiqを利用するためにHeroku Redisを使ってRedisを構築します。

devcenter.heroku.com

Heroku RedisはHobby Devであれば無料で構築できます。

導入は簡単で以下のコマンドを実行するかHerokuのダッシュボードから手動で構築することができます。

$ heroku addons:create heroku-redis:hobby-dev -a your-app-name --version your-redis-version

※デフォルトだと6.0系がインストールされるようです👀(2021/03/28時点)

構築は数分で終わって完了すると環境変数REDIS_URLに構築したHeroku Redisへの接続情報が自動的に設定されます。(便利✨)

As of Redis version 6, Hobby plans support both TLS and unencrypted connections, while production plans require TLS connections.

https://devcenter.heroku.com/articles/heroku-redis#create-a-new-instance

redis 6以降のredisを構築すると、REDIS_TLS_URLも同時に環境変数に定義され、こちらを利用するとTLSを活用した暗号化もサポートされているようです👀

sidekiqの導入

SidekiqのWiki等を参考にgemをインストールします。

gam 'sidekiq'

私は以下のような設定ファイルをconfig/sidekiq.ymlに置きましたが、このへんは好みなので設置せずに実行時に指定するなり、諸々対応します。

---
:concurrency: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
:queues:
  - high
  - default
  - low
development:
  :logfile: log/sidekiq.log
  :pidfile: tmp/pids/sidekiq.pid

あとはroutesにSidekiqの管理画面をmountして、initializerの中でベーシック認証を追加しておきます。

Rails.application.routes.draw do
  require 'sidekiq/web'
  mount Sidekiq::Web, at: '/sidekiq'
end
require 'sidekiq/web'

# NOTE: Sidekiqのwebuiにベーシック認証をかける
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  [user, password] == [ENV['BASIC_AUTH_USER'], ENV['BASIC_AUTH_PASSWORD']]
end

※ SidekiqはデフォルトでREDIS_URLを参照してくれるので接続情報等の設定はなくても大丈夫です。

You may also use the generic REDIS_URL which may be set to your own private Redis server. Using Redis · mperham/sidekiq Wiki · GitHub

Sidekiq用のプロセスタイプを定義

プロジェクトのルートに以下を記載したProcfileを用意してSidekiq用のworkerのプロセスタイプを定義し、herokuにpushします。

web: bin/rails server -p ${PORT:-5000} -e $RAILS_ENV
worker: bundle exec sidekiq

HerokuはこのProcfileに記載されたプロセスタイプごとにインスタンスを生成するようです。

devcenter.heroku.com

sidekiq用のインスタンスを構築する。

以下のコマンドを実行し、HerokuにRailsアプリケーションが動作するwebとSidekiqが動作するworkerインスタンスを1つずつ立ち上げます。

$ heroku ps:scale web=1 worker=1

※ 前述の「 Sidekiq用のプロセスタイプを定義」を実施しないとコマンド実行時に以下のエラーが発生します。前述の通り。Herokuはプロセスタイプに従ってインスタンス化するようなので、事前にProcfileにプロセスタイプを定義する必要があるようです👀

$ heroku ps:scale web=1 worker=1
Scaling dynos... !
 ▸    Couldn't find that process type (worker).

これでHerokuでRailsアプリケーションとSidekiqを起動することができました🙌

以下のようなコマンドを実行してJobをエンキューして無事に処理されることを確認できれば問題なさそうです。

$ heroku run bin/rails c -e production
$ MySampleJob.perform_later

おわりに

Herokuの無料プランでSidekiqまで動かせると思っていなかったのですが、ここまで出来るとは・・・!

参考

yutojp.com

uesaiso.netlify.app

sunday-morning.app