Deploy a Rails app with Sidekiq in Heroku
This post will show you how to deploy a Rails app with Sidekiq in Heroku, there is two ways of doing this:
-
In the web dyno:
Heroku works with dynos ti handle their resources, in this way they give you thw web dyno for free, if you add more dynos in the platform it begin to be paid. What we will dois to set Sidekiq to run inside the same dyno as your server. It's important to mention that is not the recommended way of doing for production apps. As is well known Sidekiq works with Redis for enqueue his jobs, so you have to install a Redis add-on in Heroku, I recommend this two Heroku Redis or Redis Cloud.
To setting up Puma and work with Sidekiq we have to create this file config/puma.rb, and put the following:
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } workers ENV.fetch("WEB_CONCURRENCY") { 2 } preload_app! before_fork do @sidekiq_pid ||= spawn('bundle exec sidekiq -t 25') end on_worker_boot do ActiveRecord::Base.establish_connection if defined?(ActiveRecord) end on_restart do Sidekiq.redis.shutdown { |conn| conn.close } end
Edit or create a Procfile in the root of the project and write the following:
web: bundle exec puma -C config/puma.rb
Save and deploy to heroku.
-
Worker dyno:
This one is the recommended way of working with Sidekiq and Heroku because it work in a different process to the web server, if for some reason one is down the other will be working. With this way you also need to install a Redis add-on. Follow the same instructions that the first step. After Redis has been instaled create this file config/sidekiq.yml and put the following:
development: :concurrency: 5 production: :concurrency: 3 :queues: - default
In :queues: section you have to put the queues the app use.
Setting up connection between Redis and Sidekiq, inside config/initializers/sidekiq.rb put the following:
if Rails.env.development? Sidekiq.configure_server do |config| config.redis = { url: 'redis://localhost:6379' } end end if Rails.env.production? Sidekiq.configure_client do |config| config.redis = { url: ENV['REDIS_URL'], size: 2 } end Sidekiq.configure_server do |config| config.redis = { url: ENV['REDIS_URL'], size: 20 } end end
Remember to put in the environment variables in Heroku the Redis address under the name REDIS_URL
In order to Heroku take in count this settings and mount it inside a worker dyno wu must put the following in the Procfile:
web: bundle exec puma -C config/puma.rb worker: bundle exec sidekiq -e production -t 25 -C config/sidekiq.yml
And we are done!, We succesfully set up a Rails app with Sidekiq.
Any doubt, advice or correctio, you can comment below.