Skip to content

acouvreur/sablier

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
app
 
 
cmd
 
 
 
 
 
 
 
 
e2e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Sablier

Github Actions Go Report Go Version Latest Release

Sablier is an API that start containers for a given duration.

It provides an integrations with multiple reverse proxies and different loading strategies.

Which allows you to start your containers on demand and shut them down automatically as soon as there's no activity.

Hourglass

Quick start with Traefik

You will see how to use Sablier with Traefik in order to start your container automatically when reaching it by its route.

Demo

git clone https://github.com/acouvreur/sablier
cd sablier
docker-compose up -d
docker-compose stop whoami

# Now you go to http://localhost:8080/whoami/dynamic with your browser
# Or you can call the blocking URL, this will wait until whoami is started
curl http://localhost:8080/whoami/blocking

Hostname: 1d034329b651
IP: 127.0.0.1
IP: 172.18.0.2
RemoteAddr: 172.18.0.4:33052
GET /whoami/blocking HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: localhost:8080
X-Forwarded-Port: 8080
X-Forwarded-Proto: http
X-Forwarded-Server: 1aea141808c5
X-Real-Ip: 172.18.0.1

Reverse proxies integration plugins

The reverse proxy integrations is probably what you're most interested about.

It leverage the API calls to Sablier to your reverse proxy middleware to wake up your instances on demand.

Reverse Proxy Integration

Traefik Middleware Plugin

See Traefik Middleware Plugin

Guides

Sablier Guide: Code-Server + Traefik + Kubernetes Ingress

See Sablier Guide: Code-Server + Traefik + Kubernetes Ingress

Configuration

There are three different ways to define configuration options in Sablier:

  1. In a configuration file
  2. As environment variables
  3. In the command-line arguments

These ways are evaluated in the order listed above.

If no value was provided for a given option, a default value applies.

Configuration File

At startup, Sablier searches for configuration in a 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)
  name: docker 
server:
  # The server port to use
  port: 10000 
  # The base path for the API
  base-path: /
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: trace
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: false
    # 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

Environment Variables

All environment variables can be used in the form of the config file such as

strategy:
  dynamic:
    custom-themes-path: /my/path

Becomes

STRATEGY_DYNAMIC_CUSTOM_THEMES_PATH=/my/path

Arguments

To get the list of all available arguments:

sablier --help

# or

docker run acouvreur/sablier[:version] --help
# ex: docker run acouvreur/sablier:v1.0.0 --help

All arguments can be used in the form of the config file such as

strategy:
  dynamic:
    custom-themes-path: /my/path

Becomes

sablier start --strategy.dynamic.custom-themes-path /my/path

Install Sablier on its own

You can install Sablier with the following flavors:

  • Use the Docker image
  • Use the binary distribution
  • Compile your binary from the sources

Use the Docker image

Choose one of the Docker images and run it with one sample configuration file:

docker run -d -p 10000:10000 \
    -v $PWD/sablier.yml:/etc/sablier/sablier.yml acouvreur/sablier:1.1.0

Use the binary distribution

Grab the latest binary from the releases page.

And run it:

./sablier --help

Compile your binary from the sources

git clone git@github.com:acouvreur/sablier.git
cd sablier
make
# Output will change depending on your distro
./sablier_draft_linux-amd64

Loading with a waiting page

The Dynamic Strategy provides a waiting UI with multiple themes. This is best suited when this interaction is made through a browser.

Name Preview
ghost ghost
shuffle shuffle
hacker-terminal hacker-terminal
matrix matrix

Dynamic Strategy Configuration

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: false
    # 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

Creating your own loading theme

See creating your own theme.

Blocking the loading until the session is ready

The Blocking Strategy waits for the instances to load before serving the request This is best suited when this interaction from an API.

strategy:
  blocking:
    # Default timeout used for blocking strategy (default 1m)
    default-timeout: 1m

Saving the state to a file

You can save the state of the application in case of failure to resume your sessions.

For this you can use the storage configuration.

storage:
  file: /path/to/file.json

If the file doesn't exist it will be created, and it will be syned upon exit.

Loaded instances that expired during the restart won't be changed though, they will simply be ignored.

Sablier Healthcheck

Using the /health route

You can use the route /health to check for healthiness.

  • Returns 200 OK when ready
  • Returns 503 Service Unavailable when terminating

Using the sablier health command

You can use the command sablier health to check for healthiness.

sablier health takes on argument --url which defaults to http://localhost:10000/health.

services:
  sablier:
    image: acouvreur/sablier:1.2.0
    healthcheck:
      test: ["sablier", "health"]
      interval: 1m30s

API

To run the following examples you can create two containers:

  • docker create --name nginx nginx
  • docker create --name apache httpd

GET /api/strategies/dynamic

Description: The /api/strategies/dynamic endpoint allows you to request a waiting page for multiple instances

Parameter Value Description
names array of string The instances to be started
session_duration duration time.ParseDuration The session duration for all services, which will reset at each subsequent calls
show_details (optional) bool The details about instances
display_name (optional) string The display name
theme (optional) string The theme to use
refresh_frequency (optional) duration time.ParseDuration The refresh frequency for the loading page

Go to http://localhost:10000/api/strategies/dynamic?names=nginx&names=apache&session_duration=5m&show_details=true&display_name=example&theme=hacker-terminal&refresh_frequency=10s and you should see

A special header X-Sablier-Session-Status is returned and will have the value ready if all instances are ready. Or else not-ready.

API Dynamic Prompt image

GET /api/strategies/blocking

Description: The /api/strategies/blocking endpoint allows you to wait until the instances are ready

Parameter Value Description
names array of string The instances to be started
session_duration duration time.ParseDuration The session duration for all services, which will reset at each subsequent calls
timeout (optional) duration time.ParseDuration The maximum time to wait for instances to be ready

A special header X-Sablier-Session-Status is returned and will have the value ready if all instances are ready. Or else not-ready.

Curl example

curl -X GET -v "http://localhost:10000/api/strategies/blocking?names=nginx&names=apache&session_duration=5m&timeout=5s"
*   Trying 127.0.0.1:10000...
* Connected to localhost (127.0.0.1) port 10000 (#0)
> GET /api/strategies/blocking?names=nginx&names=apache&session_duration=5m&timeout=30s HTTP/1.1
> Host: localhost:10000
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< X-Sablier-Session-Status: ready
< Date: Mon, 14 Nov 2022 19:20:50 GMT
< Content-Length: 245
< 
{"session":
  {"instances":
    [
      {"instance":{"name":"nginx","currentReplicas":1,"desiredReplicas":1,"status":"ready"},"error":null},
      {"instance":{"name":"apache","currentReplicas":1,"desiredReplicas":1,"status":"ready"},"error":null}
    ],
    "status":"ready"
  }
}

Glossary

I'll use these terms in order to be provider agnostic.

  • Session: A Session is a set of instances
  • Instance: An instance is either a docker container, docker swarm service, kubernetes deployment or kubernetes statefulset

Versioning

Sablier follows the Semantic Versioning 2.0.0 Specification (SemVer).

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes
  2. MINOR version when you add functionality in a backwards compatible manner
  3. PATCH version when you make backwards compatible bug fixes

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

This process is fully automated using Semantic Release.

The configuration is release.config.js.

Credits