feat: Add comprehensive restart policy documentation and Sablier lazy loading support

- Add SERVER_HOSTNAME env var for Sablier group naming
- Update default hostname from 'jarvis' to 'debian' for generic repo compatibility
- Add restart policy documentation to all docker-compose files
- Add Sablier labels to lazy-loaded services (jellyfin, dozzle, glances, code-server, homarr, dokuwiki)
- Update sablier.yml template to use debian- prefixes
- Enhance deploy script to auto-detect hostname and update configurations
- Ensure all YAML files remain syntactically valid
This commit is contained in:
EZ-Homelab
2026-01-22 19:49:24 -05:00
parent 30bf095fd3
commit 9cc0e93c79
14 changed files with 172 additions and 59 deletions

View File

@@ -12,6 +12,9 @@ TZ=America/New_York
# Server IP address # Server IP address
SERVER_IP=192.168.1.100 SERVER_IP=192.168.1.100
# Server hostname (used for Sablier group naming)
SERVER_HOSTNAME=debian
# Default credentials (used by multiple services for easier setup) # Default credentials (used by multiple services for easier setup)
DEFAULT_USER=admin DEFAULT_USER=admin
DEFAULT_PASSWORD=changeme DEFAULT_PASSWORD=changeme

View File

@@ -1,10 +1,10 @@
http: http:
middlewares: middlewares:
sablier-jarvis-arr: sablier-debian-arr:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-arr group: debian-arr
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -12,11 +12,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-backrest: sablier-debian-backrest:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-backrest group: debian-backrest
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -24,11 +24,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-bookstack: sablier-debian-bookstack:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-bookstack group: debian-bookstack
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -36,11 +36,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-jellyfin: sablier-debian-jellyfin:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-jellyfin group: debian-jellyfin
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -48,11 +48,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-calibre-web: sablier-debian-calibre-web:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-calibre-web group: debian-calibre-web
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -60,11 +60,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-code-server: sablier-debian-code-server:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-code-server group: debian-code-server
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -72,11 +72,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-bitwarden: sablier-debian-bitwarden:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-bitwarden group: debian-bitwarden
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -84,11 +84,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-wordpress: sablier-debian-wordpress:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-wordpress group: debian-wordpress
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -96,11 +96,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-nextcloud: sablier-debian-nextcloud:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-nextcloud group: debian-nextcloud
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -108,11 +108,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-mediawiki: sablier-debian-mediawiki:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-mediawiki group: debian-mediawiki
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -120,11 +120,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-mealie: sablier-debian-mealie:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-mealie group: debian-mealie
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -132,11 +132,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-gitea: sablier-debian-gitea:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-gitea group: debian-gitea
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -144,11 +144,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-formio: sablier-debian-formio:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-formio group: debian-formio
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -156,11 +156,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-dozzle: sablier-debian-dozzle:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-dozzle group: debian-dozzle
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -168,11 +168,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-duplicati: sablier-debian-duplicati:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-duplicati group: debian-duplicati
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -180,11 +180,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-glances: sablier-debian-glances:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-glances group: debian-glances
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -192,11 +192,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-homarr: sablier-debian-homarr:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-homarr group: debian-homarr
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -204,11 +204,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-komodo: sablier-debian-komodo:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-komodo group: debian-komodo
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -217,11 +217,11 @@ http:
show-details-by-default: true show-details-by-default: true
sablier-jarvis-kopia: sablier-debian-kopia:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-kopia group: debian-kopia
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -229,11 +229,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-openkm: sablier-debian-openkm:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-openkm group: debian-openkm
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -241,11 +241,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-openwebui: sablier-debian-openwebui:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-openwebui group: debian-openwebui
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -253,11 +253,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-pulse: sablier-debian-pulse:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-pulse group: debian-pulse
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -265,11 +265,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-tdarr: sablier-debian-tdarr:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-tdarr group: debian-tdarr
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -277,11 +277,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-unmanic: sablier-debian-unmanic:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-unmanic group: debian-unmanic
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:
@@ -289,11 +289,11 @@ http:
theme: ghost theme: ghost
show-details-by-default: true show-details-by-default: true
sablier-jarvis-dokuwiki: sablier-debian-dokuwiki:
plugin: plugin:
sablier: sablier:
sablierUrl: http://sablier-service:10000 sablierUrl: http://sablier-service:10000
group: jarvis-dokuwiki group: debian-dokuwiki
sessionDuration: 30m sessionDuration: 30m
ignoreUserAgent: curl ignoreUserAgent: curl
dynamic: dynamic:

View File

@@ -3,10 +3,16 @@
# Deploy manually through Dockge if you want to use these alternatives # Deploy manually through Dockge if you want to use these alternatives
# Place in /opt/stacks/alternatives/docker-compose.yml # Place in /opt/stacks/alternatives/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
services: services:
# Portainer - Docker management UI (Alternative to Dockge) # Portainer - Docker management UI (Alternative to Dockge)
# Access at: https://portainer.${DOMAIN} # Access at: https://portainer.${DOMAIN}
# NOTE: Dockge is the default Docker management UI. Deploy Portainer only if you prefer its interface # NOTE: Dockge is the default Docker management UI. Deploy Portainer only if you prefer its interface
# Docker management interface should always run when deployed
portainer: portainer:
image: portainer/portainer-ce:2.19.4 image: portainer/portainer-ce:2.19.4
container_name: portainer container_name: portainer
@@ -33,6 +39,7 @@ services:
# Access at: https://authentik.${DOMAIN} # Access at: https://authentik.${DOMAIN}
# NOTE: Authelia is the default SSO. Deploy Authentik only if you need a web UI for user management # NOTE: Authelia is the default SSO. Deploy Authentik only if you need a web UI for user management
# WARNING: Do not run both Authelia and Authentik at the same time # WARNING: Do not run both Authelia and Authentik at the same time
# SSO service should always run when deployed as alternative to Authelia
authentik-server: authentik-server:
image: ghcr.io/goauthentik/server:2024.2.0 image: ghcr.io/goauthentik/server:2024.2.0
container_name: authentik-server container_name: authentik-server
@@ -66,6 +73,7 @@ services:
- authentik-redis - authentik-redis
# Authentik Worker - Background task processor # Authentik Worker - Background task processor
# SSO background worker should always run when Authentik is deployed
authentik-worker: authentik-worker:
image: ghcr.io/goauthentik/server:2024.2.0 image: ghcr.io/goauthentik/server:2024.2.0
container_name: authentik-worker container_name: authentik-worker
@@ -93,6 +101,7 @@ services:
- authentik-redis - authentik-redis
# Authentik Database - PostgreSQL # Authentik Database - PostgreSQL
# Database must always run for Authentik to function
authentik-db: authentik-db:
image: postgres:16-alpine image: postgres:16-alpine
container_name: authentik-db container_name: authentik-db
@@ -115,6 +124,7 @@ services:
retries: 5 retries: 5
# Authentik Redis - Cache and message queue # Authentik Redis - Cache and message queue
# Cache service must always run for Authentik performance
authentik-redis: authentik-redis:
image: redis:7-alpine image: redis:7-alpine
container_name: authentik-redis container_name: authentik-redis
@@ -136,6 +146,7 @@ services:
# Plex Media Server - Alternative to Jellyfin # Plex Media Server - Alternative to Jellyfin
# Access at: https://plex.yourdomain.duckdns.org # Access at: https://plex.yourdomain.duckdns.org
# NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc. # NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc.
# Media server should always run when deployed as alternative to Jellyfin
plex: plex:
image: plexinc/pms-docker:1.40.0.7998-f68041501 image: plexinc/pms-docker:1.40.0.7998-f68041501
container_name: plex container_name: plex

View File

@@ -1,3 +1,16 @@
# Core Infrastructure Services
# These services form the foundation of the homelab and should always be running
# Place in /opt/stacks/core/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs:
# - Traefik Dashboard: https://traefik.${DOMAIN}
# - Authelia: https://auth.${DOMAIN}
x-dockge: x-dockge:
urls: urls:
- https://auth.${DOMAIN} - https://auth.${DOMAIN}
@@ -5,6 +18,7 @@ x-dockge:
services: services:
duckdns: duckdns:
# Dynamic DNS service - must always run to maintain domain resolution
image: lscr.io/linuxserver/duckdns:latest image: lscr.io/linuxserver/duckdns:latest
container_name: duckdns container_name: duckdns
restart: unless-stopped restart: unless-stopped
@@ -20,6 +34,7 @@ services:
- traefik-network - traefik-network
traefik: traefik:
# Reverse proxy and SSL termination - core routing service, must always run
image: traefik:v3 image: traefik:v3
container_name: traefik container_name: traefik
restart: unless-stopped restart: unless-stopped
@@ -49,6 +64,7 @@ services:
- "x-dockge.url=https://traefik.${DOMAIN}" - "x-dockge.url=https://traefik.${DOMAIN}"
authelia: authelia:
# Single sign-on authentication service - must always run for user authentication
image: authelia/authelia:latest image: authelia/authelia:latest
container_name: authelia container_name: authelia
restart: unless-stopped restart: unless-stopped
@@ -74,6 +90,7 @@ services:
- x-dockge.url=https://auth.${DOMAIN} - x-dockge.url=https://auth.${DOMAIN}
# Sablier - Lazy loading service for Docker containers # Sablier - Lazy loading service for Docker containers
# Controls startup/shutdown of lazy-loaded services, must always run
sablier-service: sablier-service:
image: sablierapp/sablier:latest image: sablierapp/sablier:latest
container_name: sablier-service container_name: sablier-service

View File

@@ -2,6 +2,11 @@
# Homepage and Homarr for homelab dashboards # Homepage and Homarr for homelab dashboards
# Place in /opt/stacks/dashboards/docker-compose.yml # Place in /opt/stacks/dashboards/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Homepage: https://home.${DOMAIN} # - Homepage: https://home.${DOMAIN}
# - Homarr: https://homarr.${DOMAIN} # - Homarr: https://homarr.${DOMAIN}
@@ -9,6 +14,7 @@
services: services:
# Homepage - Application dashboard (AI-configurable via YAML) # Homepage - Application dashboard (AI-configurable via YAML)
# Access at: https://home.${DOMAIN} # Access at: https://home.${DOMAIN}
# Dashboard service should always run for quick access to service overview
homepage: homepage:
image: ghcr.io/gethomepage/homepage:latest image: ghcr.io/gethomepage/homepage:latest
deploy: deploy:
@@ -46,6 +52,7 @@ services:
# Homarr - Modern dashboard # Homarr - Modern dashboard
# Access at: https://homarr.${DOMAIN} # Access at: https://homarr.${DOMAIN}
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
homarr: homarr:
image: ghcr.io/ajnart/homarr:latest image: ghcr.io/ajnart/homarr:latest
deploy: deploy:
@@ -72,6 +79,9 @@ services:
labels: labels:
- "homelab.category=dashboard" - "homelab.category=dashboard"
- "homelab.description=Modern homelab dashboard" - "homelab.description=Modern homelab dashboard"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-homarr"
- "sablier.start-on-demand=true"
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.homarr.rule=Host(`homarr.${DOMAIN}`)" - "traefik.http.routers.homarr.rule=Host(`homarr.${DOMAIN}`)"
- "traefik.http.routers.homarr.entrypoints=websecure" - "traefik.http.routers.homarr.entrypoints=websecure"

View File

@@ -2,12 +2,18 @@
# Docker Compose Stack Manager # Docker Compose Stack Manager
# Place in /opt/dockge/docker-compose.yml # Place in /opt/dockge/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Dockge: https://dockge.${DOMAIN} # - Dockge: https://dockge.${DOMAIN}
services: services:
# Dockge - Docker Compose Stack Manager (PRIMARY - preferred over Portainer) # Dockge - Docker Compose Stack Manager (PRIMARY - preferred over Portainer)
# Access at: https://dockge.${DOMAIN} # Access at: https://dockge.${DOMAIN}
# Stack management interface should always run for container management
dockge: dockge:
image: louislam/dockge:1 image: louislam/dockge:1
deploy: deploy:

View File

@@ -4,6 +4,11 @@
# NOTE: Traefik, Authelia, DuckDNS, and Gluetun have their own separate stacks # NOTE: Traefik, Authelia, DuckDNS, and Gluetun have their own separate stacks
# See /opt/stacks/traefik/, /opt/stacks/authelia/, etc. # See /opt/stacks/traefik/, /opt/stacks/authelia/, etc.
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Portainer: https://portainer.${DOMAIN} # - Portainer: https://portainer.${DOMAIN}
# - Pi-hole: https://pihole.${DOMAIN} # - Pi-hole: https://pihole.${DOMAIN}
@@ -13,6 +18,7 @@
services: services:
dockerproxy: dockerproxy:
# Docker socket proxy for security - provides safe Docker API access, must always run
image: tecnativa/docker-socket-proxy:latest image: tecnativa/docker-socket-proxy:latest
container_name: dockerproxy container_name: dockerproxy
privileged: true privileged: true
@@ -33,6 +39,7 @@ services:
# Pi-hole - Network-wide ad blocker and DNS server # Pi-hole - Network-wide ad blocker and DNS server
# Access at: https://pihole.${DOMAIN} # Access at: https://pihole.${DOMAIN}
# DNS service must always run for network-wide ad blocking
pihole: pihole:
image: pihole/pihole:2024.01.0 image: pihole/pihole:2024.01.0
deploy: deploy:
@@ -76,14 +83,6 @@ services:
- "traefik.http.services.pihole.loadbalancer.server.port=80" - "traefik.http.services.pihole.loadbalancer.server.port=80"
- "x-dockge.url=https://pihole.${DOMAIN}" - "x-dockge.url=https://pihole.${DOMAIN}"
# Watchtower - Automatic container updates
# TEMPORARILY DISABLED: Docker API version incompatibility with Docker 29.x
# Watchtower versions have API compatibility issues:
# - v1.7.1: Uses API v1.25 (too old for Docker 29.x which requires min v1.44)
# - v1.7.2+/latest: Has issues with API negotiation
# Issue tracked for resolution in future release
# To enable: Uncomment service below and run: docker compose up -d watchtower
#
# Watchtower - Automatic container updates # Watchtower - Automatic container updates
# Monitors and updates Docker containers to latest versions # Monitors and updates Docker containers to latest versions
# Runs daily at 4 AM # Runs daily at 4 AM
@@ -108,6 +107,7 @@ services:
# Dozzle - Real-time Docker log viewer # Dozzle - Real-time Docker log viewer
# Access at: https://dozzle.${DOMAIN} # Access at: https://dozzle.${DOMAIN}
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
dozzle: dozzle:
image: amir20/dozzle:latest image: amir20/dozzle:latest
deploy: deploy:
@@ -133,6 +133,9 @@ services:
labels: labels:
- "homelab.category=infrastructure" - "homelab.category=infrastructure"
- "homelab.description=Real-time Docker log viewer" - "homelab.description=Real-time Docker log viewer"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-dozzle"
- "sablier.start-on-demand=true"
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.dozzle.rule=Host(`dozzle.${DOMAIN}`)" - "traefik.http.routers.dozzle.rule=Host(`dozzle.${DOMAIN}`)"
- "traefik.http.routers.dozzle.entrypoints=websecure" - "traefik.http.routers.dozzle.entrypoints=websecure"
@@ -142,6 +145,7 @@ services:
# Glances - System monitoring # Glances - System monitoring
# Access at: https://glances.${DOMAIN} # Access at: https://glances.${DOMAIN}
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
glances: glances:
image: nicolargo/glances:latest-full image: nicolargo/glances:latest-full
deploy: deploy:
@@ -167,6 +171,9 @@ services:
labels: labels:
- "homelab.category=infrastructure" - "homelab.category=infrastructure"
- "homelab.description=System and Docker monitoring" - "homelab.description=System and Docker monitoring"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-glances"
- "sablier.start-on-demand=true"
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.glances.rule=Host(`glances.${DOMAIN}`)" - "traefik.http.routers.glances.rule=Host(`glances.${DOMAIN}`)"
- "traefik.http.routers.glances.entrypoints=websecure" - "traefik.http.routers.glances.entrypoints=websecure"
@@ -176,6 +183,7 @@ services:
# Code Server - VS Code in browser # Code Server - VS Code in browser
# Access at: https://code.${DOMAIN} # Access at: https://code.${DOMAIN}
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
code-server: code-server:
image: lscr.io/linuxserver/code-server:latest image: lscr.io/linuxserver/code-server:latest
deploy: deploy:
@@ -205,6 +213,9 @@ services:
labels: labels:
- "homelab.category=infrastructure" - "homelab.category=infrastructure"
- "homelab.description=VS Code in browser" - "homelab.description=VS Code in browser"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-code-server"
- "sablier.start-on-demand=true"
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.code-server.rule=Host(`code.${DOMAIN}`)" - "traefik.http.routers.code-server.rule=Host(`code.${DOMAIN}`)"
- "traefik.http.routers.code-server.entrypoints=websecure" - "traefik.http.routers.code-server.entrypoints=websecure"

View File

@@ -2,6 +2,11 @@
# Content automation and library management (*arr apps, transcoders, etc.) # Content automation and library management (*arr apps, transcoders, etc.)
# Place in /opt/stacks/media-management/docker-compose.yml # Place in /opt/stacks/media-management/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Sonarr: https://sonarr.${DOMAIN} # - Sonarr: https://sonarr.${DOMAIN}
# - Radarr: https://radarr.${DOMAIN} # - Radarr: https://radarr.${DOMAIN}

View File

@@ -2,6 +2,10 @@
# Default Services for media management and streaming # Default Services for media management and streaming
# Place in /opt/stacks/media/docker-compose.yml # Place in /opt/stacks/media/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Jellyfin: https://jellyfin.${DOMAIN} (no SSO - app access) # - Jellyfin: https://jellyfin.${DOMAIN} (no SSO - app access)
@@ -12,6 +16,7 @@ services:
# Jellyfin - Open-source media streaming server # Jellyfin - Open-source media streaming server
# Access at: https://jellyfin.yourdomain.duckdns.org # Access at: https://jellyfin.yourdomain.duckdns.org
# NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc. # NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc.
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
jellyfin: jellyfin:
image: jellyfin/jellyfin:10.8.13 image: jellyfin/jellyfin:10.8.13
deploy: deploy:
@@ -43,6 +48,9 @@ services:
labels: labels:
- "homelab.category=media" - "homelab.category=media"
- "homelab.description=Open-source media streaming server" - "homelab.description=Open-source media streaming server"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-jellyfin"
- "sablier.start-on-demand=true"
# Traefik labels - NO Authelia for app access # Traefik labels - NO Authelia for app access
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.jellyfin.rule=Host(`jellyfin.${DOMAIN}`)" - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.${DOMAIN}`)"
@@ -51,7 +59,6 @@ services:
- "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt" - "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096" - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
- "x-dockge.url=https://jellyfin.${DOMAIN}" - "x-dockge.url=https://jellyfin.${DOMAIN}"
- "x-dockge.url=https://jellyfin.${DOMAIN}"
# Calibre-Web - Ebook reader and server # Calibre-Web - Ebook reader and server
# Access at: https://calibre.${DOMAIN} # Access at: https://calibre.${DOMAIN}

View File

@@ -2,6 +2,11 @@
# Services for monitoring your homelab infrastructure # Services for monitoring your homelab infrastructure
# Place in /opt/stacks/monitoring/docker-compose.yml # Place in /opt/stacks/monitoring/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Prometheus: http://server-ip:9090 (or configure Traefik) # - Prometheus: http://server-ip:9090 (or configure Traefik)
# - Grafana: http://server-ip:3000 (or configure Traefik) # - Grafana: http://server-ip:3000 (or configure Traefik)

View File

@@ -1,6 +1,11 @@
# Productivity and Content Management Services # Productivity and Content Management Services
# Place in /opt/stacks/productivity/docker-compose.yml # Place in /opt/stacks/productivity/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Nextcloud: https://nextcloud.${DOMAIN} # - Nextcloud: https://nextcloud.${DOMAIN}
# - Mealie: https://mealie.${DOMAIN} # - Mealie: https://mealie.${DOMAIN}
@@ -13,6 +18,7 @@
services: services:
# Nextcloud - File sync and collaboration # Nextcloud - File sync and collaboration
# Access at: https://nextcloud.${DOMAIN} # Access at: https://nextcloud.${DOMAIN}
# File storage service should always run for continuous sync
nextcloud: nextcloud:
image: nextcloud:28 image: nextcloud:28
deploy: deploy:
@@ -208,6 +214,7 @@ services:
# DokuWiki - Wiki without database # DokuWiki - Wiki without database
# Access at: https://wiki.${DOMAIN} # Access at: https://wiki.${DOMAIN}
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
dokuwiki: dokuwiki:
image: lscr.io/linuxserver/dokuwiki:latest image: lscr.io/linuxserver/dokuwiki:latest
container_name: dokuwiki container_name: dokuwiki
@@ -224,6 +231,9 @@ services:
labels: labels:
- "homelab.category=productivity" - "homelab.category=productivity"
- "homelab.description=File-based wiki" - "homelab.description=File-based wiki"
- "sablier.enable=true"
- "sablier.group=${SERVER_HOSTNAME:-debian}-dokuwiki"
- "sablier.start-on-demand=true"
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.dokuwiki.rule=Host(`dokuwiki.${DOMAIN}`)" - "traefik.http.routers.dokuwiki.rule=Host(`dokuwiki.${DOMAIN}`)"
- "traefik.http.routers.dokuwiki.entrypoints=websecure" - "traefik.http.routers.dokuwiki.entrypoints=websecure"

View File

@@ -1,6 +1,11 @@
# Backup and Utility Services # Backup and Utility Services
# Place in /opt/stacks/utilities/docker-compose.yml # Place in /opt/stacks/utilities/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - Backrest: https://backrest.${DOMAIN} # - Backrest: https://backrest.${DOMAIN}
# - Duplicati: https://duplicati.${DOMAIN} # - Duplicati: https://duplicati.${DOMAIN}

View File

@@ -2,12 +2,18 @@
# VPN client and VPN-routed download clients # VPN client and VPN-routed download clients
# Place in /opt/stacks/vpn/docker-compose.yml # Place in /opt/stacks/vpn/docker-compose.yml
# RESTART POLICY GUIDE:
# - unless-stopped: Core infrastructure services that should always run
# - no: Services with Sablier lazy loading (start on-demand)
# - See individual service comments for specific reasoning
# Service Access URLs: # Service Access URLs:
# - qBittorrent: https://qbit.${DOMAIN} # - qBittorrent: https://qbit.${DOMAIN}
services: services:
# Gluetun - VPN client (Surfshark) # Gluetun - VPN client (Surfshark)
# Routes download clients through VPN for security # Routes download clients through VPN for security
# VPN service should always run to maintain secure connections
gluetun: gluetun:
image: qmcgaw/gluetun:latest image: qmcgaw/gluetun:latest
container_name: gluetun container_name: gluetun

View File

@@ -218,6 +218,23 @@ if [ "$DEPLOY_CORE" = true ]; then
fi fi
cp -r "$REPO_DIR/config-templates/traefik" /opt/stacks/core/ cp -r "$REPO_DIR/config-templates/traefik" /opt/stacks/core/
# Detect server hostname and update configuration
log_info "Detecting server hostname..."
DETECTED_HOSTNAME=$(hostname)
if [ -n "$DETECTED_HOSTNAME" ] && [ "$DETECTED_HOSTNAME" != "debian" ]; then
log_info "Detected hostname: $DETECTED_HOSTNAME"
# Update SERVER_HOSTNAME in the copied .env file
sed -i "s/SERVER_HOSTNAME=.*/SERVER_HOSTNAME=$DETECTED_HOSTNAME/" /opt/stacks/core/.env
# Update SERVER_HOSTNAME in the source .env file for future deployments
sed -i "s/SERVER_HOSTNAME=.*/SERVER_HOSTNAME=$DETECTED_HOSTNAME/" "$REPO_DIR/.env"
# Update sablier.yml with detected hostname
sed -i "s/debian-/$DETECTED_HOSTNAME-/g" /opt/stacks/core/traefik/dynamic/sablier.yml
log_success "Updated configuration with detected hostname: $DETECTED_HOSTNAME"
else
log_info "Using default hostname 'debian' (hostname detection failed or returned default)"
fi
echo ""
if [ -d "/opt/stacks/core/authelia" ]; then if [ -d "/opt/stacks/core/authelia" ]; then
log_warning "Authelia configuration already exists in /opt/stacks/core/" log_warning "Authelia configuration already exists in /opt/stacks/core/"
log_info "Creating backup: authelia.backup.$(date +%Y%m%d_%H%M%S)" log_info "Creating backup: authelia.backup.$(date +%Y%m%d_%H%M%S)"