How to install Sidekiq to a Ruby on Rails project deployed on Dokku server
This minipost will guide you through all the required steps needed in order to successfully deploy a sidekiq service on a Ruby on Rails application. We will focus on herokuish servers, try to cover both Heroku and Dokku implementations, that are pretty much the same.
To start with, add Sidekiq gem to your Gemfile
, by:
# Sidekiq gem 'sidekiq', '~> 5.2.5'
and run:
$ bundle install
inside the project directory.
Add the file config/initializers/sidekiq.rb
and paste the following configuration content:
Sidekiq.configure_server do |config| config.redis = { url: "#{ENV['REDIS_URL']}/#{ENV['REDIS_SIDEKIQ_DB']}" } end Sidekiq.configure_client do |config| config.redis = { url: "#{ENV['REDIS_URL']}/#{ENV['REDIS_SIDEKIQ_DB']}" } end
The project we are working on has the following characteristics:
ruby 2.6.1p33 rails 5.2.2 bundler 2.0.1
To support this setup, a custom buildpack is required on dokku server. Therefore, login to your Dokku server as deploy user and run the following:
dokku config:set --no-restart appname BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby.git#v199
At the latest version of the buildpack is 199, feel free to check github for the latest release version. With this BUILDPACK_URL
you will get a herokuish deployment:
-----> Cleaning up... -----> Building appname from herokuish... -----> Adding BUILD_ENV to build environment... -----> Fetching custom buildpack -----> Ruby app detected -----> Compiling Ruby/Rails -----> Using Ruby version: ruby-2.6.1 -----> Installing dependencies using bundler 2.0.1
On your Dokku server create a redis service for the application, type:
dokku redis:create redis-appname
(where appname
your RoR application name)
Waiting for container to be ready =====> Redis container created: redis-appname =====> Container Information Config dir: /var/lib/dokku/services/redis/redis-appname/config Data dir: /var/lib/dokku/services/redis/redis-appname/data Dsn: redis://redis-appname:XXXXXXXXXXXXXXXXXXXXXX@dokku-redis-redis-appname:6379 Exposed ports: - Id: XXXXXXXXXXXXXXXXXXXXXX Internal ip: XXX.XX.X.X Links: - Service root: /var/lib/dokku/services/redis/redis-appname Status: running Version: redis:4.0.11
LInk redis service to your application(appname
), by:
dokku redis:link redis-appname appname
-----> Setting config vars REDIS_URL: redis://redis-appname:995@dokku-redis-redis-appname:6379 -----> Restarting app appname -----> Releasing appname (dokku/appname:latest)... -----> Deploying appname (dokku/appname:latest)... -----> App Procfile file found (/home/dokku/appname/DOKKU_PROCFILE) -----> DOKKU_SCALE file found (/home/dokku/appname/DOKKU_SCALE) =====> web=1 -----> Attempting pre-flight checks For more efficient zero downtime deployments, create a file CHECKS. See http://dokku.viewdocs.io/dokku/deployment/zero-downtime-deploys/ for examples CHECKS file not found in container: Running simple container check... -----> Waiting for 10 seconds ...
Add Sidekiq configuration(config/sidekiq.yml
) file:
--- :concurrency: 5 production: :concurrency: 5 :queues: - default - mailers - broadcasters
In the above snippet, I have used one more queue than :default
and :mailers
. Feel free to add below, all the queues you are using.
Add the relevant routes for Sidekiq UI to be mounted(config/routes.rb
):
Rails.application.routes.draw do require 'sidekiq/web' # ---------------------------------------------------------------------- # Monitoring scope :monitoring do # Sidekiq Basic Auth from routes on production environment Sidekiq::Web.use Rack::Auth::Basic do |username, password| ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_AUTH_USERNAME"])) & ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_AUTH_PASSWORD"])) end if Rails.env.production? mount Sidekiq::Web, at: '/sidekiq' end # ---------------------------------------------------------------------- end
In the above, I have used Sidekiq Basic HTTP Authentication from Rails Routes that requires two env vars
, that will be set at a later step, on the Dokku server.
Update Ruby on Rails config.ru
file:
# This file is used by Rack-based servers to start the application. require_relative 'config/environment' # Sidekiq require 'sidekiq/web' run Sidekiq::Web run Rails.application
Configure application.rb to use Sidekiq as the ActiveJob Queue adapter(config/application.rb):
class Application < Rails::Application # Active Job adapter config.active_job.queue_adapter = :sidekiq end
Add to your Procfile
the following worker line:
worker: bundle exec sidekiq -C config/sidekiq.yml
Go to Dokku server and set all the required environment variables with --no-restart
flag:
dokku config:set --no-restart appname REDIS_SIDEKIQ_DB=1 SIDEKIQ_AUTH_USERNAME=sidekiq SIDEKIQ_AUTH_PASSWORD=12345
With the --no-restart
flag, the env vars
will be available on the next deployment. Commit all the above changes on the project and deploy the code to Dokku server, by:
$ git push dokku master
After deployment succeeds, scale your application to initiate the worker responsible for Sidekiq:
dokku ps:scale appname web=1 worker=1
Navigate to the application’s URL to check that Sidekiq UI is working. If you have followed the setup in this guide, your Sidekiq UI should be available at a url like the following:
https://www.appname.com/monitoring/sidekiq