Introduction#

Sidekiq is the standard in the Ruby ecosystem for background jobs. This short tutorial will show you how to set up Sidekiq in a Hanami application using Docker Compose.

For the basic setup, please look at my previous tutorial: Getting Started with Hanami and Docker Compose. We’ll modify that demo application to support Sidekiq.

Steps#

1. Add the Sidekiq gem#

⚡ bundle add sidekiq

2. Add a Sidekiq provider#

Add a Hanami provider for Sidekiq (config/providers/sidekiq.rb).

# frozen_string_literal: true

Hanami.app.register_provider(:sidekiq) do
  prepare do
    require "sidekiq"
  end

  start do
    Sidekiq.configure_client do |config|
      config.redis = {url: target["settings"].redis_url}
    end

    Sidekiq.configure_server do |config|
      config.redis = {url: target["settings"].redis_url}
    end
  end
end

3. Create a Base Job#

Create a convenience base class for the background jobs (app/job.rb).

# frozen_string_literal: true

require "sidekiq"

module Bookshelf
  class Job
    def self.inherited(base)
      super
      base.include(Sidekiq::Job)
    end
  end
end

4. Create a Background Job#

Create your first background job (app/jobs/index_book.rb).

# frozen_string_literal: true

module Bookshelf
  module Jobs
    class IndexBook < Bookshelf::Job
      def perform(_book_id)
        # simulate a long-running job
        sleep 5
      end
    end
  end
end

5. Configure Sidekiq with Docker Compose#

Add a config/boot.rb which Sidekiq will use to boot the app code.

# frozen_string_literal: true

require_relative "./app"

Hanami.boot

Add the sidekiq service to docker-compose.yml

# ...
  sidekiq:
    image: bookshelf
    volumes:
      - ./storage/redis/data:/data
    command: bundle exec sidekiq -r ./config/boot.rb
    env_file:
      - .env
    depends_on:
      - redis

6. Setup HTTP Sessions#

Set up HTTP Sessions (required by Sidekiq Web).

Add a SESSION_SECRET to .env:

# ...
SESSION_SECRET="..."

Add the corresponding setting to config/settings.rb:

# frozen_string_literal: true

module Bookshelf
  class Settings < Hanami::Settings
    # ...
    setting :session_secret, constructor: Types::String
  end
end

Enable HTTP Sessions into config/app.rb:

# frozen_string_literal: true

require "hanami"

module Bookshelf
  class App < Hanami::App
    # ...

    config.actions.sessions = :cookie, {
      key: "_bookshelf.session",
      secret: settings.session_secret,
      expire_after: 60 * 60 * 24 * 365
    }
  end
end

7. Mount Sidekiq Web#

Edit config/routes.rb:

# frozen_string_literal: true

require "sidekiq/web"

module Bookshelf
  class Routes < Hanami::Routes
    # ...
    mount Sidekiq::Web, at: "/sidekiq"
  end
end

8. Rebuild Docker image#

Rebuild the Docker image and restart Docker Compose.

⚡ docker build -t bookshelf .
⚡ docker compose down
⚡ docker compose up

9. Try it#

Visit http://localhost:2300/sidekiq. You should see the Sidekiq Web dashboard.

From another console, ssh into the Sidekiq container.

⚡ docker exec -it bookshelf-sidekiq-1 /bin/sh
# bundle exec hanami console

Then enqueue several times the job:

bookshelf[development]> Bookshelf::Jobs::IndexBook.perform_async("books:123")
# repeat several times

Go to the browser, and you should see the performed jobs.

Conclusion#

We set up Hanami with Sidekiq in few simple steps.

Update#

If you want to learn this topic from a different angle, check this Hanami Mastery episode.