Files
sure/config/initializers/sidekiq.rb
Copilot a135866dbf Add Redis Sentinel support for Sidekiq high availability (#457)
* Initial plan

* Add Redis Sentinel support for Sidekiq configuration

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Add documentation for Redis Sentinel configuration

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Improve Sentinel host parsing with better validation and error handling

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Add port validation to prevent invalid Sentinel configurations

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Linter

* Add Sentinel authentication credentials to fix NOAUTH error

- Add sentinel_username (defaults to "default")
- Add sentinel_password (uses REDIS_PASSWORD)
- Update documentation for sentinel auth configuration

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Add CHANGELOG.md for Helm chart documenting Redis Sentinel support

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Set REDIS_URL alongside in Sentinel mode also

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-10 20:18:03 +01:00

71 lines
2.3 KiB
Ruby

require "sidekiq/web"
if Rails.env.production?
Sidekiq::Web.use(Rack::Auth::Basic) do |username, password|
configured_username = ::Digest::SHA256.hexdigest(ENV.fetch("SIDEKIQ_WEB_USERNAME", "sure"))
configured_password = ::Digest::SHA256.hexdigest(ENV.fetch("SIDEKIQ_WEB_PASSWORD", "sure"))
ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), configured_username) &&
ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), configured_password)
end
end
# Configure Redis connection for Sidekiq
# Supports both Redis Sentinel (for HA) and direct Redis URL
redis_config = if ENV["REDIS_SENTINEL_HOSTS"].present?
# Redis Sentinel configuration for high availability
# REDIS_SENTINEL_HOSTS should be comma-separated list: "host1:port1,host2:port2,host3:port3"
sentinels = ENV["REDIS_SENTINEL_HOSTS"].split(",").filter_map do |host_port|
parts = host_port.strip.split(":", 2)
host = parts[0]&.strip
port_str = parts[1]&.strip
next if host.blank?
# Parse port with validation, default to 26379 if invalid or missing
port = if port_str.present?
port_int = port_str.to_i
(port_int > 0 && port_int <= 65535) ? port_int : 26379
else
26379
end
{ host: host, port: port }
end
if sentinels.empty?
Rails.logger.warn("REDIS_SENTINEL_HOSTS is set but no valid sentinel hosts found, falling back to REDIS_URL")
{ url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
else
{
url: "redis://#{ENV.fetch('REDIS_SENTINEL_MASTER', 'mymaster')}/0",
sentinels: sentinels,
password: ENV["REDIS_PASSWORD"],
sentinel_username: ENV.fetch("REDIS_SENTINEL_USERNAME", "default"),
sentinel_password: ENV["REDIS_PASSWORD"],
role: :master,
# Recommended timeouts for Sentinel
connect_timeout: 0.2,
read_timeout: 1,
write_timeout: 1,
reconnect_attempts: 3
}
end
else
# Standard Redis URL configuration (no Sentinel)
{ url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end
Sidekiq.configure_server do |config|
config.redis = redis_config
end
Sidekiq.configure_client do |config|
config.redis = redis_config
end
Sidekiq::Cron.configure do |config|
# 10 min "catch-up" window in case worker process is re-deploying when cron tick occurs
config.reschedule_grace_period = 600
end