Sablier - start & stop containers

tags

Running a home server can be an excellent way to self-host various web services, but it often comes with the challenge of resource management. While we want our services to be readily available, keeping them running continuously isn’t always necessary or efficient, especially for services we only access occasionally. This article explores how to implement an intelligent container management solution using Treafik and Sablier.

Background

When setting up a home server with Docker containers, we typically configure a reverse proxy (like Traefik) to route traffic to our various services. However, this traditional setup keeps containers running permanently, consuming resources even during periods of inactivity. By introducing Sablier into this architecture, we can create a more efficient “scale-to-zero” system that automatically manages container lifecycles based on actual usage.

Understanding Sablier

Sablier is a powerful plugin that integrates with popular proxy servers, particularly Traefik. Its primary function is to monitor traffic to your services and manage their container lifecycle accordingly. When a service receives no traffic for a specified period, Sablier will automatically shut it down. When new traffic arrives, Sablier can restart the service, either showing a loading screen or waiting for the service to become available.

Implementation Guide

1. Setting Up the Sablier Container

First, we need to add the Sablier service to our Docker Compose configuration:

services:
	traefik:
	    container_name: traefik
	    image: traefik:v3
	    ports:
	      - "80:80"
	      - "443:443"
	      - "8080:8080"
	    environment:
	      - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
	      - TZ=Europe/Bratislava
	    volumes:
	      - /var/run/docker.sock:/var/run/docker.sock
	      - ./config/traefik.yaml:/etc/traefik/traefik.yaml:ro
	      - ./config/dynamic:/etc/traefik/dynamic:ro
	      - ./config/certs:/var/traefik/certs:rw
	      - ./logs:/etc/traefik/log:rw
	    networks:
	      - traefik
	    restart: unless-stopped
	    
	sablier:
	    container_name: trefik-sablier
	    image: sablierapp/sablier:1.8.1
	    command:
	        - start
	        - --provider.name=docker
	    volumes:
	      - /var/run/docker.sock:/var/run/docker.sock
	    networks:
	      - traefik
	    restart: unless-stopped
 
networks:
  traefik:
    name: traefik
    external: true

This configuration:

  • User the Treafik configuration from the article Traefik - Configuring a Secure Docker Proxy
  • Uses the official Sablier image
  • Provides access to the Docker socket for container management
  • Connects to the Traefik network
  • Ensures the service restarts automatically if it stops unexpectedly

2. Configuring Traefik Integration

Next, we need to register Sablier as a plugin in our Traefik configuration (traefik.yaml):

# ...
 
################################################################
# Configuration providers
################################################################
providers:
  docker:
    endpoint: unix:///var/run/docker.sock
    exposedByDefault: false
    network: traefik
  file:
    directory: /etc/traefik/dynamic/
    watch: true
 
# ...
 
################################################################
# Plugins
################################################################
experimental:
  plugins:
    sablier:
      moduleName: "github.com/sablierapp/sablier"
      version: "v1.8.1"

3. Implementing Dynamic Service Configuration

Instead of using container labels, we’ll use dynamic configuration to set up our service routing and Sablier integration:

http:
  services:
    blog-service:
      loadBalancer:
        servers:
          - url: http://blog:8080
  routers:
    blog-http-router:
      rule: "Host(`blog.zloutek1.com`) || Host(`blog.epicartificials.com`)"
      service: blog-service
      middlewares:
        - blog-sablier@file
      entryPoints:
        - http
    blog-https-router:
      rule: "Host(`blog.zloutek1.com`) || Host(`blog.epicartificials.com`)"
      service: blog-service
      middlewares:
        - blog-sablier@file
      entryPoints:
        - https
      tls:
        certResolver: cloudflare
  middlewares:
    blog-sablier:
      plugin:
        sablier:
          sablierUrl: http://sablier:10000
          sessionDuration: 30m
          names: blog
          dynamic:
            displayName: blog
            refreshFrequency: 3s
            showDetails: true
            theme: ghost

This configuration implements several important features:

  • Sets up both HTTP and HTTPS routing for the blog service
  • Configures Sablier middleware with a 30-minute session duration
  • Implements a dynamic strategy with the “ghost” theme for loading screens
  • Enables automatic container management based on traffic patterns

How It Works

When this configuration is active, the system operates as follows:

  1. When a user accesses http://blog.zloutek1.com, Traefik receives the request
  2. If the blog container is stopped, Sablier intercepts the request
  3. Sablier starts the blog container
  4. During startup, users see the ghost theme loading screen
  5. Once the container is ready, traffic is forwarded to the blog service
  6. After 30 minutes of inactivity, Sablier automatically stops the container

This approach provides several benefits:

  • Reduces resource usage during inactive periods
  • Maintains service availability when needed
  • Provides a smooth user experience during container startup
  • Automatically manages container lifecycle without manual intervention

Configuration Options

Sablier offers two main strategies for handling requests during container startup:

  • Dynamic Strategy: Shows a loading screen (like the ghost theme used above)
  • Blocking Strategy: Waits for the service to start before responding

Choose the strategy that best fits your service’s needs and user experience requirements.

Further Reading

For more detailed information about implementing scale-to-zero solutions with Docker, see the article Docker Scale-to-Zero with Traefik and Sablier which provides additional configuration examples and best practices.