Files
EZ-Homelab/docs/service-docs/sablier.md
kelinfoxy 16b7e1f1a7 Documentation Reorganization
Major upgrade to the documentation.
2026-01-20 19:01:21 -05:00

15 KiB

Sablier - Lazy Loading Service

Table of Contents

Overview

Category: Core Infrastructure Docker Image: sablierapp/sablier Default Stack: core.yml Web UI: No web UI (API only) Authentication: None required Purpose: On-demand container startup and resource management

What is Sablier?

Sablier is a lightweight service that enables lazy loading for Docker containers. It automatically starts containers when they're accessed through Traefik and stops them after a period of inactivity, helping to conserve system resources and reduce power consumption.

Key Features

  • On-Demand Startup: Containers start automatically when accessed
  • Automatic Shutdown: Containers stop after configurable inactivity periods
  • Traefik Integration: Works seamlessly with Traefik reverse proxy
  • Resource Conservation: Reduces memory and CPU usage for unused services
  • Group Management: Related services can be managed as groups
  • Health Checks: Waits for services to be ready before forwarding traffic
  • Minimal Overhead: Lightweight with low resource requirements

Why Use Sablier?

  1. Resource Efficiency: Save memory and CPU by only running services when needed
  2. Power Savings: Reduce power consumption on always-on systems
  3. Faster Boot: Services start quickly when accessed vs. waiting for full system startup
  4. Scalability: Handle more services than would fit in memory simultaneously
  5. Cost Effective: Lower resource requirements mean smaller/fewer servers needed
  6. Environmental: Reduce energy consumption and carbon footprint

How It Works

User Request → Traefik → Sablier Check → Container Start → Health Check → Forward Traffic
                                      ↓
                               Container Stop (after timeout)

When a request comes in for a service with Sablier enabled:

  1. Route Detection: Sablier monitors Traefik routes for configured services
  2. Container Check: Verifies if the target container is running
  3. Startup Process: If not running, starts the container via Docker API
  4. Health Verification: Waits for the service to report healthy
  5. Traffic Forwarding: Routes traffic to the now-running service
  6. Timeout Monitoring: Tracks inactivity and stops containers after timeout

Configuration in AI-Homelab

Sablier is deployed as part of the core infrastructure stack and requires no additional configuration for basic operation. It automatically discovers services with the appropriate labels.

Service Integration

Add these labels to any service that should use lazy loading:

services:
  myservice:
    # ... other configuration ...
    labels:
      - "sablier.enable=true"
      - "sablier.group=core-myservice"  # Optional: group related services
      - "traefik.enable=true"
      - "traefik.http.routers.myservice.rule=Host(`myservice.${DOMAIN}`)"
      # ... other Traefik labels ...

Advanced Configuration

For services requiring custom timeouts or group management:

labels:
  - "sablier.enable=true"
  - "sablier.group=media-services"        # Group name for related services
  - "sablier.timeout=300"                 # 5 minutes inactivity timeout (default: 300)
  - "sablier.theme=dark"                  # Optional: theme for Sablier UI (if used)

Official Resources

Educational Resources

Docker Configuration

Environment Variables

Variable Description Default Required
SABLIER_PROVIDER Container runtime provider docker Yes
SABLIER_DOCKER_API_VERSION Docker API version 1.53 No
SABLIER_DOCKER_NETWORK Docker network for containers traefik-network Yes
SABLIER_LOG_LEVEL Logging level (debug, info, warn, error) debug No
DOCKER_HOST Docker socket endpoint tcp://docker-proxy:2375 Yes

Ports

  • 10000 - Sablier API endpoint (internal use only)

Volumes

None required - Sablier communicates with Docker via API

Networks

  • traefik-network - Required for communication with Traefik
  • homelab-network - Required for Docker API access

Using Sablier

Basic Usage

  1. Enable on Service: Add sablier.enable=true label to any service
  2. Access Service: Navigate to the service URL in your browser
  3. Automatic Startup: Sablier detects the request and starts the container
  4. Wait for Ready: Service starts and health checks pass
  5. Use Service: Container is now running and accessible
  6. Automatic Shutdown: Container stops after 5 minutes of inactivity

Monitoring Lazy Loading

Check which services are managed by Sablier:

# View all containers with Sablier labels
docker ps --filter "label=sablier.enable=true" --format "table {{.Names}}\t{{.Status}}"

# Check Sablier logs
docker logs sablier

# View Traefik routes that trigger lazy loading
docker logs traefik | grep sablier

Service Groups

Group related services that should start/stop together:

# Database and web app in same group
services:
  myapp:
    labels:
      - "sablier.enable=true"
      - "sablier.group=myapp-stack"

  myapp-db:
    labels:
      - "sablier.enable=true"
      - "sablier.group=myapp-stack"

Custom Timeouts

Set different inactivity timeouts per service:

labels:
  - "sablier.enable=true"
  - "sablier.timeout=600"  # 10 minutes

Advanced Topics

Performance Considerations

  • Startup Time: Services take longer to respond on first access
  • Resource Spikes: Multiple services starting simultaneously can cause load
  • Health Checks: Ensure services have proper health checks for reliable startup

Troubleshooting Startup Issues

  • Container Won't Start: Check Docker logs for the failing container
  • Health Check Fails: Verify service health endpoints are working
  • Network Issues: Ensure containers are on the correct Docker network

Integration with Monitoring

Sablier works with existing monitoring:

  • Prometheus: Can monitor Sablier API metrics
  • Grafana: Visualize container start/stop events
  • Dozzle: View logs from lazy-loaded containers

Troubleshooting

Service Won't Start Automatically

Symptoms: Accessing service URL shows connection error

Solutions:

# Check if Sablier is running
docker ps | grep sablier

# Verify service has correct labels
docker inspect container-name | grep sablier

# Check Sablier logs
docker logs sablier

# Test manual container start
docker start container-name

Containers Not Stopping

Symptoms: Containers remain running after inactivity timeout

Solutions:

# Check timeout configuration
docker inspect container-name | grep sablier.timeout

# Verify Sablier has access to Docker API
docker exec sablier curl -f http://docker-proxy:2375/_ping

# Check for active connections
netstat -tlnp | grep :port

Traefik Routing Issues

Symptoms: Service accessible but Sablier not triggering

Solutions:

# Verify Traefik labels
docker inspect container-name | grep traefik

# Check Traefik configuration
docker logs traefik | grep "Creating router"

# Test direct access (bypass Sablier)
curl http://container-name:port/health

Common Issues

Issue: Services start but are not accessible Fix: Ensure services are on the traefik-network

Issue: Sablier can't connect to Docker API Fix: Verify DOCKER_HOST environment variable and network connectivity

Issue: Containers start but health checks fail Fix: Add proper health checks to service configurations

Issue: High resource usage during startup Fix: Stagger service startups or increase system resources

Performance Tuning

  • Increase Timeouts: For services that need longer inactivity periods
  • Group Services: Related services can share startup/shutdown cycles
  • Monitor Resources: Use Glances or Prometheus to track resource usage
  • Optimize Health Checks: Ensure health checks are fast and reliable

Getting Help

  • GitHub Issues: https://github.com/sablierapp/sablier/issues
  • Community: Check Traefik and Docker forums for lazy loading discussions
  • Logs: Enable debug logging with SABLIER_LOG_LEVEL=debug
    • "sablier.start-on-demand=true" # Enable lazy loading

### Traefik Middleware

Configure Sablier middleware in Traefik dynamic configuration:

```yaml
http:
  middlewares:
    sablier-service:
      plugin:
        sablier:
          sablierUrl: http://sablier-service:10000
          group: core-service-name
          sessionDuration: 2m    # How long to keep service running after access
          ignoreUserAgent: curl  # Don't start service for curl requests
          dynamic:
            displayName: Service Name
            theme: ghost
            show-details-by-default: true

Examples

Basic Service with Lazy Loading

services:
  my-service:
    image: my-service:latest
    container_name: my-service
    restart: "no"  # Important: Must be "no" for Sablier to control start/stop
    networks:
      - traefik-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-service.rule=Host(`my-service.${DOMAIN}`)"
      - "traefik.http.routers.my-service.entrypoints=websecure"
      - "traefik.http.routers.my-service.tls.certresolver=letsencrypt"
      - "traefik.http.routers.my-service.middlewares=authelia@docker"
      - "traefik.http.services.my-service.loadbalancer.server.port=8080"
      # Sablier lazy loading
      - "sablier.enable=true"
      - "sablier.group=core-my-service"
      - "sablier.start-on-demand=true"

Remote Service Proxy

For services on remote servers, configure Traefik routes with Sablier middleware:

# In /opt/stacks/core/traefik/dynamic/remote-services.yml
http:
  routers:
    remote-service:
      rule: "Host(`remote-service.${DOMAIN}`)"
      entryPoints:
        - websecure
      service: remote-service
      tls:
        certResolver: letsencrypt
      middlewares:
        - sablier-remote-service@file

  services:
    remote-service:
      loadBalancer:
        servers:
          - url: "http://remote-server-ip:port"

  middlewares:
    sablier-remote-service:
      plugin:
        sablier:
          sablierUrl: http://sablier-service:10000
          group: remote-server-group
          sessionDuration: 5m
          displayName: Remote Service

Troubleshooting

Service Won't Start

Check Sablier logs:

cd /opt/stacks/core
docker compose logs sablier-service

Verify container permissions:

# Check if Sablier can access Docker API
docker exec sablier-service curl -f http://localhost:10000/health

Services Not Starting on Demand

Check Traefik middleware configuration:

# Verify middleware is loaded
docker logs traefik | grep sablier

Check service labels:

# Verify Sablier labels are present
docker inspect service-name | grep sablier

Services Stop Too Quickly

Increase session duration:

middlewares:
  sablier-service:
    plugin:
      sablier:
        sessionDuration: 10m  # Increase from default

Performance Issues

Check resource usage:

docker stats sablier-service

Monitor Docker API calls:

docker logs sablier-service | grep "API call"

Best Practices

Resource Management

  • Use lazy loading for services that aren't accessed frequently
  • Set appropriate session durations based on usage patterns
  • Monitor resource usage to ensure adequate system capacity

Configuration

  • Always set restart: "no" for Sablier-managed services to allow full lifecycle control
  • Group related services together for coordinated startup
  • Use descriptive display names for the loading page
  • Configure appropriate timeouts for your use case

Security

  • Sablier runs with Docker API access - ensure proper network isolation
  • Use Docker socket proxy for additional security
  • Monitor Sablier logs for unauthorized access attempts

Integration with Other Services

Homepage Dashboard

Add Sablier status to Homepage:

# In homepage config
- Core Infrastructure:
    - Sablier:
        icon: docker.png
        href: http://sablier-service:10000
        description: Lazy loading service
        widget:
          type: iframe
          url: http://sablier-service:10000

Monitoring

Monitor Sablier with Prometheus metrics (if available) or basic health checks:

# Health check
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:10000/health"]
  interval: 30s
  timeout: 10s
  retries: 3

Advanced Configuration

Custom Themes

Sablier supports different loading page themes:

dynamic:
  displayName: My Service
  theme: ghost      # Options: ghost, hacker, ocean, etc.
  show-details-by-default: true

Group Management

Services can be grouped for coordinated startup:

# All services in the same group start together
labels:
  - "sablier.group=media-stack"
  - "sablier.enable=true"
  - "sablier.start-on-demand=true"

API Access

Sablier provides a REST API for programmatic control:

# Get service status
curl http://sablier-service:10000/api/groups

# Start a service group
curl -X POST http://sablier-service:10000/api/groups/media-stack/start

# Stop a service group
curl -X POST http://sablier-service:10000/api/groups/media-stack/stop

Migration from Manual Management

When adding Sablier to existing services:

  1. Change restart policy to "no" in the compose file (critical for Sablier control)
  2. Add Sablier labels to the service compose file
  3. Configure Traefik middleware for the service
  4. Stop the service initially (let Sablier manage it)
  5. Test access - service should start automatically
  6. Monitor logs to ensure proper operation

Important

: Services managed by Sablier must have restart: "no" to allow Sablier full control over container lifecycle. Do not use unless-stopped, always, or on-failure restart policies.