sablier
Start your containers on demand, shut them down automatically when there's no activity. Docker, Dock
100K+

Free and open-source software that starts workloads on demand and stops them after a period of inactivity.
It integrates with reverse proxy pluginsā (Traefik, Caddy, Nginx, Envoy, etc.) to intercept incoming requests, wake up sleeping workloads, and display a waiting page until they're ready.

Whether you're running on a resource-constrained device like a Raspberry Pi, managing a QA environment used only once a week, or reducing cloud costs by scaling idle workloads to zero ā Sablier is built for you.
Key features:
You can install Sablier using one of the following methods:
With Docker Compose ā copy this into a compose.yaml and run docker compose up -d:
services:
sablier:
image: sablierapp/sablier:1.15.0 # x-release-please-version
command:
- start
- --provider.name=docker
ports:
- "10000:10000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
With docker run ā using a sample configuration file (sablier.yamlā ):
docker run -p 10000:10000 -v /var/run/docker.sock:/var/run/docker.sock sablierapp/sablier:1.15.0
Tip
Verify the image signature to ensure authenticity: ```bash gh attestation verify --owner sablierapp oci://sablierapp/sablier:1.15.0 ```
Grab the latest binary from the releasesā page and run it:
./sablier --help
Tip
Verify the binary signature to ensure authenticity: ```bash gh attestation verify sablier-1.10.3-linux-amd64.tar.gz -R sablierapp/sablier ```
git clone [email protected]:sablierapp/sablier.git
cd sablier
make
# Output will change depending on your distro
./sablier_draft_linux-amd64
Deploy Sablier to your Kubernetes cluster using the official Helm chart for production-ready deployments.
Add the Sablier Helm repository:
helm repo add sablierapp https://sablierapp.github.io/helm-charts
helm repo update
Install Sablier:
helm install sablier sablierapp/sablier
š Full Documentationā | š» Chart Repositoryā
Note
This quick start demonstrates Sablier with the **Docker provider**.For other providers, see the Providersā section.
Run your container with Sablier labels:
docker run -d --health-cmd "/mimic healthcheck" -p 8080:80 --name mimic \
--label sablier.enable=true \
--label sablier.group=demo \
sablierapp/mimic:v0.3.3 \
-running -running-after=5s \
-healthy=true -healthy-after=5s
Here we run sablierapp/mimicā , a configurable web-server for testing purposes.
Caution
You should **always** use a healthcheck with your application that needs to be scaled to zero.Without a healtheck, Sablier cannot distinguish a started container from a container ready to receive incoming requests.
Stop the container to simulate a scaled-down state:
docker stop mimic
Tip
Sablier can **automatically** stop containers at startup using the `--provider.auto-stop-on-startup` flag, which will stop all containers with `sablier.enable=true` labels.
Start the Sablier server with the Docker provider:
docker run --name sablier \
-p 10000:10000 \
-v /var/run/docker.sock:/var/run/docker.sock \
sablierapp/sablier:1.10.5 \
start --provider.name=docker
Call the Sablier API to start a session for the demo group:
curl -v http://localhost:10000/api/strategies/blocking\?group\=demo\&session_duration\=20s
* Request completely sent off
< HTTP/1.1 200 OK
< X-Sablier-Session-Status: ready
Sablier will start the mimic container automatically for 20 seconds..
Tip
Check out the [Usage with Reverse Proxies](#usage-with-reverse-proxies) section to integrate Sablier with **Traefik**, **Caddy**, **Nginx**, and more.
docker ps | grep mimic
After the session duration (20 seconds in this example), Sablier will automatically stop the container.
# Wait 20 seconds, then check
docker ps -a | grep mimic
The container should be stopped.
š Full Documentationā
There are three ways to configure Sablier:
Configuration sources are evaluated in the order listed above with later methods overriding earlier ones.
If no value is provided for a given option, a default value is used.
At startup, Sablier searches for a configuration file named sablier.yml (or sablier.yaml) in:
/etc/sablier/$XDG_CONFIG_HOME/$HOME/.config/. (the working directory)You can override this using the configFile argument.
sablier --configFile=path/to/myconfigfile.yml
provider:
# Provider to use to manage containers (docker, swarm, kubernetes, podman, proxmox_lxc)
name: docker
# Reject requests for containers/services that don't have the Sablier enable label
reject-unlabeled-requests: false
# Verify that the Sablier enable label is present when an instance expires
verify-enabled-on-expiration: false
docker:
# Strategy to use when stopping containers (stop or pause)
strategy: stop
server:
# The server port to use
port: 10000
# The base path for the API
base-path: /
metrics:
# Enable Prometheus metrics endpoint
enabled: true
storage:
# File path to save the state (default stateless)
file:
sessions:
# The default session duration (default 5m)
default-duration: 5m
# The expiration checking interval.
# Higher duration gives less stress on CPU.
# If you only use sessions of 1h, setting this to 5m is a good trade-off.
expiration-interval: 20s
logging:
level: info
strategy:
dynamic:
# Custom themes folder, will load all .html files recursively (default empty)
custom-themes-path:
# Show instances details by default in waiting UI
show-details-by-default: true
# Default theme used for dynamic strategy (default "hacker-terminal")
default-theme: hacker-terminal
# Default refresh frequency in the HTML page for dynamic strategy
default-refresh-frequency: 5s
blocking:
# Default timeout used for blocking strategy (default 1m)
default-timeout: 1m
webhooks:
endpoints:
# Notify an uptime-monitoring service every time an instance starts or stops.
# - url: https://uptime.example.com/api/push/xxxxxxxx
# headers:
# Authorization: "Bearer <token>"
# events:
# - started
# - stopped
tracing:
# Set enabled: true to export OpenTelemetry traces.
enabled: false
# exporterType selects the trace backend: "otlphttp" (default) or "stdout".
exporterType: otlphttp
# endpoint is the OTLP collector base URL (scheme + host + optional port).
# For Jaeger: http://jaeger:4318
# For Grafana Tempo: http://tempo:4318
endpoint: http://localhost:4318
# serviceName is the logical name that appears in the tracing backend.
serviceName: sablier
# samplingRate controls the fraction of requests traced (0.0 ā 1.0).
samplingRate: 1.0
Environment variables follow the same structure as the configuration file and are prefixed with SABLIER_. For example:
strategy:
dynamic:
custom-themes-path: /my/path
becomes
SABLIER_STRATEGY_DYNAMIC_CUSTOM_THEMES_PATH=/my/path
To list all available arguments:
sablier --help
# or
docker run sablierapp/sablier:1.15.0 --help
Command-line arguments follow the same structure as the configuration file. For example:
strategy:
dynamic:
custom-themes-path: /my/path
becomes
sablier start --strategy.dynamic.custom-themes-path /my/path
Sablier integrates seamlessly with Docker Engine to manage container lifecycle based on demand.
Features:
š Full Documentationā
Sablier supports Docker Swarm mode for managing services across a cluster of Docker engines.
Features:
š Full Documentationā
Sablier works with Podman, the daemonless container engine, providing the same dynamic scaling capabilities as Docker.
Features:
š Full Documentationā
Sablier provides native Kubernetes support for managing deployments, scaling workloads dynamically.
Features:
š Full Documentationā
Sablier supports Proxmox VE for managing LXC containers on demand via the Proxmox API.
Features:
sablier tagš Full Documentationā
By default, Sablier stops (or pauses) workloads when a session expires and restarts them on the next request. Scale mode is an alternative: instead of stopping a container, Sablier throttles its CPU, memory, and (on Docker) block I/O to a minimal idle allocation, then restores full resources the moment a new session arrives.
Because the container never stops, there is no cold-start latency ā ideal for resource-constrained environments like a Raspberry Pi where you want to reclaim most of the hardware while keeping response times acceptable.
Scale mode is controlled entirely through labels:
labels:
- "sablier.enable=true"
- "sablier.group=myapp"
# Idle state: keep running but throttle resources
- "sablier.idle.replicas=1"
- "sablier.idle.cpu=0.1"
- "sablier.idle.memory=64m"
# Active state: full resources when a session is requested
- "sablier.active.replicas=1"
- "sablier.active.cpu=2.0"
- "sablier.active.memory=512m"
| Label | Description |
|---|---|
sablier.idle.replicas | Replica count while idle. Set to 0 to stop (default behaviour), 1+ to keep running. |
sablier.idle.cpu | CPU limit while idle (e.g. 0.1 for 10% of one core). Requires idle.replicas >= 1. |
sablier.idle.memory | Memory limit while idle (e.g. 64m). Requires idle.replicas >= 1. |
sablier.active.replicas | Replica count when a session is active. |
sablier.active.cpu | CPU limit restored when a session is active. |
sablier.active.memory | Memory limit restored when a session is active. |
sablier.idle.blkio-weight / sablier.active.blkio-weight | Block I/O weight 10ā1000 (Docker only). |
sablier.idle.blkio-device-{read,write}-{bps,iops} | Per-device I/O throughput/IOPS limits (Docker only). |
Docker only: Block I/O throttling is supported on the Docker provider. Per-device limits (
blkio-*-device,blkio-device-*) require a Docker daemon with API version ā„ 1.55 (moby/moby#52650ā ); Sablier logs a warning on older daemons. See the configuration referenceā for the full list.
š Full Exampleā
On a machine where several heavy services share a non-shareable resource (GPU VRAM, RAM), running two at once can OOM. Anti-affinity lets an instance back off automatically while another group is in use:
labels:
- "sablier.enable=true"
- "sablier.anti-affinity=streaming" # yield whenever the "streaming" group is active
When any session for the streaming group is active, every instance that declared an anti-affinity against it is forced idle (stopped, or throttled to its idle profile in scale mode) and restored once the group is no longer active. Multiple groups can be listed comma-separated.
š Anti-Affinity documentationā | Full Exampleā
Sablier can POST a normalized JSON notification to one or more HTTP endpoints whenever a managed instance starts or stops. Because Sablier sits in front of every supported provider, webhooks act as a unified, provider-agnostic event stream ā your receiver always gets the same payload structure regardless of the underlying runtime.
Common uses:
š Full Documentationā
Sablier exposes a Prometheusā -compatible /metrics endpoint. Enable it in your configuration:
server:
metrics:
enabled: true
Sablier supports distributed tracing via OpenTelemetryā . When enabled, every incoming HTTP request and every call to the underlying container provider is captured as a span and exported to an OTLP-compatible backend such as Jaegerā or Grafana Tempoā . Trace context is propagated using the W3C TraceContext format, so if your reverse proxy injects a traceparent header, Sablier will join the existing trace.
tracing:
enabled: true
exporterType: otlphttp
endpoint: http://localhost:4318
serviceName: sablier
samplingRate: 1.0
š Full Documentationā
Sablier adds ~1.5ā2 ms of latency per request at steady state (session cache hot, container already running), sustaining ~5,000ā5,750 req/s on a single core. Cold starts depend entirely on container startup time; once the container is ready, subsequent requests return to warm latency immediately.
| Scenario | Req/s | p50 latency | p99 latency |
|---|---|---|---|
| Blocking, warm session | 5,751 | 1.54 ms | 4.94 ms |
| Dynamic, warm session | 5,066 | 1.81 ms | 4.62 ms |
| Dynamic, not-ready | 4,663 | 1.93 ms | 5.88 ms |
š Full benchmark methodology and resultsā
Sablier is an API server that manages workload lifecycle. To automatically wake up workloads when users access your services, you can integrate Sablier with reverse proxy plugins.
These plugins intercept incoming requests, call the Sablier API to start sleeping workloads, and display a waiting page until they're ready.
Sablier integrates with Apache APISIX through a Proxy-WASM plugin, enabling dynamic scaling for your services.
Quick Start:
š Full Documentationā | š» Plugin Repositoryā
Sablier provides a native Caddy module for seamless integration with Caddy v2.
Quick Start:
xcaddyš Full Documentationā | š» Plugin Repositoryā
Sablier integrates with Envoy Proxy through a Proxy-WASM plugin for high-performance dynamic scaling.
Quick Start:
š Full Documentationā | š» Plugin Repositoryā
Sablier works with Istio service mesh using the Proxy-WASM plugin for intelligent traffic management.
Quick Start:
š Full Documentationā | š» Plugin Repositoryā
Sablier integrates with Nginx through a WASM module, bringing dynamic scaling to your Nginx deployments.
Quick Start:
š Full Documentationā | š» Plugin Repositoryā
Sablier provides a powerful middleware plugin for Traefik, the cloud-native application proxy.
Quick Start:
š Full Documentationā | š» Plugin Repositoryā
Join our Discord server to discuss and get 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:
š Share your usage - We'd love to see how you're using Sablier! Consider:
š¬ 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ā .
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:
Every contribution, no matter the size, makes a real difference. Thank you for considering! š
This project is supported by:
Content type
Image
Digest
sha256:46dd23dc6ā¦
Size
17.8 MB
Last updated
4 days ago
docker pull sablierapp/sablier:next