Sidekiq¶
Guide for background mail delivery via Sidekiq on Ruby on Rails (Ruby 3.2+). Messages are sent to Mailexam SMTP from a worker through Action Mailer — convenient for notifications and CI without blocking the HTTP request.
The web layer enqueues a job; Sidekiq sends the message asynchronously (similar to Celery in Python).
What you need¶
- A Mailexam account and a project with SMTP credentials.
- A message broker — Redis (required by Sidekiq).
- Ruby 3.2+, Bundler, and a Rails application.
Copy from the welcome email (or dashboard) for your project:
YOUR_LOGIN— SMTP login (for example,xxxxx);YOUR_PASSWORD— SMTP password (a unique pair with the login);- host —
YOUR_LOGIN.mailexam.io(matches the login).
1. Dependencies¶
In Gemfile:
gem "rails", "~> 8.1"
gem "sidekiq", "~> 7.3"
gem "redis", "~> 5.0"
gem "dotenv-rails", groups: %i[development test]
Run Redis locally (Docker):
2. Environment variables¶
.env file in the project root:
REDIS_URL=redis://localhost:6379/0
MAILEXAM_LOGIN=YOUR_LOGIN
MAILEXAM_PASSWORD=YOUR_PASSWORD
MAILEXAM_PORT=587
MAIL_FROM=noreply@example.test
SMTP host: YOUR_LOGIN.mailexam.io.
3. Action Mailer configuration¶
Same as Ruby on Rails — config/initializers/mailexam_mailer.rb or environment-specific SMTP settings.
4. Sidekiq configuration¶
config/initializers/sidekiq.rb:
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end
Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end
config/sidekiq.yml:
Add worker autoload paths in config/application.rb:
config.autoload_paths << Rails.root.join("app/workers")
config.eager_load_paths << Rails.root.join("app/workers")
5. Mailer, worker, and route¶
Mailer (same as Rails example):
# app/mailers/test_mailer.rb
class TestMailer < ApplicationMailer
def test_email
@body = params[:body]
mail(
to: params[:to],
subject: params[:subject]
)
end
end
Worker:
# app/workers/mail_test_worker.rb
class MailTestWorker
include Sidekiq::Worker
def perform(to, subject, body)
TestMailer.with(
to: to,
subject: subject,
body: body
).test_email.deliver_now
end
end
Controller — enqueue instead of deliver_now:
# app/controllers/mail_controller.rb
class MailController < ApplicationController
def test
payload = JSON.parse(request.body.read.presence || "{}")
MailTestWorker.perform_async(
payload["to"].presence || "user@example.test",
payload["subject"].presence || "Sidekiq + Mailexam",
payload["body"].presence || payload["text"].presence || "Mailexam test from Sidekiq"
)
render json: { status: "ok", queued: true }
end
end
Start Redis, Sidekiq, and Rails:
curl -X POST http://127.0.0.1:3000/mail/test \
-H 'Content-Type: application/json' \
-d '{"to":"user@example.test","subject":"Test","body":"Hello"}'
The message will appear in the Mailexam dashboard → your project → inbox after the worker processes the job.
6. Local development and CI¶
| Environment | Recommendation |
|---|---|
local |
Redis + Sidekiq process + Rails server |
| CI | Redis service, REDIS_URL, and Mailexam secrets in pipeline variables |
Example for .gitlab-ci.yml:
variables:
REDIS_URL: redis://redis:6379/0
MAILEXAM_LOGIN: $MAILEXAM_LOGIN
MAILEXAM_PASSWORD: $MAILEXAM_PASSWORD
MAILEXAM_PORT: "587"
MAIL_FROM: "noreply@example.test"
After an integration test, verify delivery via the Mailexam API.
7. Common issues¶
Job queued but mail not sent
- Ensure Sidekiq is running.
- Check
REDIS_URLand Redis connectivity. - Inspect Sidekiq logs for SMTP errors.
TLS or authentication failed
- SMTP host must be
{login}.mailexam.io, same login as in the welcome email.
Message not in the dashboard
- View the inbox of the same Mailexam project.
- Wait for the worker to finish processing.
See also¶
- Examples catalog
- Reference implementation (Sidekiq) on GitHub
- Ruby on Rails — synchronous Action Mailer on the same SMTP stack
- Celery — background mail in Python
- BullMQ — background mail in Node.js
- Mailexam API documentation
- Sidekiq wiki