From 3701b11a733b6763f4fff74dad1c51b98e4ec7b7 Mon Sep 17 00:00:00 2001 From: EZ-Homelab Date: Fri, 23 Jan 2026 15:25:25 -0500 Subject: [PATCH] feat: Update Sablier configs for debian hostname and reorganize .env.example - Change Traefik configs to use ${SERVER_HOSTNAME} placeholder (defaults to debian) - Update ez-homelab.sh to replace SERVER_HOSTNAME in config templates - Set Sablier session duration to 5m for testing (increase to 30m for production) - Add SERVER_HOSTNAME prompt and saving in setup script - Reorganize .env.example with better structure and SMTP variables - Add production guidance comments to docker-compose files - Intentional SMTP variable redundancy for service flexibility --- .env.example | 204 ++-- .../dynamic/external-host-production.yml | 264 ++--- config-templates/traefik/dynamic/sablier.yml | 151 +-- docker-compose/dashboards/docker-compose.yml | 8 +- .../infrastructure/docker-compose.yml | 10 +- docker-compose/media/docker-compose.yml | 8 +- .../productivity/docker-compose.yml | 20 +- scripts/ez-homelab.sh | 10 + working-config-from-jasper.md | 901 ++++++++++++++++++ 9 files changed, 1247 insertions(+), 329 deletions(-) create mode 100644 working-config-from-jasper.md diff --git a/.env.example b/.env.example index 9b3b85a..5e0780a 100644 --- a/.env.example +++ b/.env.example @@ -1,93 +1,88 @@ # Environment Variables Template -# Copy this file to .env and fill in your values: cp .env.example .env -# NEVER commit .env to git! +# Copy this file to .env and fill in your values -# User and Group IDs (get with: id -u and id -g) +# User and Group IDs for file permissions (get with: id -u and id -g) PUID=1000 PGID=1000 -# Timezone (list: timedatectl list-timezones) TZ=America/New_York -# Server IP address SERVER_IP=192.168.1.100 +SERVER_HOSTNAME=debian # used for Sablier group naming -# Server hostname (used for Sablier group naming) -SERVER_HOSTNAME=debian +# Domain & DuckDNS Configuration +DUCKDNS_SUBDOMAINS=yourdomain # Without .duckdns.org +DOMAIN=${DUCKDNS_SUBDOMAINS}.duckdns.org +DUCKDNS_TOKEN=your-duckdns-token # Default credentials (used by multiple services for easier setup) DEFAULT_USER=admin DEFAULT_PASSWORD=changeme DEFAULT_EMAIL=admin@example.com -# ==================================== -# DOMAIN & DNS CONFIGURATION -# ==================================== +# DIRECTORY PATHS -# Your DuckDNS domain (without https://) -DOMAIN=yourdomain.duckdns.org +USERDIR=/opt/stacks # all docker-compose stacks +MEDIADIR=/mnt/media # Large media files on separate drive +DOWNLOADDIR=/mnt/downloads # Downloads on separate drive +PROJECTDIR=~/projects # User's projects folder -# DuckDNS Configuration -DUCKDNS_TOKEN=your-duckdns-token -DUCKDNS_SUBDOMAINS=yourdomain # Without .duckdns.org + +################################################### +# ==== Everything above this line is required ==== +################################################### + + +# Surfshark OpenVPN (RECOMMENDED - Default) +# Wireguard options are below and commented out +SURFSHARK_USERNAME=your-surfshark-username +SURFSHARK_PASSWORD=your-surfshark-password +VPN_SERVER_COUNTRIES=Netherlands # Preferred VPN server location + +# Optional: Email credentials for services that need SMTP +SMTP_EMAIL_SERVER=smtp.gmail.com +SMTP_EMAIL_PORT=587 +SMTP_EMAIL_PASSWORD=your-email-app-password +SMTP_EMAIL_FROM=${DEFAULT_EMAIL} +SMTP_EMAIL_SECURITY=starttls + +################################################## +# #### Individual Service Configurations #### +# The default values should work as a starting point +################################################## # Let's Encrypt / ACME (for SSL certificates) ACME_EMAIL=${DEFAULT_EMAIL} ADMIN_EMAIL=${DEFAULT_EMAIL} # Used for admin user account -# Cloudflare API (optional, for DNS challenge instead of DuckDNS) -# CF_DNS_API_TOKEN=your-cloudflare-api-token - -# ==================================== # AUTHELIA SSO CONFIGURATION -# ==================================== -# Generate these secrets with: openssl rand -hex 64 # The setup script will auto-generate these if not set AUTHELIA_JWT_SECRET=generate-with-openssl-rand-hex-64 AUTHELIA_SESSION_SECRET=generate-with-openssl-rand-hex-64 AUTHELIA_STORAGE_ENCRYPTION_KEY=generate-with-openssl-rand-hex-64 -# Authelia Admin Credentials -# These will be auto-generated by setup-homelab.sh -# DO NOT set these manually - they are generated during setup +# #### Authelia Admin Credentials #### + +# These will be auto-generated by EZ-Homelab.sh # AUTHELIA_ADMIN_USER=${DEFAULT_USER} # AUTHELIA_ADMIN_EMAIL=${DEFAULT_EMAIL} # AUTHELIA_ADMIN_PASSWORD=${DEFAULT_PASSWORD} # SMTP for Authelia Notifications (OPTIONAL) # If not configured, notifications are saved to file instead -# SMTP_USERNAME=your-email@example.com -# SMTP_PASSWORD=your-smtp-password +# SMTP_USERNAME=${SMTP_EMAIL_FROM} +# SMTP_PASSWORD=${SMTP_EMAIL_PASSWORD} -# ==================================== -# VPN CONFIGURATION (GLUETUN) -# ==================================== - -# Surfshark OpenVPN (RECOMMENDED - Default) -SURFSHARK_USERNAME=your-surfshark-username -SURFSHARK_PASSWORD=your-surfshark-password -VPN_SERVER_COUNTRIES=Netherlands # Preferred VPN server location +# #### VPN OPTIONAL WIREGUARD CONFIGURATION (GLUETUN) #### # Surfshark WireGuard (OPTIONAL - Advanced users only) -# Only needed if you prefer WireGuard over OpenVPN # Get WireGuard details from Surfshark dashboard # SURFSHARK_PRIVATE_KEY=your-wireguard-private-key # SURFSHARK_ADDRESSES=10.14.0.2/16 -# ==================================== -# DIRECTORY PATHS -# ==================================== - -USERDIR=/opt/stacks -MEDIADIR=/mnt/media # Large media files on separate drive -DOWNLOADDIR=/mnt/downloads # Downloads on separate drive -PROJECTDIR=/home/username/projects - -# ==================================== -# ALTERNATIVE SERVICES (OPTIONAL) +# #### ALTERNATIVE SERVICES (OPTIONAL) #### # Deploy alternatives.yml stack if you want these -# ==================================== # Authentik SSO (alternative to Authelia with web UI) # WARNING: Do not run both Authelia and Authentik at the same time @@ -96,63 +91,42 @@ PROJECTDIR=/home/username/projects # AUTHENTIK_DB_USER=authentik # AUTHENTIK_DB_PASSWORD=changeme-authentik-db-password # AUTHENTIK_DB_NAME=authentik +# PLEX_CLAIM=claim-xxxxxxxxxx # Uncomment to user Plex instead of Jellyfin -# ==================================== -# MEDIA SERVICES -# ==================================== -PLEX_CLAIM=claim-xxxxxxxxxx - -# qBittorrent -QBITTORRENT_USER=admin -QBITTORRENT_PASS=${DEFAULT_PASSWORD} - -# ==================================== -# INFRASTRUCTURE SERVICES -# ==================================== +# #### INFRASTRUCTURE SERVICES #### # Pi-hole PIHOLE_PASSWORD=${DEFAULT_PASSWORD} # Watchtower Notifications (optional) -# If not set, Watchtower will still update containers but without notifications -# Supports various notification services via Shoutrrr URL format -# Examples: -# Discord: discord://token@webhookid -# Slack: slack://token@channel -# Email: smtp://username:password@host:port/?from=sender@example.com +# If not set, Watchtower will still update containers but without notifications +# Supports various notification services via Shoutrrr URL format # WATCHTOWER_NOTIFICATION_URL= -# ==================================== -# MONITORING & DASHBOARDS -# ==================================== +# #### Other Services #### +# qBittorrent +QBITTORRENT_USER=admin +QBITTORRENT_PASS=${DEFAULT_PASSWORD} + +# GRAFANA GRAFANA_ADMIN_PASSWORD=${DEFAULT_PASSWORD} -# ==================================== -# DEVELOPMENT TOOLS -# ==================================== - +# VS Code Server CODE_SERVER_PASSWORD=${DEFAULT_PASSWORD} CODE_SERVER_SUDO_PASSWORD=${DEFAULT_PASSWORD} +# Jupyter Notebook JUPYTER_TOKEN=${DEFAULT_PASSWORD} -# ==================================== # DATABASES - GENERAL -# ==================================== - POSTGRES_USER=${DEFAULT_USER} POSTGRES_PASSWORD=${DEFAULT_PASSWORD} POSTGRES_DB=homelab - PGADMIN_EMAIL=${DEFAULT_EMAIL} PGADMIN_PASSWORD=${DEFAULT_PASSWORD} -# ==================================== -# PRODUCTIVITY SERVICES -# ==================================== - # Nextcloud NEXTCLOUD_ADMIN_USER=${DEFAULT_USER} NEXTCLOUD_ADMIN_PASSWORD=${DEFAULT_PASSWORD} @@ -174,51 +148,45 @@ BOOKSTACK_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} MEDIAWIKI_DB_PASSWORD=${DEFAULT_PASSWORD} MEDIAWIKI_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} -# ==================================== -# UTILITIES -# ==================================== - -# Bitwarden (Vaultwarden) Password Manager -# Admin token: openssl rand -base64 48 +# Bitwarden (Vaultwarden) BITWARDEN_ADMIN_TOKEN=${DEFAULT_PASSWORD} BITWARDEN_SIGNUPS_ALLOWED=true # Set to false after creating accounts BITWARDEN_INVITATIONS_ALLOWED=true -SMTP_HOST=smtp.gmail.com -SMTP_FROM=${DEFAULT_EMAIL} -SMTP_PORT=587 -SMTP_SECURITY=starttls +SMTP_HOST=${SMTP_EMAIL_SERVER} +SMTP_FROM=${SMTP_EMAIL_FROM} +SMTP_PORT=${SMTP_EMAIL_PORT} +SMTP_SECURITY=${SMTP_EMAIL_SECURITY} # Form.io FORMIO_JWT_SECRET=${DEFAULT_PASSWORD} FORMIO_DB_SECRET=${DEFAULT_PASSWORD} -# ==================================== +#################################### # HOMEPAGE DASHBOARD - API KEYS -# Generate these from each service's settings page -# ==================================== +#################################### -HOMEPAGE_VAR_DOMAIN=${DOMAIN} -HOMEPAGE_VAR_SERVER_IP=${SERVER_IP} -HOMEPAGE_VAR_PORTAINER_KEY=your-portainer-api-key -HOMEPAGE_VAR_PIHOLE_KEY=your-pihole-api-key -HOMEPAGE_VAR_PLEX_KEY=your-plex-token -HOMEPAGE_VAR_JELLYFIN_KEY=your-jellyfin-api-key -HOMEPAGE_VAR_SONARR_KEY=your-sonarr-api-key -HOMEPAGE_VAR_RADARR_KEY=your-radarr-api-key -HOMEPAGE_VAR_LIDARR_KEY=your-lidarr-api-key -HOMEPAGE_VAR_READARR_KEY=your-readarr-api-key -HOMEPAGE_VAR_PROWLARR_KEY=your-prowlarr-api-key -HOMEPAGE_VAR_JELLYSEERR_KEY=your-jellyseerr-api-key -HOMEPAGE_VAR_QBITTORRENT_USER=${QBITTORRENT_USER} -HOMEPAGE_VAR_QBITTORRENT_PASS=${QBITTORRENT_PASS} -HOMEPAGE_VAR_HA_KEY=your-home-assistant-long-lived-token -HOMEPAGE_VAR_NEXTCLOUD_USER=${NEXTCLOUD_ADMIN_USER} -HOMEPAGE_VAR_NEXTCLOUD_PASS=${NEXTCLOUD_ADMIN_PASSWORD} -HOMEPAGE_VAR_GRAFANA_USER=admin -HOMEPAGE_VAR_GRAFANA_PASS=${GRAFANA_ADMIN_PASSWORD} -HOMEPAGE_VAR_BOOKSTACK_KEY=your-bookstack-api-token -HOMEPAGE_VAR_UPTIMEKUMA_SLUG=your-uptime-kuma-slug -HOMEPAGE_VAR_OPENWEATHER_KEY=your-openweather-api-key -HOMEPAGE_VAR_WEATHERAPI_KEY=your-weatherapi-key -HOMEPAGE_VAR_UNIFI_USER=your-unifi-username -HOMEPAGE_VAR_UNIFI_PASS=your-unifi-password \ No newline at end of file +# HOMEPAGE_VAR_DOMAIN=${DOMAIN} +# HOMEPAGE_VAR_SERVER_IP=${SERVER_IP} +# HOMEPAGE_VAR_PORTAINER_KEY=your-portainer-api-key +# HOMEPAGE_VAR_PIHOLE_KEY=your-pihole-api-key +# HOMEPAGE_VAR_PLEX_KEY=your-plex-token +# HOMEPAGE_VAR_JELLYFIN_KEY=your-jellyfin-api-key +# HOMEPAGE_VAR_SONARR_KEY=your-sonarr-api-key +# HOMEPAGE_VAR_RADARR_KEY=your-radarr-api-key +# HOMEPAGE_VAR_LIDARR_KEY=your-lidarr-api-key +# HOMEPAGE_VAR_READARR_KEY=your-readarr-api-key +# HOMEPAGE_VAR_PROWLARR_KEY=your-prowlarr-api-key +# HOMEPAGE_VAR_JELLYSEERR_KEY=your-jellyseerr-api-key +# HOMEPAGE_VAR_QBITTORRENT_USER=${QBITTORRENT_USER} +# HOMEPAGE_VAR_QBITTORRENT_PASS=${QBITTORRENT_PASS} +# HOMEPAGE_VAR_HA_KEY=your-home-assistant-long-lived-token +# HOMEPAGE_VAR_NEXTCLOUD_USER=${NEXTCLOUD_ADMIN_USER} +# HOMEPAGE_VAR_NEXTCLOUD_PASS=${NEXTCLOUD_ADMIN_PASSWORD} +# HOMEPAGE_VAR_GRAFANA_USER=admin +# HOMEPAGE_VAR_GRAFANA_PASS=${GRAFANA_ADMIN_PASSWORD} +# HOMEPAGE_VAR_BOOKSTACK_KEY=your-bookstack-api-token +# HOMEPAGE_VAR_UPTIMEKUMA_SLUG=your-uptime-kuma-slug +# HOMEPAGE_VAR_OPENWEATHER_KEY=your-openweather-api-key +# HOMEPAGE_VAR_WEATHERAPI_KEY=your-weatherapi-key +# HOMEPAGE_VAR_UNIFI_USER=your-unifi-username +# HOMEPAGE_VAR_UNIFI_PASS=your-unifi-password \ No newline at end of file diff --git a/config-templates/traefik/dynamic/external-host-production.yml b/config-templates/traefik/dynamic/external-host-production.yml index b613446..6d286bb 100644 --- a/config-templates/traefik/dynamic/external-host-production.yml +++ b/config-templates/traefik/dynamic/external-host-production.yml @@ -1,535 +1,535 @@ http: routers: - backrest-jarvis: + backrest-${SERVER_HOSTNAME}: rule: "Host(`backrest.${DOMAIN}`)" entryPoints: - websecure - service: backrest-jarvis + service: backrest-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-backrest@file + - sablier-${SERVER_HOSTNAME}-backrest@file - authelia@docker - bookstack-jarvis: + bookstack-${SERVER_HOSTNAME}: rule: "Host(`bookstack.${DOMAIN}`)" entryPoints: - websecure - service: bookstack-jarvis + service: bookstack-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-bookstack@file + - sablier-${SERVER_HOSTNAME}-bookstack@file - authelia@docker - bitwarden-jarvis: + bitwarden-${SERVER_HOSTNAME}: rule: "Host(`bitwarden.${DOMAIN}`)" entryPoints: - websecure - service: bitwarden-jarvis + service: bitwarden-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-bitwarden@file + - sablier-${SERVER_HOSTNAME}-bitwarden@file - authelia@docker - calibre-web-jarvis: + calibre-web-${SERVER_HOSTNAME}: rule: "Host(`calibre.${DOMAIN}`)" entryPoints: - websecure - service: calibre-web-jarvis + service: calibre-web-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-calibre-web@file + - sablier-${SERVER_HOSTNAME}-calibre-web@file - authelia@docker - code-jarvis: + code-${SERVER_HOSTNAME}: rule: "Host(`code.${DOMAIN}`)" entryPoints: - websecure - service: code-jarvis + service: code-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-code-server@file + - sablier-${SERVER_HOSTNAME}-code-server@file - authelia@docker - dockge-jarvis: + dockge-${SERVER_HOSTNAME}: rule: "Host(`jarvis.${DOMAIN}`)" entryPoints: - websecure - service: dockge-jarvis + service: dockge-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - authelia@docker - dockhand-jarvis: + dockhand-${SERVER_HOSTNAME}: rule: "Host(`dockhand.${DOMAIN}`)" entryPoints: - websecure - service: dockhand-jarvis + service: dockhand-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - authelia@docker - dokuwiki-jarvis: + dokuwiki-${SERVER_HOSTNAME}: rule: "Host(`dokuwiki.${DOMAIN}`)" entryPoints: - websecure - service: dokuwiki-jarvis + service: dokuwiki-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-dokuwiki@file + - sablier-${SERVER_HOSTNAME}-dokuwiki@file - authelia@docker - dozzle-jarvis: + dozzle-${SERVER_HOSTNAME}: rule: "Host(`dozzle.${DOMAIN}`)" entryPoints: - websecure - service: dozzle-jarvis + service: dozzle-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-dozzle@file + - sablier-${SERVER_HOSTNAME}-dozzle@file - authelia@docker - duplicati-jarvis: + duplicati-${SERVER_HOSTNAME}: rule: "Host(`duplicati.${DOMAIN}`)" entryPoints: - websecure - service: duplicati-jarvis + service: duplicati-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-duplicati@file + - sablier-${SERVER_HOSTNAME}-duplicati@file - authelia@docker - formio-jarvis: + formio-${SERVER_HOSTNAME}: rule: "Host(`formio.${DOMAIN}`)" entryPoints: - websecure - service: formio-jarvis + service: formio-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-formio@file + - sablier-${SERVER_HOSTNAME}-formio@file - authelia@docker - gitea-jarvis: + gitea-${SERVER_HOSTNAME}: rule: "Host(`gitea.${DOMAIN}`)" entryPoints: - websecure - service: gitea-jarvis + service: gitea-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-gitea@file + - sablier-${SERVER_HOSTNAME}-gitea@file - authelia@docker - glances-jarvis: + glances-${SERVER_HOSTNAME}: rule: "Host(`glances.jarvis.${DOMAIN}`)" entryPoints: - websecure - service: glances-jarvis + service: glances-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-glances@file + - sablier-${SERVER_HOSTNAME}-glances@file - authelia@docker - homepage-jarvis: + homepage-${SERVER_HOSTNAME}: rule: "Host(`homepage.jarvis.${DOMAIN}`)" entryPoints: - websecure - service: homepage-jarvis + service: homepage-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - authelia@docker - homarr-jarvis: + homarr-${SERVER_HOSTNAME}: rule: "Host(`homarr.${DOMAIN}`)" entryPoints: - websecure - service: homarr-jarvis + service: homarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - authelia@docker - - sablier-jarvis-homarr@file + - sablier-${SERVER_HOSTNAME}-homarr@file - jellyfin-jarvis: + jellyfin-${SERVER_HOSTNAME}: rule: "Host(`jellyfin.${DOMAIN}`)" entryPoints: - websecure - service: jellyfin-jarvis + service: jellyfin-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-jellyfin@file + - sablier-${SERVER_HOSTNAME}-jellyfin@file # No authelia middleware for media apps - kopia-jarvis: + kopia-${SERVER_HOSTNAME}: rule: "Host(`kopia.${DOMAIN}`)" entryPoints: - websecure - service: kopia-jarvis + service: kopia-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-kopia@file + - sablier-${SERVER_HOSTNAME}-kopia@file - authelia@docker - mealie-jarvis: + mealie-${SERVER_HOSTNAME}: rule: "Host(`mealie.${DOMAIN}`)" entryPoints: - websecure - service: mealie-jarvis + service: mealie-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-mealie@file + - sablier-${SERVER_HOSTNAME}-mealie@file - authelia@docker - motioneye-jarvis: + motioneye-${SERVER_HOSTNAME}: rule: "Host(`motioneye.${DOMAIN}`)" entryPoints: - websecure - service: motioneye-jarvis + service: motioneye-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - authelia@docker - mediawiki-jarvis: + mediawiki-${SERVER_HOSTNAME}: rule: "Host(`mediawiki.${DOMAIN}`)" entryPoints: - websecure - service: mediawiki-jarvis + service: mediawiki-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-mediawiki@file + - sablier-${SERVER_HOSTNAME}-mediawiki@file - authelia@docker - nextcloud-jarvis: + nextcloud-${SERVER_HOSTNAME}: rule: "Host(`nextcloud.${DOMAIN}`)" entryPoints: - websecure - service: nextcloud-jarvis + service: nextcloud-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-nextcloud@file + - sablier-${SERVER_HOSTNAME}-nextcloud@file - authelia@docker - openkm-jarvis: + openkm-${SERVER_HOSTNAME}: rule: "Host(`openkm.${DOMAIN}`)" entryPoints: - websecure - service: openkm-jarvis + service: openkm-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-openkm@file + - sablier-${SERVER_HOSTNAME}-openkm@file - authelia@docker - openwebui-jarvis: + openwebui-${SERVER_HOSTNAME}: rule: "Host(`openwebui.${DOMAIN}`)" entryPoints: - websecure - service: openwebui-jarvis + service: openwebui-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-openwebui@file + - sablier-${SERVER_HOSTNAME}-openwebui@file - authelia@docker - qbittorrent-jarvis: + qbittorrent-${SERVER_HOSTNAME}: rule: "Host(`torrents.${DOMAIN}`)" entryPoints: - websecure - service: qbittorrent-jarvis + service: qbittorrent-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - tdarr-jarvis: + tdarr-${SERVER_HOSTNAME}: rule: "Host(`tdarr.${DOMAIN}`)" entryPoints: - websecure - service: tdarr-jarvis + service: tdarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - unmanic-jarvis: + unmanic-${SERVER_HOSTNAME}: rule: "Host(`unmanic.${DOMAIN}`)" entryPoints: - websecure - service: unmanic-jarvis + service: unmanic-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-unmanic@file + - sablier-${SERVER_HOSTNAME}-unmanic@file - authelia@docker - wordpress-jarvis: + wordpress-${SERVER_HOSTNAME}: rule: "Host(`knot-u.${DOMAIN}`)" entryPoints: - websecure - service: wordpress-jarvis + service: wordpress-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-wordpress@file + - sablier-${SERVER_HOSTNAME}-wordpress@file - authelia@file # Arr Services (no SSO for media apps) - jellyseerr-jarvis: + jellyseerr-${SERVER_HOSTNAME}: rule: "Host(`jellyseerr.${DOMAIN}`)" entryPoints: - websecure - service: jellyseerr-jarvis + service: jellyseerr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - prowlarr-jarvis: + prowlarr-${SERVER_HOSTNAME}: rule: "Host(`prowlarr.${DOMAIN}`)" entryPoints: - websecure - service: prowlarr-jarvis + service: prowlarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - radarr-jarvis: + radarr-${SERVER_HOSTNAME}: rule: "Host(`radarr.${DOMAIN}`)" entryPoints: - websecure - service: radarr-jarvis + service: radarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - sonarr-jarvis: + sonarr-${SERVER_HOSTNAME}: rule: "Host(`sonarr.${DOMAIN}`)" entryPoints: - websecure - service: sonarr-jarvis + service: sonarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - lidarr-jarvis: + lidarr-${SERVER_HOSTNAME}: rule: "Host(`lidarr.${DOMAIN}`)" entryPoints: - websecure - service: lidarr-jarvis + service: lidarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - readarr-jarvis: + readarr-${SERVER_HOSTNAME}: rule: "Host(`readarr.${DOMAIN}`)" entryPoints: - websecure - service: readarr-jarvis + service: readarr-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker - mylar3-jarvis: + mylar3-${SERVER_HOSTNAME}: rule: "Host(`mylar3.${DOMAIN}`)" entryPoints: - websecure - service: mylar3-jarvis + service: mylar3-${SERVER_HOSTNAME} tls: certResolver: letsencrypt middlewares: - - sablier-jarvis-arr@file + - sablier-${SERVER_HOSTNAME}-arr@file - authelia@docker services: - backrest-jarvis: + backrest-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:9898" passHostHeader: true - bitwarden-jarvis: + bitwarden-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8000" passHostHeader: true - bookstack-jarvis: + bookstack-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:6875" passHostHeader: true - calibre-web-jarvis: + calibre-web-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8083" passHostHeader: true - code-jarvis: + code-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8079" passHostHeader: true - dockge-jarvis: + dockge-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:5001" passHostHeader: true - dockhand-jarvis: + dockhand-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:3003" passHostHeader: true - dokuwiki-jarvis: + dokuwiki-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8087" passHostHeader: true - dozzle-jarvis: + dozzle-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8085" passHostHeader: true - duplicati-jarvis: + duplicati-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8200" passHostHeader: true - formio-jarvis: + formio-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:3002" passHostHeader: true - gitea-jarvis: + gitea-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:3010" passHostHeader: true - glances-jarvis: + glances-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:61208" passHostHeader: true - homarr-jarvis: + homarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:7575" passHostHeader: true - homepage-jarvis: + homepage-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:3000" passHostHeader: true - jellyfin-jarvis: + jellyfin-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8096" passHostHeader: true - kopia-jarvis: + kopia-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:51515" passHostHeader: true - mealie-jarvis: + mealie-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:9000" passHostHeader: true - mediawiki-jarvis: + mediawiki-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8084" passHostHeader: true - motioneye-jarvis: + motioneye-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8081" passHostHeader: true - nextcloud-jarvis: + nextcloud-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8089" passHostHeader: true - openkm-jarvis: + openkm-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:18080" passHostHeader: true - openwebui-jarvis: + openwebui-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:3000" passHostHeader: true - qbittorrent-jarvis: + qbittorrent-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8080" passHostHeader: true - tdarr-jarvis: + tdarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8265" passHostHeader: true - unmanic-jarvis: + unmanic-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8888" passHostHeader: true - wordpress-jarvis: + wordpress-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8088" @@ -537,43 +537,43 @@ http: # Arr Services - jellyseerr-jarvis: + jellyseerr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:5055" passHostHeader: true - prowlarr-jarvis: + prowlarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:9696" passHostHeader: true - radarr-jarvis: + radarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:7878" passHostHeader: true - sonarr-jarvis: + sonarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8989" passHostHeader: true - lidarr-jarvis: + lidarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8686" passHostHeader: true - readarr-jarvis: + readarr-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8787" passHostHeader: true - mylar3-jarvis: + mylar3-${SERVER_HOSTNAME}: loadBalancer: servers: - url: "http://192.168.4.11:8090" diff --git a/config-templates/traefik/dynamic/sablier.yml b/config-templates/traefik/dynamic/sablier.yml index 31d4b1c..fce0df4 100644 --- a/config-templates/traefik/dynamic/sablier.yml +++ b/config-templates/traefik/dynamic/sablier.yml @@ -1,215 +1,216 @@ +# Session duration set to 5m for testing. Increase to 30m for production. http: middlewares: - sablier-debian-arr: + sablier-${SERVER_HOSTNAME}-arr: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-arr - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-arr + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Arr Apps theme: ghost show-details-by-default: true - sablier-debian-backrest: + sablier-${SERVER_HOSTNAME}-backrest: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-backrest - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-backrest + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Backrest theme: ghost show-details-by-default: true - sablier-debian-bookstack: + sablier-${SERVER_HOSTNAME}-bookstack: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-bookstack - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-bookstack + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Bookstack theme: ghost show-details-by-default: true - sablier-debian-jellyfin: + sablier-${SERVER_HOSTNAME}-jellyfin: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-jellyfin - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-jellyfin + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Jellyfin theme: ghost show-details-by-default: true - sablier-debian-calibre-web: + sablier-${SERVER_HOSTNAME}-calibre-web: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-calibre-web - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-calibre-web + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Calibre Web theme: ghost show-details-by-default: true - sablier-debian-code-server: + sablier-${SERVER_HOSTNAME}-code-server: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-code-server - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-code-server + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Code Server theme: ghost show-details-by-default: true - sablier-debian-bitwarden: + sablier-${SERVER_HOSTNAME}-bitwarden: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-bitwarden - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-bitwarden + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: bitwarden theme: ghost show-details-by-default: true - sablier-debian-wordpress: + sablier-${SERVER_HOSTNAME}-wordpress: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-wordpress - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-wordpress + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: wordpress theme: ghost show-details-by-default: true - sablier-debian-nextcloud: + sablier-${SERVER_HOSTNAME}-nextcloud: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-nextcloud - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-nextcloud + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: NextCloud theme: ghost show-details-by-default: true - sablier-debian-mediawiki: + sablier-${SERVER_HOSTNAME}-mediawiki: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-mediawiki - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-mediawiki + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: mediawiki theme: ghost show-details-by-default: true - sablier-debian-mealie: + sablier-${SERVER_HOSTNAME}-mealie: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-mealie - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-mealie + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Mealie theme: ghost show-details-by-default: true - sablier-debian-gitea: + sablier-${SERVER_HOSTNAME}-gitea: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-gitea - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-gitea + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Gitea theme: ghost show-details-by-default: true - sablier-debian-formio: + sablier-${SERVER_HOSTNAME}-formio: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-formio - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-formio + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: FormIO theme: ghost show-details-by-default: true - sablier-debian-dozzle: + sablier-${SERVER_HOSTNAME}-dozzle: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-dozzle - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-dozzle + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: dozzle theme: ghost show-details-by-default: true - sablier-debian-duplicati: + sablier-${SERVER_HOSTNAME}-duplicati: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-duplicati - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-duplicati + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Duplicati theme: ghost show-details-by-default: true - sablier-debian-glances: + sablier-${SERVER_HOSTNAME}-glances: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-glances - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-glances + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Glances theme: ghost show-details-by-default: true - sablier-debian-homarr: + sablier-${SERVER_HOSTNAME}-homarr: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-homarr - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-homarr + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Homarr theme: ghost show-details-by-default: true - sablier-debian-komodo: + sablier-${SERVER_HOSTNAME}-komodo: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-komodo - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-komodo + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Komodo @@ -217,84 +218,84 @@ http: show-details-by-default: true - sablier-debian-kopia: + sablier-${SERVER_HOSTNAME}-kopia: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-kopia - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-kopia + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Kopia theme: ghost show-details-by-default: true - sablier-debian-openkm: + sablier-${SERVER_HOSTNAME}-openkm: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-openkm - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-openkm + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: OpenKM theme: ghost show-details-by-default: true - sablier-debian-openwebui: + sablier-${SERVER_HOSTNAME}-openwebui: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-openwebui - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-openwebui + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: OpenWebUI theme: ghost show-details-by-default: true - sablier-debian-pulse: + sablier-${SERVER_HOSTNAME}-pulse: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-pulse - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-pulse + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Pulse theme: ghost show-details-by-default: true - sablier-debian-tdarr: + sablier-${SERVER_HOSTNAME}-tdarr: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-tdarr - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-tdarr + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Tdarr theme: ghost show-details-by-default: true - sablier-debian-unmanic: + sablier-${SERVER_HOSTNAME}-unmanic: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-unmanic - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-unmanic + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: Unmanic theme: ghost show-details-by-default: true - sablier-debian-dokuwiki: + sablier-${SERVER_HOSTNAME}-dokuwiki: plugin: sablier: sablierUrl: http://sablier-service:10000 - group: debian-dokuwiki - sessionDuration: 30m + group: ${SERVER_HOSTNAME}-dokuwiki + sessionDuration: 5m ignoreUserAgent: curl dynamic: displayName: DokuWiki diff --git a/docker-compose/dashboards/docker-compose.yml b/docker-compose/dashboards/docker-compose.yml index 6c2861a..859dd60 100644 --- a/docker-compose/dashboards/docker-compose.yml +++ b/docker-compose/dashboards/docker-compose.yml @@ -2,6 +2,8 @@ # Homepage and Homarr for homelab dashboards # Place in /opt/stacks/dashboards/docker-compose.yml +# SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml + # RESTART POLICY GUIDE: # - unless-stopped: Core infrastructure services that should always run # - no: Services with Sablier lazy loading (start on-demand) @@ -31,6 +33,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "3000:3000" volumes: - ./homepage:/app/config - /var/run/docker.sock:/var/run/docker.sock # For Docker integration do not mount RO @@ -52,7 +56,7 @@ services: # Homarr - Modern dashboard # Access at: https://homarr.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity homarr: image: ghcr.io/ajnart/homarr:latest deploy: @@ -69,6 +73,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "7575:7575" volumes: - ./homarr/config:/app/config/configs - ./homarr/data:/data diff --git a/docker-compose/infrastructure/docker-compose.yml b/docker-compose/infrastructure/docker-compose.yml index ab3d8db..a2c14c2 100644 --- a/docker-compose/infrastructure/docker-compose.yml +++ b/docker-compose/infrastructure/docker-compose.yml @@ -4,6 +4,8 @@ # NOTE: Traefik, Authelia, DuckDNS, and Gluetun have their own separate stacks # See /opt/stacks/traefik/, /opt/stacks/authelia/, etc. +# SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml + # RESTART POLICY GUIDE: # - unless-stopped: Core infrastructure services that should always run # - no: Services with Sablier lazy loading (start on-demand) @@ -111,7 +113,7 @@ services: # Dozzle - Real-time Docker log viewer # Access at: https://dozzle.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity dozzle: image: amir20/dozzle:latest deploy: @@ -128,6 +130,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: @@ -166,6 +170,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "61208:61208" pid: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -204,6 +210,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "8443:8443" volumes: - ./code-server/config:/config - /opt/stacks:/opt/stacks # Access to all stacks diff --git a/docker-compose/media/docker-compose.yml b/docker-compose/media/docker-compose.yml index c516360..e585fab 100644 --- a/docker-compose/media/docker-compose.yml +++ b/docker-compose/media/docker-compose.yml @@ -2,6 +2,8 @@ # Default Services for media management and streaming # Place in /opt/stacks/media/docker-compose.yml +# SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml + # RESTART POLICY GUIDE: # - unless-stopped: Core infrastructure services that should always run # - no: Services with Sablier lazy loading (start on-demand) @@ -16,7 +18,7 @@ services: # Jellyfin - Open-source media streaming server # Access at: https://jellyfin.yourdomain.duckdns.org # NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc. - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity jellyfin: image: jellyfin/jellyfin:10.8.13 deploy: @@ -34,6 +36,8 @@ services: - media-network - homelab-network - traefik-network + ports: + - "8096:8096" volumes: - ./jellyfin/config:/config - ./jellyfin/cache:/cache @@ -86,6 +90,8 @@ services: - media-network - homelab-network - traefik-network + ports: + - "8083:8083" volumes: - ./calibre-web/config:/config - /mnt/media/books:/books diff --git a/docker-compose/productivity/docker-compose.yml b/docker-compose/productivity/docker-compose.yml index 3a62764..bec1be9 100644 --- a/docker-compose/productivity/docker-compose.yml +++ b/docker-compose/productivity/docker-compose.yml @@ -1,6 +1,8 @@ # Productivity and Content Management Services # Place in /opt/stacks/productivity/docker-compose.yml +# SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml + # RESTART POLICY GUIDE: # - unless-stopped: Core infrastructure services that should always run # - no: Services with Sablier lazy loading (start on-demand) @@ -36,6 +38,8 @@ services: - homelab-network - traefik-network - nextcloud-network + ports: + - "80:80" volumes: - ./nextcloud/html:/var/www/html - /mnt/nextcloud-data:/var/www/html/data # Large data on separate drive @@ -89,6 +93,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "9000:9000" volumes: - ./mealie/data:/app/data environment: @@ -117,6 +123,8 @@ services: - homelab-network - traefik-network - wordpress-network + ports: + - "80:80" volumes: - ./wordpress/html:/var/www/html environment: @@ -172,6 +180,8 @@ services: - homelab-network - traefik-network - gitea-network + ports: + - "3000:3000" volumes: - ./gitea/data:/data - /etc/timezone:/etc/timezone:ro @@ -214,7 +224,7 @@ services: # DokuWiki - Wiki without database # Access at: https://wiki.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity dokuwiki: image: lscr.io/linuxserver/dokuwiki:latest container_name: dokuwiki @@ -222,6 +232,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "80:80" volumes: - ./dokuwiki/config:/config environment: @@ -251,6 +263,8 @@ services: - homelab-network - traefik-network - bookstack-network + ports: + - "80:80" volumes: - ./bookstack/config:/config environment: @@ -304,6 +318,8 @@ services: - homelab-network - traefik-network - mediawiki-network + ports: + - "80:80" volumes: - ./mediawiki/images:/var/www/html/images - ./mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php @@ -351,6 +367,8 @@ services: networks: - homelab-network - traefik-network + ports: + - "8888:8888" volumes: - ./config/jupyter:/home/jovyan/work environment: diff --git a/scripts/ez-homelab.sh b/scripts/ez-homelab.sh index ab519cb..b4a1c02 100755 --- a/scripts/ez-homelab.sh +++ b/scripts/ez-homelab.sh @@ -55,6 +55,7 @@ load_env_file() { echo "Current configuration:" echo " Domain: ${DOMAIN:-Not set}" echo " Server IP: ${SERVER_IP:-Not set}" + echo " Server Hostname: ${SERVER_HOSTNAME:-Not set}" echo " Admin User: ${AUTHELIA_ADMIN_USER:-Not set}" echo " Admin Email: ${AUTHELIA_ADMIN_EMAIL:-Not set}" echo " Timezone: ${TZ:-Not set}" @@ -79,6 +80,7 @@ save_env_file() { # Update values sed -i "s%DOMAIN=.*%DOMAIN=$DOMAIN%" "$REPO_DIR/.env" sed -i "s%SERVER_IP=.*%SERVER_IP=$SERVER_IP%" "$REPO_DIR/.env" + sed -i "s%SERVER_HOSTNAME=.*%SERVER_HOSTNAME=$SERVER_HOSTNAME%" "$REPO_DIR/.env" sed -i "s%TZ=.*%TZ=$TZ%" "$REPO_DIR/.env" # Authelia settings (only if deploying core) @@ -165,6 +167,13 @@ prompt_for_values() { [ -n "$input" ] && SERVER_IP="$input" fi + # Server Hostname + if [ -z "$SERVER_HOSTNAME" ]; then + SERVER_HOSTNAME="debian" + fi + read -p "Server hostname [$SERVER_HOSTNAME] (press Enter to keep current): " input + [ -n "$input" ] && SERVER_HOSTNAME="$input" + # Timezone if [ -z "$TZ" ]; then TZ="America/New_York" @@ -369,6 +378,7 @@ perform_deployment() { # Replace domain placeholders in traefik dynamic configs find /opt/stacks/core/traefik/dynamic -name "*.yml" -exec sed -i "s/\${DOMAIN}/${DOMAIN}/g" {} \; + find /opt/stacks/core/traefik/dynamic -name "*.yml" -exec sed -i "s/\${SERVER_HOSTNAME}/${SERVER_HOSTNAME}/g" {} \; if [ -d "/opt/stacks/core/authelia" ]; then mv /opt/stacks/core/authelia /opt/stacks/core/authelia.backup.$(date +%Y%m%d_%H%M%S) diff --git a/working-config-from-jasper.md b/working-config-from-jasper.md new file mode 100644 index 0000000..49b05e5 --- /dev/null +++ b/working-config-from-jasper.md @@ -0,0 +1,901 @@ +This file contains the current configuration for Traefik & Sablier on the server jarvis (192.168.4.4) +This configuration was working in a previous test round. + +external-host-jarvis.yml +```yaml +http: + routers: + backrest-jarvis: + rule: "Host(`backrest.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: backrest-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-backrest@file + - authelia@docker + + bookstack-jarvis: + rule: "Host(`bookstack.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: bookstack-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-bookstack@file + - authelia@docker + + bitwarden-jarvis: + rule: "Host(`bitwarden.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: bitwarden-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-bitwarden@file + - authelia@docker + + calibre-web-jarvis: + rule: "Host(`calibre.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: calibre-web-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-calibre-web@file + - authelia@docker + + code-jarvis: + rule: "Host(`code.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: code-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-code-server@file + - authelia@docker + + dockge-jarvis: + rule: "Host(`jarvis.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: dockge-jarvis + tls: + certResolver: letsencrypt + middlewares: + - authelia@docker + + dockhand-jarvis: + rule: "Host(`dockhand.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: dockhand-jarvis + tls: + certResolver: letsencrypt + middlewares: + - authelia@docker + + dokuwiki-jarvis: + rule: "Host(`wiki.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: dokuwiki-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-dokuwiki@file + - authelia@docker + + dozzle-jarvis: + rule: "Host(`dozzle.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: dozzle-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-dozzle@file + - authelia@docker + + duplicati-jarvis: + rule: "Host(`duplicati.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: duplicati-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-duplicati@file + - authelia@docker + + formio-jarvis: + rule: "Host(`formio.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: formio-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-formio@file + - authelia@docker + + gitea-jarvis: + rule: "Host(`gitea.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: gitea-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-gitea@file + - authelia@docker + + glances-jarvis: + rule: "Host(`glances.jarvis.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: glances-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-glances@file + - authelia@docker + + homepage-jarvis: + rule: "Host(`homepage.jarvis.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: homepage-jarvis + tls: + certResolver: letsencrypt + middlewares: + - authelia@docker + + homarr-jarvis: + rule: "Host(`homarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: homarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - authelia@docker + - sablier-jarvis-homarr@file + + jellyfin-jarvis: + rule: "Host(`jellyfin.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: jellyfin-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-jellyfin@file + # No authelia middleware for media apps + + kopia-jarvis: + rule: "Host(`kopia.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: kopia-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-kopia@file + - authelia@docker + + mealie-jarvis: + rule: "Host(`mealie.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: mealie-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-mealie@file + - authelia@docker + + motioneye-jarvis: + rule: "Host(`motioneye.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: motioneye-jarvis + tls: + certResolver: letsencrypt + middlewares: + - authelia@docker + + mediawiki-jarvis: + rule: "Host(`mediawiki.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: mediawiki-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-mediawiki@file + - authelia@docker + + nextcloud-jarvis: + rule: "Host(`nextcloud.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: nextcloud-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-nextcloud@file + - authelia@docker + + openkm-jarvis: + rule: "Host(`openkm.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: openkm-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-openkm@file + - authelia@docker + + openwebui-jarvis: + rule: "Host(`openwebui.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: openwebui-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-openwebui@file + - authelia@docker + + qbittorrent-jarvis: + rule: "Host(`torrents.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: qbittorrent-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + tdarr-jarvis: + rule: "Host(`tdarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: tdarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + unmanic-jarvis: + rule: "Host(`unmanic.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: unmanic-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-unmanic@file + - authelia@docker + + wordpress-jarvis: + rule: "Host(`knot-u.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: wordpress-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-wordpress@file + - authelia@file + +# Arr Services (no SSO for media apps) + + jellyseerr-jarvis: + rule: "Host(`jellyseerr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: jellyseerr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + prowlarr-jarvis: + rule: "Host(`prowlarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: prowlarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + radarr-jarvis: + rule: "Host(`radarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: radarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + sonarr-jarvis: + rule: "Host(`sonarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: sonarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + lidarr-jarvis: + rule: "Host(`lidarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: lidarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + readarr-jarvis: + rule: "Host(`readarr.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: readarr-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + mylar3-jarvis: + rule: "Host(`mylar3.kelinreij.duckdns.org`)" + entryPoints: + - websecure + service: mylar3-jarvis + tls: + certResolver: letsencrypt + middlewares: + - sablier-jarvis-arr@file + - authelia@docker + + services: + backrest-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:9898" + passHostHeader: true + + bitwarden-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8000" + passHostHeader: true + + bookstack-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:6875" + passHostHeader: true + + calibre-web-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8083" + passHostHeader: true + + code-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8079" + passHostHeader: true + + dockge-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:5001" + passHostHeader: true + + dockhand-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:3003" + passHostHeader: true + + dokuwiki-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8087" + passHostHeader: true + + dozzle-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8085" + passHostHeader: true + + duplicati-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8200" + passHostHeader: true + + formio-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:3002" + passHostHeader: true + + gitea-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:3010" + passHostHeader: true + + glances-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:61208" + passHostHeader: true + + homarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:7575" + passHostHeader: true + + homepage-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:3000" + passHostHeader: true + + jellyfin-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8096" + passHostHeader: true + + kopia-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:51515" + passHostHeader: true + + mealie-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:9000" + passHostHeader: true + + mediawiki-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8084" + passHostHeader: true + + motioneye-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8081" + passHostHeader: true + + nextcloud-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8089" + passHostHeader: true + + openkm-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:18080" + passHostHeader: true + + openwebui-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:3004" + passHostHeader: true + + qbittorrent-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8080" + passHostHeader: true + + tdarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8265" + passHostHeader: true + + unmanic-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8888" + passHostHeader: true + + wordpress-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8088" + passHostHeader: true + + # Arr Services + + jellyseerr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:5055" + passHostHeader: true + + prowlarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:9696" + passHostHeader: true + + radarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:7878" + passHostHeader: true + + sonarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8989" + passHostHeader: true + + lidarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8686" + passHostHeader: true + + readarr-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8787" + passHostHeader: true + + mylar3-jarvis: + loadBalancer: + servers: + - url: "http://192.168.4.11:8090" + passHostHeader: true + +``` + +sablier.yml +```yaml +http: + middlewares: + sablier-jarvis-arr: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-arr + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Arr Apps + theme: ghost + show-details-by-default: true + + sablier-jarvis-backrest: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-backrest + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Backrest + theme: ghost + show-details-by-default: true + + sablier-jarvis-bookstack: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-bookstack + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Bookstack + theme: ghost + show-details-by-default: true + + sablier-jarvis-jellyfin: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-jellyfin + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Jellyfin + theme: ghost + show-details-by-default: true + + sablier-jarvis-calibre-web: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-calibre-web + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Calibre Web + theme: ghost + show-details-by-default: true + + sablier-jarvis-code-server: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-code-server + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Code Server + theme: ghost + show-details-by-default: true + + sablier-jarvis-bitwarden: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-bitwarden + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: bitwarden + theme: ghost + show-details-by-default: true + + sablier-jarvis-wordpress: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-wordpress + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: wordpress + theme: ghost + show-details-by-default: true + + sablier-jarvis-nextcloud: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-nextcloud + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: NextCloud + theme: ghost + show-details-by-default: true + + sablier-jarvis-mediawiki: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-mediawiki + sessionDuration: 2m + ignoreUserAgent: curl + dynamic: + displayName: mediawiki + theme: ghost + show-details-by-default: true + + sablier-jarvis-mealie: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-mealie + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Mealie + theme: ghost + show-details-by-default: true + + sablier-jarvis-gitea: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-gitea + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Gitea + theme: ghost + show-details-by-default: true + + sablier-jarvis-formio: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-formio + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: FormIO + theme: ghost + show-details-by-default: true + + sablier-jarvis-dozzle: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-dozzle + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: dozzle + theme: ghost + show-details-by-default: true + + sablier-jarvis-duplicati: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-duplicati + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Duplicati + theme: ghost + show-details-by-default: true + + sablier-jarvis-glances: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-glances + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Glances + theme: ghost + show-details-by-default: true + + sablier-jarvis-homarr: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-homarr + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Homarr + theme: ghost + show-details-by-default: true + + sablier-jarvis-komodo: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-komodo + sessionDuration: 2m + ignoreUserAgent: curl + dynamic: + displayName: Komodo + theme: ghost + show-details-by-default: true + + sablier-jarvis-kopia: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-kopia + sessionDuration: 2m + ignoreUserAgent: curl + dynamic: + displayName: Kopia + theme: ghost + show-details-by-default: true + + sablier-jarvis-openkm: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-openkm + sessionDuration: 2m + ignoreUserAgent: curl + dynamic: + displayName: OpenKM + theme: ghost + show-details-by-default: true + + sablier-jarvis-openwebui: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: openwebui-jarvis + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: OpenWebUI + theme: ghost + show-details-by-default: true + + sablier-jarvis-pulse: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-pulse + sessionDuration: 2m + ignoreUserAgent: curl + dynamic: + displayName: Pulse + theme: ghost + show-details-by-default: true + + sablier-jarvis-tdarr: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-tdarr + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Tdarr + theme: ghost + show-details-by-default: true + + sablier-jarvis-unmanic: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-unmanic + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: Unmanic + theme: ghost + show-details-by-default: true + + sablier-jarvis-dokuwiki: + plugin: + sablier: + sablierUrl: http://sablier-service:10000 + group: jarvis-dokuwiki + sessionDuration: 30m + ignoreUserAgent: curl + dynamic: + displayName: DokuWiki + theme: ghost + show-details-by-default: true + + authelia: + forwardauth: + address: http://authelia:9091/api/verify?rd=https://auth.kelinreij.duckdns.org/ + authResponseHeaders: + - X-Secret + trustForwardHeader: true + + +``` \ No newline at end of file