{"id":17711391,"url":"https://github.com/sablierapp/sablier","last_synced_at":"2026-05-29T02:02:26.841Z","repository":{"id":39453265,"uuid":"305793798","full_name":"sablierapp/sablier","owner":"sablierapp","description":"Start your containers on demand, shut them down automatically when there's no activity. Docker, Docker Swarm Mode, Podman, Kubernetes and Proxmox LXC compatible.","archived":false,"fork":false,"pushed_at":"2026-05-14T04:17:41.000Z","size":49498,"stargazers_count":2684,"open_issues_count":71,"forks_count":84,"subscribers_count":8,"default_branch":"main","last_synced_at":"2026-05-14T04:43:04.439Z","etag":null,"topics":["docker","docker-swarm","hacktoberfest","kubernetes","nginx","plugin","podman","selfhosted","traefik"],"latest_commit_sha":null,"homepage":"https://sablierapp.dev/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sablierapp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"acouvreur","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2020-10-20T18:07:26.000Z","updated_at":"2026-05-14T03:37:12.000Z","dependencies_parsed_at":"2026-01-13T04:06:22.519Z","dependency_job_id":null,"html_url":"https://github.com/sablierapp/sablier","commit_stats":{"total_commits":570,"total_committers":19,"mean_commits":30.0,"dds":"0.43157894736842106","last_synced_commit":"79f83d7870edb15a8f17189be01ff2a93c0916ce"},"previous_names":["sablierapp/sablier"],"tags_count":130,"template":false,"template_full_name":null,"purl":"pkg:github/sablierapp/sablier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sablierapp%2Fsablier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sablierapp%2Fsablier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sablierapp%2Fsablier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sablierapp%2Fsablier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sablierapp","download_url":"https://codeload.github.com/sablierapp/sablier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sablierapp%2Fsablier/sbom","scorecard":{"id":1240094,"data":{"date":"2025-11-30T03:12:55Z","repo":{"name":"github.com/sablierapp/sablier","commit":"5ab62a79b250ec69610e4ade832935ab2d2a5ec4"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":5.9,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 2/18 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/build.yml:17","Info: jobLevel 'contents' permission set to 'read': .github/workflows/label.yml:16","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:27","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecard.yml:28","Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/dockerhub-description.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/goreleaser.yml:10","Warn: topLevel 'packages' permission set to 'write': .github/workflows/goreleaser.yml:11","Warn: no topLevel permission defined: .github/workflows/label.yml:1","Info: topLevel 'contents' permission set to 'read': .github/workflows/lint.yml:14","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release-please.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:16","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 20 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  16 out of  16 GitHub-owned GitHubAction dependencies pinned","Info:  15 out of  15 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU Affero General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"CII-Best-Practices","score":2,"reason":"badge detected: InProgress","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.10.5 not signed: https://api.github.com/repos/sablierapp/sablier/releases/264648346","Warn: release artifact v1.10.4 not signed: https://api.github.com/repos/sablierapp/sablier/releases/264630366","Warn: release artifact v1.10.3 not signed: https://api.github.com/repos/sablierapp/sablier/releases/264628250","Warn: release artifact v1.10.1 not signed: https://api.github.com/repos/sablierapp/sablier/releases/236447430","Warn: release artifact v1.10.5 does not have provenance: https://api.github.com/repos/sablierapp/sablier/releases/264648346","Warn: release artifact v1.10.4 does not have provenance: https://api.github.com/repos/sablierapp/sablier/releases/264630366","Warn: release artifact v1.10.3 does not have provenance: https://api.github.com/repos/sablierapp/sablier/releases/264628250","Warn: release artifact v1.10.1 does not have provenance: https://api.github.com/repos/sablierapp/sablier/releases/236447430"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2024-3042","Warn: Project is vulnerable to: GO-2025-3961","Warn: Project is vulnerable to: GO-2025-4098 / GHSA-cgrx-mc8f-2prm"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/goreleaser.yml:17"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"SAST","score":9,"reason":"SAST tool is not run on all commits -- score normalized to 9","details":["Warn: 15 commits out of 16 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Branch-Protection","score":1,"reason":"branch protection is not maximal on development and all release branches","details":["Warn: branch protection not enabled for branch 'beta'","Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'","Info: 'stale review dismissal' is required to merge on branch 'main'","Warn: required approving review count is 1 on branch 'main'","Info: codeowner review is required on branch 'main'","Info: 'last push approval' is required to merge on branch 'main'","Warn: no status checks found to merge onto branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":9,"reason":"15 out of 16 merged PRs checked by a CI test -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}},{"name":"Contributors","score":10,"reason":"project has 3 contributing companies or organizations -- score normalized to 10","details":["Info: found contributions from: retarus gmbh, sablierapp, semantic-release"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}}]},"last_synced_at":"2025-12-01T08:54:45.801Z","repository_id":39453265,"created_at":"2025-12-01T08:54:45.801Z","updated_at":"2025-12-01T08:54:45.801Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33633468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-swarm","hacktoberfest","kubernetes","nginx","plugin","podman","selfhosted","traefik"],"created_at":"2024-10-25T08:00:58.705Z","updated_at":"2026-05-29T02:02:26.836Z","avatar_url":"https://github.com/sablierapp.png","language":"Go","funding_links":["https://github.com/sponsors/acouvreur"],"categories":["Go"],"sub_categories":[],"readme":"![Sablier Banner](https://raw.githubusercontent.com/sablierapp/artwork/refs/heads/main/horizontal/sablier-horizontal-color.png)\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/sablierapp/sablier)](https://goreportcard.com/report/github.com/sablierapp/sablier)\n[![Discord](https://img.shields.io/discord/1298488955947454464?logo=discord\u0026logoColor=5865F2\u0026cacheSeconds=1\u0026link=http%3A%2F%2F)](https://discord.gg/WXYp59KeK9)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/sablierapp/sablier/badge)](https://scorecard.dev/viewer/?uri=github.com/sablierapp/sablier)\n\nFree and open-source software that starts workloads on demand and stops them after a period of inactivity.\n\nIt integrates with [reverse proxy plugins](#usage-with-reverse-proxies) (Traefik, Caddy, Nginx, Envoy, etc.) to intercept incoming requests, wake up sleeping workloads, and display a waiting page until they're ready.\n\n![Demo](./docs/assets/img/demo.gif)\n\nWhether 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.\n\n**Key features:**\n- On-demand start/stop for Docker, Kubernetes, Podman, and Proxmox LXC workloads\n- Customizable waiting UI with themes while workloads warm up\n- [Webhook notifications](#webhooks) when instances start or stop\n- [Prometheus metrics](#metrics) for monitoring session and workload activity\n- [OpenTelemetry tracing](#tracing) for end-to-end request observability\n- Stop or pause strategies to maximize resource reclamation on constrained hardware\n- [Scale mode](#scale-mode): throttle CPU and memory when idle instead of stopping, for zero-cold-start workloads\n\n---\n\n- [Installation](#installation)\n  - [Use the Docker image](#use-the-docker-image)\n  - [Use the binary distribution](#use-the-binary-distribution)\n  - [Compile your binary from the sources](#compile-your-binary-from-the-sources)\n  - [Use the Helm Chart](#use-the-helm-chart)\n- [Quick Start](#quick-start)\n- [Configuration](#configuration)\n  - [Configuration File](#configuration-file)\n  - [Environment Variables](#environment-variables)\n  - [Arguments](#arguments)\n- [Providers](#providers)\n  - [Docker](#docker)\n  - [Docker Swarm](#docker-swarm)\n  - [Podman](#podman)\n  - [Kubernetes](#kubernetes)\n  - [Proxmox LXC](#proxmox-lxc)\n- [Scale Mode](#scale-mode)\n- [Webhooks](#webhooks)\n- [Observability](#observability)\n  - [Metrics](#metrics)\n  - [Tracing](#tracing)\n- [Performance](#performance)\n- [Usage with Reverse Proxies](#usage-with-reverse-proxies)\n  - [Apache APISIX](#apache-apisix)\n  - [Caddy](#caddy)\n  - [Envoy](#envoy)\n  - [Istio](#istio)\n  - [Nginx](#nginx)\n  - [Traefik](#traefik)\n- [Community](#community)\n- [Support](#support)\n- [Sponsor](#sponsor)\n  - [DigitalOcean](#digitalocean)\n\n\n## Installation\n\nYou can install Sablier using one of the following methods:\n\n- [Use the Docker image](#use-the-docker-image)\n- [Use the binary distribution](#use-the-binary-distribution)\n- [Compile your binary from the sources](#compile-your-binary-from-the-sources)\n- [Use the Helm Chart](#use-the-helm-chart)\n\n### Use the Docker image\n\n\u003cimg src=\"./docs/assets/img/docker.svg\" alt=\"Helm\" width=\"100\" align=\"right\" /\u003e\n\n\u003c!-- x-release-please-start-version --\u003e\n![Docker Pulls](https://img.shields.io/docker/pulls/sablierapp/sablier)\n![Docker Image Size (tag)](https://img.shields.io/docker/image-size/sablierapp/sablier/1.13.0)\n\u003c!-- x-release-please-end --\u003e\n\n- **Docker Hub**: [sablierapp/sablier](https://hub.docker.com/r/sablierapp/sablier)\n- **GitHub Container Registry**: [ghcr.io/sablierapp/sablier](https://github.com/sablierapp/sablier/pkgs/container/sablier)\n  \nChoose one of the Docker images and run it with a sample configuration file:\n\n- [sablier.yaml](https://raw.githubusercontent.com/sablierapp/sablier/main/sablier.sample.yaml)\n\n\u003c!-- x-release-please-start-version --\u003e\n```bash\ndocker run -p 10000:10000 -v /var/run/docker.sock:/var/run/docker.sock sablierapp/sablier:1.13.0\n```\n\n\u003e [!TIP]\n\u003e Verify the image signature to ensure authenticity:\n\u003e ```bash\n\u003e gh attestation verify --owner sablierapp oci://sablierapp/sablier:1.13.0\n\u003e ```\n\n\u003c!-- x-release-please-end --\u003e\n\n### Use the binary distribution\n\n\u003cimg src=\"./docs/assets/img/github.svg\" alt=\"Helm\" width=\"100\" align=\"right\" /\u003e\n\nGrab the latest binary from the [releases](https://github.com/sablierapp/sablier/releases) page and run it:\n\n```bash\n./sablier --help\n```\n\n\u003e [!TIP]\n\u003e Verify the binary signature to ensure authenticity:\n\u003e ```bash\n\u003e gh attestation verify sablier-1.10.3-linux-amd64.tar.gz -R sablierapp/sablier\n\u003e ```\n\n### Compile your binary from the sources\n\n```bash\ngit clone git@github.com:sablierapp/sablier.git\ncd sablier\nmake\n# Output will change depending on your distro\n./sablier_draft_linux-amd64\n```\n\n### Use the Helm Chart\n\n\u003cimg src=\"./docs/assets/img/helm.png\" alt=\"Helm\" width=\"100\" align=\"right\" /\u003e\n\nDeploy Sablier to your Kubernetes cluster using the official Helm chart for production-ready deployments.\n\nAdd the Sablier Helm repository:\n\n```bash\nhelm repo add sablierapp https://sablierapp.github.io/helm-charts\nhelm repo update\n```\n\nInstall Sablier:\n\n```bash\nhelm install sablier sablierapp/sablier\n```\n\n📚 **[Full Documentation](https://github.com/sablierapp/helm-charts/tree/main/charts/sablier)** | 💻 **[Chart Repository](https://github.com/sablierapp/helm-charts)**\n\n---\n\n## Quick Start\n\n\u003e [!NOTE]\n\u003e This quick start demonstrates Sablier with the **Docker provider**.\n\u003e \n\u003e For other providers, see the [Providers](#providers) section.\n\n\u003c!-- omit in toc --\u003e\n### 1. Start your container to scale to zero\n\nRun your container with Sablier labels:\n\n```bash\ndocker run -d --health-cmd \"/mimic healthcheck\" -p 8080:80 --name mimic \\\n  --label sablier.enable=true \\\n  --label sablier.group=demo \\\n  sablierapp/mimic:v0.3.3 \\\n  -running -running-after=5s \\\n  -healthy=true -healthy-after=5s\n```\n\nHere we run [sablierapp/mimic](https://github.com/sablierapp/mimic), a configurable web-server for testing purposes.\n\n\u003e [!CAUTION]\n\u003e You should **always** use a healthcheck with your application that needs to be scaled to zero.\n\u003e\n\u003e Without a healtheck, Sablier cannot distinguish a started container from a container ready to receive incoming requests.\n\n\u003c!-- omit in toc --\u003e\n### 2. Stop the Container\n\nStop the container to simulate a scaled-down state:\n\n```bash\ndocker stop mimic\n```\n\n\u003e [!TIP]\n\u003e 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.\n\n\u003c!-- omit in toc --\u003e\n### 3. Start Sablier\n\nStart the Sablier server with the Docker provider:\n\n```bash\ndocker run --name sablier \\\n  -p 10000:10000 \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  sablierapp/sablier:1.10.5 \\\n  start --provider.name=docker\n```\n\n\u003c!-- omit in toc --\u003e\n### 4. Request a Session\n\nCall the Sablier API to start a session for the `demo` group:\n\n```bash\ncurl -v http://localhost:10000/api/strategies/blocking\\?group\\=demo\\\u0026session_duration\\=20s\n* Request completely sent off\n\u003c HTTP/1.1 200 OK\n\u003c X-Sablier-Session-Status: ready\n```\n\nSablier will start the mimic container automatically for 20 seconds..\n\n\u003e [!TIP]\n\u003e Check out the [Usage with Reverse Proxies](#usage-with-reverse-proxies) section to integrate Sablier with **Traefik**, **Caddy**, **Nginx**, and more.\n\n\u003c!-- omit in toc --\u003e\n### 5. Verify the Container is Running\n\n```bash\ndocker ps | grep mimic\n```\n\n\u003c!-- omit in toc --\u003e\n### 6. Wait for Session Expiration\n\nAfter the session duration (20 seconds in this example), Sablier will automatically stop the container.\n\n```bash\n# Wait 20 seconds, then check\ndocker ps -a | grep mimic\n```\n\nThe container should be stopped.\n\n---\n\n## Configuration\n\n📚 **[Full Documentation](https://sablierapp.dev/#/configuration)**\n\nThere are three ways to configure Sablier:\n\n1. [In a configuration file](#configuration-file)\n2. [As environment variables](#environment-variables)\n3. [As command-line arguments](#arguments)\n\nConfiguration sources are evaluated in the order listed above with later methods overriding earlier ones.\n\nIf no value is provided for a given option, a default value is used.\n\n### Configuration File\n\nAt startup, Sablier searches for a configuration file named sablier.yml (or sablier.yaml) in:\n\n- `/etc/sablier/`\n- `$XDG_CONFIG_HOME/`\n- `$HOME/.config/`\n- `.` *(the working directory)*\n\nYou can override this using the `configFile` argument.\n\n```bash\nsablier --configFile=path/to/myconfigfile.yml\n```\n\n```yaml\nprovider:\n  # Provider to use to manage containers (docker, swarm, kubernetes, podman, proxmox_lxc)\n  name: docker\n  # Reject requests for containers/services that don't have the Sablier enable label\n  reject-unlabeled-requests: false\n  # Verify that the Sablier enable label is present when an instance expires\n  verify-enabled-on-expiration: false\n  docker:\n    # Strategy to use when stopping containers (stop or pause)\n    strategy: stop\nserver:\n  # The server port to use\n  port: 10000\n  # The base path for the API\n  base-path: /\n  metrics:\n    # Enable Prometheus metrics endpoint\n    enabled: true\nstorage:\n  # File path to save the state (default stateless)\n  file:\nsessions:\n  # The default session duration (default 5m)\n  default-duration: 5m\n  # The expiration checking interval.\n  # Higher duration gives less stress on CPU.\n  # If you only use sessions of 1h, setting this to 5m is a good trade-off.\n  expiration-interval: 20s\nlogging:\n  level: info\nstrategy:\n  dynamic:\n    # Custom themes folder, will load all .html files recursively (default empty)\n    custom-themes-path:\n    # Show instances details by default in waiting UI\n    show-details-by-default: true\n    # Default theme used for dynamic strategy (default \"hacker-terminal\")\n    default-theme: hacker-terminal\n    # Default refresh frequency in the HTML page for dynamic strategy\n    default-refresh-frequency: 5s\n  blocking:\n    # Default timeout used for blocking strategy (default 1m)\n    default-timeout: 1m\nwebhooks:\n  endpoints:\n    # Notify an uptime-monitoring service every time an instance starts or stops.\n    # - url: https://uptime.example.com/api/push/xxxxxxxx\n    #   headers:\n    #     Authorization: \"Bearer \u003ctoken\u003e\"\n    #   events:\n    #     - started\n    #     - stopped\ntracing:\n  # Set enabled: true to export OpenTelemetry traces.\n  enabled: false\n  # exporterType selects the trace backend: \"otlphttp\" (default) or \"stdout\".\n  exporterType: otlphttp\n  # endpoint is the OTLP collector base URL (scheme + host + optional port).\n  # For Jaeger: http://jaeger:4318\n  # For Grafana Tempo: http://tempo:4318\n  endpoint: http://localhost:4318\n  # serviceName is the logical name that appears in the tracing backend.\n  serviceName: sablier\n  # samplingRate controls the fraction of requests traced (0.0 – 1.0).\n  samplingRate: 1.0\n```\n\n### Environment Variables\n\nEnvironment variables follow the same structure as the configuration file and are prefixed with `SABLIER_`. For example:\n\n```yaml\nstrategy:\n  dynamic:\n    custom-themes-path: /my/path\n```\n\nbecomes\n\n```bash\nSABLIER_STRATEGY_DYNAMIC_CUSTOM_THEMES_PATH=/my/path\n```\n\n### Arguments\n\nTo list all available arguments:\n\n\u003c!-- x-release-please-start-version --\u003e\n```bash\nsablier --help\n\n# or\n\ndocker run sablierapp/sablier:1.13.0 --help\n```\n\u003c!-- x-release-please-end --\u003e\n\nCommand-line arguments follow the same structure as the configuration file. For example:\n\n```yaml\nstrategy:\n  dynamic:\n    custom-themes-path: /my/path\n```\n\nbecomes\n\n```bash\nsablier start --strategy.dynamic.custom-themes-path /my/path\n```\n\n\u003c!--\n## Reference\nTODO: Add link to full auto-generated reference\n--\u003e\n\n## Providers\n\n### Docker\n\n\u003cimg src=\"./docs/assets/img/docker.svg\" alt=\"Docker\" width=\"100\" align=\"right\" /\u003e\n\nSablier integrates seamlessly with Docker Engine to manage container lifecycle based on demand.\n\n**Features:**\n- Connects to the Docker socket\n- Starts/Stops containers\n- Compatible with Docker Compose\n\n📚 **[Full Documentation](https://sablierapp.dev/#/providers/docker)**\n\n---\n\n### Docker Swarm\n\n\u003cimg src=\"./docs/assets/img/docker_swarm.png\" alt=\"Docker Swarm\" width=\"100\" align=\"right\" /\u003e\n\nSablier supports Docker Swarm mode for managing services across a cluster of Docker engines.\n\n**Features:**\n- Connects to the Docker socket (Manager node)\n- Scales services to 0 and back\n- Compatible with Docker Stack\n\n📚 **[Full Documentation](https://sablierapp.dev/#/providers/docker_swarm)**\n\n---\n\n### Podman\n\n\u003cimg src=\"./docs/assets/img/podman.png\" alt=\"Podman\" width=\"100\" align=\"right\" /\u003e\n\nSablier works with Podman, the daemonless container engine, providing the same dynamic scaling capabilities as Docker.\n\n**Features:**\n- Connects to the Podman socket\n- Starts/Stops containers\n- Supports rootless containers\n\n📚 **[Full Documentation](https://sablierapp.dev/#/providers/podman)**\n\n---\n\n### Kubernetes\n\n\u003cimg src=\"./docs/assets/img/kubernetes.png\" alt=\"Kubernetes\" width=\"100\" align=\"right\" /\u003e\n\nSablier provides native Kubernetes support for managing deployments, scaling workloads dynamically.\n\n**Features:**\n- Connects to the Kubernetes API\n- Scales Deployments and StatefulSets to 0 and back\n- Supports in-cluster and out-of-cluster configuration\n\n📚 **[Full Documentation](https://sablierapp.dev/#/providers/kubernetes)**\n\n---\n\n### Proxmox LXC\n\n\u003cimg src=\"./docs/assets/img/proxmox.png\" alt=\"Proxmox\" width=\"100\" align=\"right\" /\u003e\n\nSablier supports Proxmox VE for managing LXC containers on demand via the Proxmox API.\n\n**Features:**\n- Connects to the Proxmox VE API with token authentication\n- Starts/Stops LXC containers\n- Discovers containers by `sablier` tag\n\n📚 **[Full Documentation](https://sablierapp.dev/#/providers/proxmox_lxc)**\n\n## Scale Mode\n\nBy 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 and memory to a minimal idle allocation, then restores full resources the moment a new session arrives.\n\nBecause 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.\n\nScale mode is controlled entirely through labels:\n\n```yaml\nlabels:\n  - \"sablier.enable=true\"\n  - \"sablier.group=myapp\"\n  # Idle state: keep running but throttle resources\n  - \"sablier.idle.replicas=1\"\n  - \"sablier.idle.cpu=0.1\"\n  - \"sablier.idle.memory=64m\"\n  # Active state: full resources when a session is requested\n  - \"sablier.active.replicas=1\"\n  - \"sablier.active.cpu=2.0\"\n  - \"sablier.active.memory=512m\"\n```\n\n| Label | Description |\n|---|---|\n| `sablier.idle.replicas` | Replica count while idle. Set to `0` to stop (default behaviour), `1+` to keep running. |\n| `sablier.idle.cpu` | CPU limit while idle (e.g. `0.1` for 10% of one core). Requires `idle.replicas \u003e= 1`. |\n| `sablier.idle.memory` | Memory limit while idle (e.g. `64m`). Requires `idle.replicas \u003e= 1`. |\n| `sablier.active.replicas` | Replica count when a session is active. |\n| `sablier.active.cpu` | CPU limit restored when a session is active. |\n| `sablier.active.memory` | Memory limit restored when a session is active. |\n\n📚 **[Full Example](./examples/scale-mode/)**\n\n---\n\n## Webhooks\n\nSablier 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.\n\n**Common uses:**\n- Push heartbeats to an uptime monitor such as [Uptime Kuma](https://github.com/louislam/uptime-kuma)\n- Trigger CI/CD pipelines or automation on instance lifecycle events\n- Feed a central observability or alerting bus\n\n📚 **[Full Documentation](https://sablierapp.dev/#/webhooks)**\n\n---\n\n## Observability\n\n### Metrics\n\nSablier exposes a [Prometheus](https://prometheus.io/)-compatible `/metrics` endpoint. Enable it in your configuration:\n\n```yaml\nserver:\n  metrics:\n    enabled: true\n```\n\n---\n\n### Tracing\n\nSablier supports distributed tracing via [OpenTelemetry](https://opentelemetry.io/). 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](https://www.jaegertracing.io/) or [Grafana Tempo](https://grafana.com/oss/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.\n\n```yaml\ntracing:\n  enabled: true\n  exporterType: otlphttp\n  endpoint: http://localhost:4318\n  serviceName: sablier\n  samplingRate: 1.0\n```\n\n📚 **[Full Documentation](https://sablierapp.dev/#/tracing)**\n\n---\n\n## Performance\n\nSablier 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.\n\n| Scenario | Req/s | p50 latency | p99 latency |\n|---|---|---|---|\n| Blocking, warm session | 5,751 | 1.54 ms | 4.94 ms |\n| Dynamic, warm session | 5,066 | 1.81 ms | 4.62 ms |\n| Dynamic, not-ready | 4,663 | 1.93 ms | 5.88 ms |\n\n📚 **[Full benchmark methodology and results](https://sablierapp.dev/#/performance)**\n\n---\n\n## Usage with Reverse Proxies\n\nSablier 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.\n\nThese plugins intercept incoming requests, call the Sablier API to start sleeping workloads, and display a waiting page until they're ready.\n\n### Apache APISIX\n\n\u003cimg src=\"./docs/assets/img/apacheapisix.png\" alt=\"Apache APISIX\" width=\"100\" align=\"right\" /\u003e\n\nSablier integrates with Apache APISIX through a Proxy-WASM plugin, enabling dynamic scaling for your services.\n\n**Quick Start:**\n1. Install the Sablier Proxy-WASM plugin\n2. Configure APISIX routes with Sablier plugin settings\n3. Define your scaling labels on target services\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-proxywasm-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-proxywasm-plugin)**\n\n---\n\n### Caddy\n\n\u003cimg src=\"./docs/assets/img/caddy.png\" alt=\"Caddy\" width=\"100\" align=\"right\" /\u003e\n\nSablier provides a native Caddy module for seamless integration with Caddy v2.\n\n**Quick Start:**\n1. Build Caddy with the Sablier module using `xcaddy`\n2. Add Sablier directives to your Caddyfile\n3. Configure dynamic scaling rules\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-caddy-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-caddy-plugin)**\n\n---\n\n### Envoy\n\n\u003cimg src=\"./docs/assets/img/envoy.png\" alt=\"Envoy\" width=\"100\" align=\"right\" /\u003e\n\nSablier integrates with Envoy Proxy through a Proxy-WASM plugin for high-performance dynamic scaling.\n\n**Quick Start:**\n1. Deploy the Sablier Proxy-WASM plugin\n2. Configure Envoy HTTP filters\n3. Set up scaling labels on your workloads\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-proxywasm-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-proxywasm-plugin)**\n\n---\n\n### Istio\n\n\u003cimg src=\"./docs/assets/img/istio.png\" alt=\"Istio\" width=\"100\" align=\"right\" /\u003e\n\nSablier works with Istio service mesh using the Proxy-WASM plugin for intelligent traffic management.\n\n**Quick Start:**\n1. Install the Sablier Proxy-WASM plugin in your Istio mesh\n2. Configure EnvoyFilter resources\n3. Annotate your services with Sablier labels\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-proxywasm-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-proxywasm-plugin)**\n\n---\n\n### Nginx\n\n\u003cimg src=\"./docs/assets/img/nginx.svg\" alt=\"Nginx\" width=\"100\" align=\"right\" /\u003e\n\nSablier integrates with Nginx through a WASM module, bringing dynamic scaling to your Nginx deployments.\n\n**Quick Start:**\n1. Build Nginx with WASM support\n2. Load the Sablier Proxy-WASM plugin\n3. Configure Nginx locations with Sablier directives\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-proxywasm-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-proxywasm-plugin)**\n\n---\n\n### Traefik\n\n\u003cimg src=\"./docs/assets/img/traefik.png\" alt=\"Traefik\" width=\"100\" align=\"right\" /\u003e\n\nSablier provides a powerful middleware plugin for Traefik, the cloud-native application proxy.\n\n**Quick Start:**\n1. Add the Sablier plugin to your Traefik static configuration\n2. Create Sablier middleware in your dynamic configuration\n3. Apply the middleware to your routes\n\n📚 **[Full Documentation](https://github.com/sablierapp/sablier-traefik-plugin)** | 💻 **[Plugin Repository](https://github.com/sablierapp/sablier-traefik-plugin)**\n\n## Community\n\nJoin our Discord server to discuss and get support!\n\n[![Discord](https://img.shields.io/discord/1298488955947454464?logo=discord\u0026logoColor=5865F2\u0026cacheSeconds=1\u0026link=http%3A%2F%2F)](https://discord.gg/WXYp59KeK9)\n\n## Support\n\nThis 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:\n\n⭐ **Star the repository** - It helps others discover the project and motivates continued development\n\n🤝 **Contribute** - Pull requests are always welcome! Whether it's:\n- Bug fixes\n- New features\n- Documentation improvements\n- Test coverage\n\n📚 **Share your usage** - We'd love to see how you're using Sablier! Consider:\n- Opening a discussion to share your setup\n- Contributing examples of your deployment configurations\n- Writing a blog post or tutorial\n\n💬 **Engage with the community** - Ask questions, report issues, or help others in [discussions](https://github.com/sablierapp/sablier/discussions)\n\nEvery contribution, no matter how small, makes a difference and is greatly appreciated! 🙏\n\nFor detailed support options, see [SUPPORT.md](SUPPORT.md).\n\n## Sponsor\n\nIf you find Sablier valuable and want to support its development, please consider sponsoring the project:\n\n💖 **[Sponsor on GitHub](https://github.com/sponsors/acouvreur)** - Your sponsorship helps keep this project maintained and actively developed\n\nYour support helps:\n- Keep the project maintained and up-to-date\n- Dedicate more time to bug fixes and new features\n- Improve documentation and examples\n- Support the broader open-source ecosystem\n\nEvery contribution, no matter the size, makes a real difference. Thank you for considering! 🙏\n\n### DigitalOcean\n\n\u003cp\u003eThis project is supported by:\u003c/p\u003e\n\u003cp\u003e\n  \u003ca href=\"https://www.digitalocean.com/?refcode=67b25d34f559\u0026utm_campaign=Referral_Invite\u0026utm_medium=Referral_Program\u0026utm_source=badge\"\u003e\n    \u003cimg src=\"https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg\" width=\"201px\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsablierapp%2Fsablier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsablierapp%2Fsablier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsablierapp%2Fsablier/lists"}