Docker SwarmSince v1.0.0
Introduction
The Docker Swarm provider scales replicated services to zero replicas when their session expires, and back up when a request needs them. Sablier runs as a service on a manager node and calls the Docker API through the node’s Docker socket.
Install Sablier
Deploy Sablier as a stack from a manager node:
docker stack deploy -c sablier.yml sablier# Sablier as a Swarm service:
# docker stack deploy -c sablier.yml sablier
services:
sablier:
image: sablierapp/sablier:1.19.0 # x-release-please-version
command:
- start
- --provider.name=docker_swarm
environment:
# sablier.running-hours windows use Sablier's local time.
TZ: Europe/Paris
volumes:
# The Docker socket of the manager node Sablier runs on.
- /var/run/docker.sock:/var/run/docker.sock
networks:
- sablier
deploy:
placement:
constraints:
# Only manager nodes serve the service API.
- node.role == manager
networks:
# Attach your reverse proxy to this network to reach http://sablier:10000.
sablier:
name: sablier
driver: overlay
attachable: true- Run Sablier on a manager node. Only managers serve the service API, so the placement constraint keeps Sablier there.
- Mount the manager’s Docker socket. Sablier lists, inspects and scales services through it.
Reverse proxy plugins reach Sablier at http://sablier:10000. Attach your reverse proxy to the sablier overlay network to resolve that name.
Usage example
Opt a service in with the sablier.enable service label, and give it a group:
# A service Sablier scales to zero when idle and back up on demand:
# docker stack deploy -c whoami.yml demo
services:
whoami:
image: sablierapp/mimic:v0.3.3
command: ["-healthy=true"]
# Sablier reports the service ready once its tasks pass this healthcheck.
healthcheck:
test: ["CMD", "/mimic", "healthcheck"]
interval: 2s
deploy:
# Service labels, not container labels: Sablier reads deploy.labels.
labels:
- sablier.enable=true
- sablier.group=whoamiDeploy it with docker stack deploy -c whoami.yml demo. Then configure your reverse proxy to call Sablier for the whoami group in front of the service. On the first request, Sablier scales the service to one replica and holds the request, or shows a waiting page, until its task passes its healthcheck. When the session expires, Sablier scales it back to zero.
Provider reference
Configuration
| Option | Value | Description |
|---|---|---|
--provider.name | docker_swarm or swarm | Selects the Docker Swarm provider. |
The provider has no options of its own. Sablier connects to Docker with the standard Docker environment variables, such as DOCKER_HOST. Without them, it uses the socket at /var/run/docker.sock.
Every --provider.* option that is not provider-specific also applies; see the CLI reference.
Workloads
Replicated services
Sablier scales replicated services by updating their replica count:
- Stop scales to
sablier.idle.replicas,0by default. - Start scales to
sablier.active.replicas,1by default.
Start ignores deploy.replicas. To run several replicas, set sablier.active.replicas to the same count:
services:
web:
deploy:
replicas: 3
labels:
- sablier.enable=true
- sablier.group=web
- sablier.active.replicas=3 # without it, Sablier starts one replicaInstance names
A reverse proxy can target one service by name instead of a group. The whoami service of the usage example, deployed in the demo stack, is named:
demo_whoamiThe instance name is the exact service name, as docker service ls lists it. docker stack deploy prefixes each service with the stack name and _.
Prefer groups: a name ties your proxy configuration to the stack name.
Labels
On Docker Swarm, Sablier settings are sablier.* service labels, under deploy.labels:
services:
team-api:
deploy:
labels:
- sablier.enable=true
- sablier.group=team-a,team-b- Put the labels under
deploy.labels. Sablier reads the service’s labels only. The service-levellabelskey sets container labels, which Sablier ignores on Swarm. sablier.enablemust be exactlytrue. Sablier finds services with asablier.enable=truelabel filter.
The label reference lists every key.
Services created without a stack file
With docker service create, set the keys with --label, which sets service labels. --container-label sets container labels, which Sablier ignores.
Workload settings
Each excerpt below is the start of a complete stack file in examples/docker-swarm.
EnableSince v1.4.0
sablier.enable=true opts the service in. It is required, must be a service label, and any other value is ignored. See the usage example.
GroupSince v1.4.0
sablier.group puts the service in one or more comma-separated groups. A session for any of them starts it. Without it, the service is in the default group.
services:
team-api:
deploy:
labels:
- sablier.enable=true
- sablier.group=team-a,team-bReady afterSince v1.13.0
sablier.ready-after keeps reporting the service as not ready for a settling delay after all its tasks first run. Use it when a task passes its healthcheck before it can serve traffic.
services:
slow-starter:
deploy:
labels:
- sablier.enable=true
- sablier.group=slow-starter
- sablier.ready-after=30sLearn more about delaying readiness.
Ready on startSince v1.15.0
sablier.ready-on-start=true reports the service ready as soon as Sablier sends the scale-up, without waiting for its tasks.
services:
fast-starter:
deploy:
labels:
- sablier.enable=true
- sablier.group=fast-starter
- sablier.ready-on-start=trueLearn more about marking ready on start.
Running hoursSince v1.13.0
sablier.running-hourskeeps the service running during a daily window.sablier.running-dayslimits that window to some weekdays, since v1.15.0.
services:
office-app:
deploy:
labels:
- sablier.enable=true
- sablier.group=office-app
- sablier.running-hours=09:00-18:00
- sablier.running-days=Mon,Tue,Wed,Thu,FriThe window uses Sablier’s local time. Set the time zone with the TZ environment variable of the Sablier service:
environment:
# sablier.running-hours windows use Sablier's local time.
TZ: Europe/ParisLearn more about running hours.
Anti-affinitySince v1.15.0
sablier.anti-affinity lists groups the service backs off from: Sablier keeps it idle while any of them has an active session.
services:
batch-worker:
deploy:
labels:
- sablier.enable=true
- sablier.group=batch
- sablier.anti-affinity=streamingLearn more about anti-affinity.
Scale instead of stopSince v1.13.0
Keep the service running when idle, optionally throttled, instead of scaling it to zero:
idle.replicasset to1or more keeps that many replicas when idle.idle.cpuandidle.memoryset the CPU and memory limits while idle.- The matching
active.*labels restore them on the next session.
CPU is in decimal cores, such as 0.5. Memory uses Docker units, such as 64m or 1g.
services:
warm-api:
deploy:
labels:
- sablier.enable=true
- sablier.group=warm-api
- sablier.idle.replicas=1
- sablier.idle.cpu=0.1
- sablier.idle.memory=64m
- sablier.active.cpu=2
- sablier.active.memory=512mactive counterpart.Learn more about scaling instead of stopping.
Readiness
Sablier compares the desired and running tasks of a service, and reports it:
- stopped when it has no desired task: it is scaled to
0. - ready when all desired tasks are running.
- starting otherwise.
Swarm marks a task running only once its container passes its healthcheck. Give your services one: without it, a task runs as soon as its container starts.
Limitations
- Sablier must reach the Docker API of a manager node: worker nodes do not serve the service API.
- Only replicated services are supported, not global services or jobs.
- Start always scales to
sablier.active.replicas, one replica by default, whateverdeploy.replicassays. - A service is ready only when all its desired tasks run: no option accepts the first ready task.
- Sablier does not start
depends_onservices. Put dependencies in the same group instead. - Block I/O throttling is not available on Docker Swarm.
docker stack deploysets each service back to itsdeploy.replicas, or one replica when unset. Redeploying a stack starts its stopped services, and Sablier treats them as started externally.
Examples
examples/docker-swarm: every stack file on this page, with instructions to run them.