Traefik Routing
This module synchronizes Decidim organization hosts and subdomains to a Redis database using Traefik's KV store format. This enables dynamic routing configuration for multi-tenant Decidim instances behind a Traefik reverse proxy.
How It Works
The routing system:
- Generates unique identifiers: Each organization gets a UUID (
voca_external_id) that is automatically created when the organization is created - Syncs routing rules: Organization hosts and secondary hosts are synced to Redis in Traefik's KV format
- Configures services: Sets up load balancer configuration with health checks
- Supports multiple servers: Uses unique keys (UUIDs) to avoid conflicts when multiple servers sync routes
Features
- Automatic routing sync: Organizations are automatically synced when created or updated
- Multi-host support: Supports both primary host and secondary hosts per organization
- Health check configuration: Configures Traefik health checks for service monitoring
- TLS configuration: Automatically configures certificate resolvers (skips for localhost domains)
- Multi-server support: UUID-based keys prevent conflicts when multiple servers sync routes
Architecture
Infrastructure

- Decidim app servers push routing keys into Redis (Traefik KV).
- Traefik nodes read from the shared Redis instance to build routers and services dynamically.
- Redis (Traefik KV) stores routing data centrally, eliminating static file reloads.
Routing flow

Scenario: Given a Decidim organization A and a Decidim organization B, when organization A is created or updated:
- The organization emits create/update hooks that enqueue a sync job
- The job ensures the organization has a UUID (
voca_external_id) - Router/service entries are written to Redis in Traefik format
- Traefik consumes those keys, generates SSL certificates, and exposes the host
Usage
Sync Routes
To sync all organization routes to Redis:
bundle exec rake decidim:voca:sync_routes
This task:
- Iterates through all Decidim organizations
- Ensures each organization has a
voca_external_id - Syncs routing configuration to Redis
- Updates common service configuration
View Routes
To view all registered routes:
# JSONL format (default): host => service URL
bundle exec rake decidim:voca:routes
# Traefik format: full Traefik configuration
FORMAT=traefik bundle exec rake decidim:voca:routes
Environment Variables
| Variable | Description | Default |
|---|---|---|
TRAEFIK_REDIS_URL | Redis connection URL for Traefik KV store | redis://traefik-db:6379/1 |
MASTER_ID | Service identifier for load balancer | Required |
MASTER_IP | Service URL/IP address | Required |
TRAEFIK_SERVICE_PROTOCOL | Protocol for service URL | http |
TRAEFIK_SERVICE_PORT | Port for service URL | 8080 |
TRAEFIK_SERVICE_HEALTHCHECK_PATH | Health check endpoint path | /health/live |
TRAEFIK_SERVICE_HEALTHCHECK_PORT | Health check port | 8080 |
TRAEFIK_SERVICE_HEALTHCHECK_INTERVAL | Health check interval | 60s |
TRAEFIK_SERVICE_HEALTHCHECK_TIMEOUT | Health check timeout | 10s |
TRAEFIK_CERT_RESOLVER | Certificate resolver name for TLS | letsencrypt |
info
Virtuozzo/Jelastic environments expose MASTER_ID and MASTER_IP natively.
If you don't use Jelastic, set these variables:
MASTER_ID: a random unique identifierMASTER_IP: an IP address that the Traefik instance can reach
Routing Configuration
Each organization creates the following Traefik router configuration:
- Router rule:
Host(primary_host) || Host(secondary_host_1) || ... - Entrypoint:
websecure(port 80) - Service: Points to
service-{MASTER_ID} - Priority:
100 - TLS: Uses configured cert resolver (skipped for
.localhostdomains)
The service configuration includes:
- Load balancer server URL
- Health check path, port, interval, and timeout
Requirements
- Redis instance accessible to both Decidim and Traefik
- Traefik configured with Redis KV provider
MASTER_IDandMASTER_IPenvironment variables set- Organizations must have valid host configurations