/Sablier

Sablier

22
v1.1.0

Traefik Sablier Plugin

Go Report Card Discord

traefik

Automatically start containers on demand and shut them down during periods of inactivity using Traefik.

This plugin is available in the Traefik Plugin Catalog.

Installation

Add the following snippet to your Traefik static configuration:

experimental:
plugins:
sablier:
moduleName: "github.com/sablierapp/sablier-traefik-plugin"
version: "v1.0.0"

Or using CLI arguments:

--experimental.plugins.sablier.moduleName=github.com/sablierapp/sablier-traefik-plugin
--experimental.plugins.sablier.version=v1.0.0

Prerequisites

[!IMPORTANT] You must have a reachable instance of Sablier from Traefik.

Configuration

The plugin supports various configuration options to customize its behavior. All options are configured at the middleware level.

Complete Configuration Example:

http:
middlewares:
my-sablier:
plugin:
sablier:
sablierUrl: http://sablier:10000
group: my-app-group
sessionDuration: 1m
ignoreUserAgent: curl
dynamic:
displayName: My Services
showDetails: true
theme: hacker-terminal
refreshFrequency: 5s
OptionTypeRequiredDefaultDescription
sablierUrlstringYeshttp://sablier:10000URL of the Sablier server API (must be reachable from Traefik)
groupstringYes-Group name for managing multiple instances collectively >
sessionDurationdurationNo-Duration to keep instances running after the last request (e.g., 1m, 30s, 2h)
dynamic.displayNamestringNoMiddleware nameDisplay name shown on the waiting page
dynamic.showDetailsbooleanNoServer defaultShow detailed information on the waiting page
dynamic.themestringNoServer defaultTheme for the waiting page (e.g., hacker-terminal, ghost, matrix)
dynamic.refreshFrequencydurationNoServer defaultHow often the waiting page checks if instances are ready
blocking.timeoutdurationNo-Maximum time to wait for instances to become ready
ignoreUserAgentstringNo-User Agent that should be ignored (middleware sends HTTP 200 to not wake up the container)

Usage

The plugin can be configured in different ways depending on your deployment context:

  • Dynamic Configuration: Universal approach using configuration files (works with all Traefik providers)
  • Docker: Label-based configuration for Docker containers (requires Traefik v3.6.0+)
  • Docker Swarm: Swarm-specific configuration with centralized middleware definition
  • Kubernetes: Kubernetes-native configuration using annotations and IngressRoute

Choose the section that matches your deployment environment below.

Dynamic Configuration

[!NOTE] This configuration method works with all Traefik providers (Docker, Swarm, Kubernetes, File, etc.).

Configure the plugin in your Traefik dynamic configuration:

http:
middlewares:
my-sablier:
plugin:
sablier:
sablierUrl: http://sablier:10000 # Sablier service URL (must be reachable from Traefik)
group: my-app-group # Group name for managing instances collectively
sessionDuration: 1m # Session duration before shutting down instances
# Only one strategy can be used at a time
# Declare either `dynamic` or `blocking`, not both
ignoreUserAgent: curl # (Optional) Ignore requests with User Agent header curl to not wake up container
# Dynamic strategy: displays a waiting page
dynamic:
displayName: My Title # (Optional) Display name (defaults to middleware name)
showDetails: true # (Optional) Show details for this middleware (defaults to Sablier server settings)
theme: hacker-terminal # (Optional) Theme for the waiting page
refreshFrequency: 5s # (Optional) Refresh frequency for the waiting page
# Blocking strategy: waits for services to start (up to the timeout limit)
# blocking:
# timeout: 1m

Docker

docker

[!IMPORTANT] Label-based configuration requires Traefik v3.6.0 or higher. This version introduced support for non-running containers (PR #10645), which is essential for Traefik to register your configuration while scaled to zero.

[!TIP] For a complete working example, see the docker example.

Add the following labels to the service you want to scale on demand:

whoami:
image: traefik/whoami:latest
labels:
# Enable Sablier for this container
- sablier.enable=true
- sablier.group=whoami
# Configure the Sablier middleware
- traefik.http.middlewares.whoami-sablier.plugin.sablier.group=whoami
- traefik.http.middlewares.whoami-sablier.plugin.sablier.sablierUrl=http://sablier:10000
- traefik.http.middlewares.whoami-sablier.plugin.sablier.sessionDuration=1m
- traefik.http.middlewares.whoami-sablier.plugin.sablier.dynamic.displayName=Whoami Service
# Allow Traefik to route to non-running containers
- traefik.docker.allownonrunning=true
# Define Traefik routing
- traefik.http.routers.whoami.rule=Host(`whoami.localhost`)
- traefik.http.routers.whoami.middlewares=whoami-sablier

Docker Swarm

docker_swarm

[!CAUTION] When using Docker Swarm, the middleware configuration must be defined on a service scanned by Traefik that is not scaled to zero.

This is because Traefik evicts services from its pool when scaled to 0/0, making service-level labels unavailable.

Enabling AllowEmptyServices is supposed to cover this use case but this is a known issue: AllowEmptyServices option does not work with the Swarm provider #12196

[!TIP] For a complete working example, see the Docker Swarm E2E test.

1. Deploy Sablier with Middleware Configuration

Deploy Sablier as a service and define all middleware configurations on it:

sablier:
image: sablierapp/sablier:1.10.1
command:
- start
- --provider.name=swarm
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
deploy:
labels:
- traefik.enable=true
# Define the Sablier middleware here
- traefik.http.middlewares.whoami-sablier.plugin.sablier.group=my-group
- traefik.http.middlewares.whoami-sablier.plugin.sablier.sablierUrl=http://tasks.sablier:10000
- traefik.http.middlewares.whoami-sablier.plugin.sablier.sessionDuration=1m
- traefik.http.middlewares.whoami-sablier.plugin.sablier.dynamic.displayName=Whoami Service
- traefik.http.services.sablier.loadbalancer.server.port=10000

2. Configure Traefik with Swarm Provider

Enable the Swarm provider with empty services support:

traefik:
image: traefik:v3.0.4
command:
- --experimental.plugins.sablier.modulename=github.com/sablierapp/sablier-traefik-plugin
- --experimental.plugins.sablier.version=v1.0.0
- --entryPoints.http.address=:80
- --providers.swarm=true
- --providers.swarm.refreshSeconds=1
ports:
- target: 80
published: 8080
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'

3. Configure Your Service Labels

Add labels to the service you want to scale on demand:

whoami:
image: acouvreur/whoami:v1.10.2
deploy:
replicas: 0
labels:
# Enable Sablier for this service
- sablier.enable=true
- sablier.group=my-group
# Enable Traefik routing
- traefik.enable=true
# Use Swarm load balancer to prevent service eviction
- traefik.docker.lbswarm=true
# Define routing and attach the middleware
- traefik.http.routers.whoami.rule=Host(`whoami.localhost`)
- traefik.http.routers.whoami.middlewares=whoami-sablier@swarm
- traefik.http.routers.whoami.service=whoami
- traefik.http.services.whoami.loadbalancer.server.port=80

āš ļø Limitations

  • The blocking strategy cannot be used reliably due to how Traefik handles service eviction with empty pools
  • Middleware configuration must be centralized on the Sablier service to remain accessible when services are scaled to 0

Kubernetes

kubernetes

āš ļø Limitations

  • Traefik evicts services from its pool when no endpoints are available. Enable allowEmptyServices to prevent this.
  • The blocking strategy is not yet supported due to Traefik's pod IP handling.

Refer to the Kubernetes E2E test script for a working example.

Other Reverse Proxy Plugins

Apache APISIX

Apache APISIX

Sablier integrates with Apache APISIX through a Proxy-WASM plugin, enabling dynamic scaling for your services.

Quick Start:

  1. Install the Sablier Proxy-WASM plugin
  2. Configure APISIX routes with Sablier plugin settings
  3. Define your scaling labels on target services

šŸ“š Full Documentation | šŸ’» Plugin Repository


Caddy

Caddy

Sablier provides a native Caddy module for seamless integration with Caddy v2.

Quick Start:

  1. Build Caddy with the Sablier module using xcaddy
  2. Add Sablier directives to your Caddyfile
  3. Configure dynamic scaling rules

šŸ“š Full Documentation | šŸ’» Plugin Repository


Envoy

Envoy

Sablier integrates with Envoy Proxy through a Proxy-WASM plugin for high-performance dynamic scaling.

Quick Start:

  1. Deploy the Sablier Proxy-WASM plugin
  2. Configure Envoy HTTP filters
  3. Set up scaling labels on your workloads

šŸ“š Full Documentation | šŸ’» Plugin Repository


Istio

Istio

Sablier works with Istio service mesh using the Proxy-WASM plugin for intelligent traffic management.

Quick Start:

  1. Install the Sablier Proxy-WASM plugin in your Istio mesh
  2. Configure EnvoyFilter resources
  3. Annotate your services with Sablier labels

šŸ“š Full Documentation | šŸ’» Plugin Repository


Nginx

Nginx

Sablier integrates with Nginx through a WASM module, bringing dynamic scaling to your Nginx deployments.

Quick Start:

  1. Build Nginx with WASM support
  2. Load the Sablier Proxy-WASM plugin
  3. Configure Nginx locations with Sablier directives

šŸ“š Full Documentation | šŸ’» Plugin Repository

If you find Sablier valuable and want to support its development, please consider sponsoring the project:

šŸ’– Sponsor on GitHub - Your sponsorship helps keep this project maintained and actively developed

Your support helps:

  • Keep the project maintained and up-to-date
  • Dedicate more time to bug fixes and new features
  • Improve documentation and examples
  • Support the broader open-source ecosystem

Every contribution, no matter the size, makes a real difference. Thank you for considering! šŸ™

Community

Join our Discord server for discussions and support:

Discord

Support

This project is maintained by a single developer in their free time. If you find Sablier useful, here are some ways you can show your support:

⭐ Star the repository - It helps others discover the project and motivates continued development

šŸ¤ Contribute - Pull requests are always welcome! Whether it's:

  • Bug fixes
  • New features
  • Documentation improvements
  • Test coverage

šŸ“š Share your usage - We'd love to see how you're using Sablier! Consider:

  • Opening a discussion to share your setup
  • Contributing examples of your deployment configurations
  • Writing a blog post or tutorial

šŸ’¬ Engage with the community - Ask questions, report issues, or help others in discussions

Every contribution, no matter how small, makes a difference and is greatly appreciated! šŸ™

For detailed support options, see SUPPORT.md.