15 KiB
Sablier - Lazy Loading Service
Table of Contents
- Overview
- What is Sablier?
- Why Use Sablier?
- How It Works
- Configuration in AI-Homelab
- Official Resources
- Educational Resources
- Docker Configuration
- Using Sablier
- Advanced Topics
- Troubleshooting
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?
- Resource Efficiency: Save memory and CPU by only running services when needed
- Power Savings: Reduce power consumption on always-on systems
- Faster Boot: Services start quickly when accessed vs. waiting for full system startup
- Scalability: Handle more services than would fit in memory simultaneously
- Cost Effective: Lower resource requirements mean smaller/fewer servers needed
- 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:
- Route Detection: Sablier monitors Traefik routes for configured services
- Container Check: Verifies if the target container is running
- Startup Process: If not running, starts the container via Docker API
- Health Verification: Waits for the service to report healthy
- Traffic Forwarding: Routes traffic to the now-running service
- 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
- GitHub Repository: https://github.com/sablierapp/sablier
- Docker Hub: https://hub.docker.com/r/sablierapp/sablier
- Documentation: https://sablierapp.github.io/sablier/
Educational Resources
- Traefik Integration: https://doc.traefik.io/traefik/middlewares/http/forwardauth/
- Docker Lazy Loading: Search for "docker lazy loading" or "container on-demand"
- Resource Management: Linux container resource management best practices
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
- Enable on Service: Add
sablier.enable=truelabel to any service - Access Service: Navigate to the service URL in your browser
- Automatic Startup: Sablier detects the request and starts the container
- Wait for Ready: Service starts and health checks pass
- Use Service: Container is now running and accessible
- 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:
- Change restart policy to
"no"in the compose file (critical for Sablier control) - Add Sablier labels to the service compose file
- Configure Traefik middleware for the service
- Stop the service initially (let Sablier manage it)
- Test access - service should start automatically
- 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 useunless-stopped,always, oron-failurerestart policies.
Related Documentation
- Traefik Documentation - Reverse proxy configuration
- Authelia Documentation - SSO authentication
- On-Demand Remote Services - Remote service setup guide