From 08b184aea74cb9afc814c07038b5f6b93ffc970b Mon Sep 17 00:00:00 2001 From: kelinfoxy <67766943+kelinfoxy@users.noreply.github.com> Date: Sat, 24 Jan 2026 23:11:05 -0500 Subject: [PATCH] Standardize Compose Files --- docker-compose/core/docker-compose.yml | 15 +- docker-compose/dashboards/docker-compose.yml | 3 + .../infrastructure/docker-compose.yml | 19 +- .../media-management/docker-compose.yml | 141 +-------- .../productivity/docker-compose.yml | 217 +------------- .../dokuwiki/lib/plugins/styling/.travis.yml | 13 - .../transcoders/docker-compose.yaml | 126 ++++++++ docker-compose/utilities/docker-compose.yml | 31 +- docker-compose/vpn/docker-compose.yml | 10 +- docker-compose/wikis/docker-compose.yaml | 188 ++++++++++++ docs/docker-guidelines.md | 8 +- docs/quick-reference.md | 17 +- docs/service-docs/calibre-web.md | 2 +- docs/service-docs/dockge.md | 2 +- docs/service-docs/flaresolverr.md | 2 +- docs/service-docs/jellyseerr.md | 2 +- docs/service-docs/lazylibrarian.md | 2 +- docs/service-docs/lidarr.md | 2 +- docs/service-docs/tdarr.md | 2 +- docs/service-docs/unmanic.md | 2 +- docs/services-overview-clean.md | 235 +++++++++++++++ docs/services-overview.md | 274 +++++------------- scripts/ez-homelab.sh | 2 +- 23 files changed, 710 insertions(+), 605 deletions(-) delete mode 100644 docker-compose/productivity/dokuwiki/config/dokuwiki/lib/plugins/styling/.travis.yml create mode 100644 docker-compose/transcoders/docker-compose.yaml create mode 100644 docker-compose/wikis/docker-compose.yaml create mode 100644 docs/services-overview-clean.md diff --git a/docker-compose/core/docker-compose.yml b/docker-compose/core/docker-compose.yml index 114b8ef..fb41a57 100644 --- a/docker-compose/core/docker-compose.yml +++ b/docker-compose/core/docker-compose.yml @@ -7,14 +7,6 @@ # - 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: - urls: - - https://auth.${DOMAIN} - services: duckdns: @@ -134,3 +126,10 @@ services: networks: traefik-network: external: true + +x-dockge: + urls: + - https://auth.${DOMAIN} + - https://{$SERVER_IP}:9091 + - https://traefik.${DOMAIN} + - https://{$SERVER_IP}:8080 \ No newline at end of file diff --git a/docker-compose/dashboards/docker-compose.yml b/docker-compose/dashboards/docker-compose.yml index 357ea47..19bf844 100644 --- a/docker-compose/dashboards/docker-compose.yml +++ b/docker-compose/dashboards/docker-compose.yml @@ -58,6 +58,7 @@ services: # Homarr - Modern dashboard # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity + homarr: image: ghcr.io/ajnart/homarr:latest deploy: @@ -113,7 +114,9 @@ x-dockge: urls: # Proxied URLs (through Traefik) - https://homepage.${DOMAIN} + - https://{$SERVER_IP}:3003 - https://homarr.${DOMAIN} + - https://{$SERVER_IP}:7575 networks: homelab-network: diff --git a/docker-compose/infrastructure/docker-compose.yml b/docker-compose/infrastructure/docker-compose.yml index 80260f8..dff076a 100644 --- a/docker-compose/infrastructure/docker-compose.yml +++ b/docker-compose/infrastructure/docker-compose.yml @@ -1,8 +1,6 @@ # Infrastructure Services # Core services that other services depend on # Place in /opt/stacks/infrastructure/docker-compose.yml -# 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 @@ -11,13 +9,6 @@ # - no: Services with Sablier lazy loading (start on-demand) # - See individual service comments for specific reasoning -# Service Access URLs: -# - Portainer: https://portainer.${DOMAIN} -# - Pi-hole: https://pihole.${DOMAIN} -# - Dozzle: https://dozzle.${DOMAIN} -# - Glances: https://glances.${DOMAIN} -# - Netdata: https://netdata.${DOMAIN} - services: dockerproxy: # Docker socket proxy for security - provides safe Docker API access, must always run @@ -281,18 +272,16 @@ services: - "sablier.group=${SERVER_HOSTNAME}-code-server" - "sablier.start-on-demand=true" -# ========================================== -# DOCKGE URL CONFIGURATION -# ========================================== x-dockge: urls: - # Proxied URLs (through Traefik) - https://pihole.${DOMAIN} + - https://${SERVER_IP}:53 - https://dozzle.${DOMAIN} + - https://${SERVER_IP}:8085 - https://glances.${DOMAIN} + - https://${SERVER_IP}:61208 - https://code.${DOMAIN} - - # Direct IP:Port URLs + - https://${SERVER_IP}:8079 - http://${SERVER_IP}:2375 # Docker Proxy - http://${SERVER_IP}:19999 # Netdata diff --git a/docker-compose/media-management/docker-compose.yml b/docker-compose/media-management/docker-compose.yml index 99da1e3..5af1e7d 100644 --- a/docker-compose/media-management/docker-compose.yml +++ b/docker-compose/media-management/docker-compose.yml @@ -28,7 +28,7 @@ services: - PGID=${PGID} - TZ=${TZ} healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8989/"] + test: ["CMD", "curl", "-f", "http://${SERVER_IP}:8989/"] interval: 30s timeout: 10s retries: 3 @@ -73,7 +73,7 @@ services: - PGID=${PGID} - TZ=${TZ} healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:7878/"] + test: ["CMD", "curl", "-f", "http://${SERVER_IP}:7878/"] interval: 30s timeout: 10s retries: 3 @@ -116,7 +116,7 @@ services: - PGID=${PGID} - TZ=${TZ} healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9696/"] + test: ["CMD", "curl", "-f", "http://${SERVER_IP}:9696/"] interval: 30s timeout: 10s retries: 3 @@ -315,7 +315,7 @@ services: - LOG_LEVEL=info - TZ=${TZ} healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5055/"] + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://${SERVER_IP}:5055/"] interval: 30s timeout: 10s retries: 3 @@ -358,141 +358,24 @@ services: - "sablier.group=${SERVER_HOSTNAME}-arr" - "sablier.start-on-demand=true" - # Tdarr Server - Distributed transcoding server - # Access at: https://tdarr.${DOMAIN} - tdarr-server: - image: ghcr.io/haveagitgat/tdarr:latest - container_name: tdarr-server - restart: no - networks: - - homelab-network - - traefik-network - ports: - - 8265:8265 # Web UI port - - 8266:8266 # Server port - volumes: - - ./tdarr/server:/app/server - - ./tdarr/configs:/app/configs - - ./tdarr/logs:/app/logs - - /mnt/media:/media - - /mnt/tdarr-transcode:/temp # Transcode cache on separate drive - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - serverIP=0.0.0.0 - - serverPort=8266 - - webUIPort=8265 - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Distributed transcoding server" - - "com.centurylinklabs.watchtower.enable=true" - # Traefik reverse proxy (comment/uncomment to disable/enable) - # If Traefik is on a remote server: these labels are NOT USED; - # configure external yml files in /traefik/dynamic folder instead. - - "traefik.enable=true" - - "traefik.http.routers.tdarr.rule=Host(`tdarr.${DOMAIN}`)" - - "traefik.http.routers.tdarr.entrypoints=websecure" - - "traefik.http.routers.tdarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.tdarr.middlewares=authelia@docker" - - "traefik.http.services.tdarr.loadbalancer.server.port=8265" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-tdarr" - - "sablier.start-on-demand=true" - - # Tdarr Node - Transcoding worker - # No web UI - controlled by server - tdarr-node: - image: ghcr.io/haveagitgat/tdarr_node:latest - container_name: tdarr-node - restart: unless-stopped - networks: - - homelab-network - volumes: - - ./tdarr/configs:/app/configs - - ./tdarr/logs:/app/logs - - /mnt/media:/media - - /mnt/tdarr-transcode:/temp - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - nodeID=MainNode - - nodeIP=0.0.0.0 - - nodePort=8267 - - serverIP=tdarr-server - - serverPort=8266 - labels: - - homelab.category=media - - homelab.description=Tdarr transcoding worker node - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-tdarr" - - "sablier.start-on-demand=true" - - # Unmanic - Another transcoding option - # Access at: https://unmanic.${DOMAIN} - unmanic: - image: josh5/unmanic:latest - container_name: unmanic - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8889:8888" - volumes: - - ./unmanic/config:/config - - /mnt/media:/library - - /mnt/unmanic-cache:/tmp/unmanic # Transcode cache on separate drive - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Library optimization and transcoding" - - "com.centurylinklabs.watchtower.enable=true" - # Traefik reverse proxy (comment/uncomment to disable/enable) - # If Traefik is on a remote server: these labels are NOT USED; - # configure external yml files in /traefik/dynamic folder instead. - - "traefik.enable=true" - - "traefik.http.routers.unmanic.rule=Host(`unmanic.${DOMAIN}`)" - - "traefik.http.routers.unmanic.entrypoints=websecure" - - "traefik.http.routers.unmanic.tls.certresolver=letsencrypt" - - "traefik.http.routers.unmanic.middlewares=authelia@docker" - - "traefik.http.services.unmanic.loadbalancer.server.port=8889" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-unmanic" - - "sablier.start-on-demand=true" - x-dockge: urls: - https://sonarr.${DOMAIN} - - http://localhost:8989 + - http://${SERVER_IP}:8989 - https://radarr.${DOMAIN} - - http://localhost:7878 + - http://${SERVER_IP}:7878 - https://prowlarr.${DOMAIN} - - http://localhost:9696 + - http://${SERVER_IP}:9696 - https://readarr.${DOMAIN} - - http://localhost:8787 + - http://${SERVER_IP}:8787 - https://lidarr.${DOMAIN} - - http://localhost:8686 + - http://${SERVER_IP}:8686 - https://lazylibrarian.${DOMAIN} - - http://localhost:5299 + - http://${SERVER_IP}:5299 - https://mylar.${DOMAIN} - - http://localhost:8090 + - http://${SERVER_IP}:8090 - https://jellyseerr.${DOMAIN} - - http://localhost:5055 - - https://tdarr.${DOMAIN} - - http://localhost:8265 - - https://unmanic.${DOMAIN} - - http://localhost:8888 + - http://${SERVER_IP}:5055 networks: homelab-network: diff --git a/docker-compose/productivity/docker-compose.yml b/docker-compose/productivity/docker-compose.yml index 651669c..d417c31 100644 --- a/docker-compose/productivity/docker-compose.yml +++ b/docker-compose/productivity/docker-compose.yml @@ -8,15 +8,6 @@ # - no: Services with Sablier lazy loading (start on-demand) # - See individual service comments for specific reasoning -# Service Access URLs: -# - Nextcloud: https://nextcloud.${DOMAIN} -# - Mealie: https://mealie.${DOMAIN} -# - WordPress: https://blog.${DOMAIN} -# - Gitea: https://git.${DOMAIN} -# - DokuWiki: https://wiki.${DOMAIN} -# - BookStack: https://docs.${DOMAIN} -# - MediaWiki: https://mediawiki.${DOMAIN} - services: # Nextcloud - File sync and collaboration # Access at: https://nextcloud.${DOMAIN} @@ -273,173 +264,6 @@ services: - "homelab.category=productivity" - "homelab.description=Gitea database" - # DokuWiki - Wiki without database - # Access at: https://wiki.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - dokuwiki: - image: lscr.io/linuxserver/dokuwiki:latest - container_name: dokuwiki - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8087:80" - volumes: - - ./dokuwiki/config:/config - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=File-based wiki" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.dokuwiki.rule=Host(`dokuwiki.${DOMAIN}`)" - - "traefik.http.routers.dokuwiki.entrypoints=websecure" - - "traefik.http.routers.dokuwiki.tls.certresolver=letsencrypt" - - "traefik.http.routers.dokuwiki.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.dokuwiki.loadbalancer.server.port=8087" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-dokuwiki" - - "sablier.start-on-demand=true" - - # BookStack - Documentation platform - # Access at: https://docs.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - bookstack: - image: lscr.io/linuxserver/bookstack:latest - container_name: bookstack - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "6875:80" - volumes: - - ./bookstack/config:/config - environment: - - PUID=${PUID} - - PGID=${PGID} - - APP_URL=https://bookstack.${DOMAIN} - - DB_HOST=bookstack-db - - DB_PORT=3306 - - DB_DATABASE=bookstack - - DB_USERNAME=bookstack - - DB_PASSWORD=${BOOKSTACK_DB_PASSWORD} - - APP_KEY=base64:NsYD8+8MAvtBhK8xw9p8pxQDy4x8aOQi/78M3CsseAw= - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - bookstack-db - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=Documentation and wiki platform" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.bookstack.rule=Host(`bookstack.${DOMAIN}`)" - - "traefik.http.routers.bookstack.entrypoints=websecure" - - "traefik.http.routers.bookstack.tls.certresolver=letsencrypt" - - "traefik.http.routers.bookstack.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.bookstack.loadbalancer.server.port=6875" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-bookstack" - - "sablier.start-on-demand=true" - - bookstack-db: - image: mariadb:10.11 - container_name: bookstack-db - restart: no - networks: - - homelab-network - volumes: - - bookstack-db-data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${BOOKSTACK_DB_ROOT_PASSWORD} - - MYSQL_DATABASE=bookstack - - MYSQL_USER=bookstack - - MYSQL_PASSWORD=${BOOKSTACK_DB_PASSWORD} - labels: - - "homelab.category=productivity" - - "homelab.description=BookStack database" - - # MediaWiki - Wiki platform - # Access at: https://mediawiki.${DOMAIN} - mediawiki: - image: mediawiki:latest - container_name: mediawiki - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8086:80" - volumes: - - ./mediawiki/images:/var/www/html/images - - ./mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php - environment: - - MEDIAWIKI_DB_HOST=mediawiki-db - - MEDIAWIKI_DB_NAME=mediawiki - - MEDIAWIKI_DB_USER=mediawiki - - MEDIAWIKI_DB_PASSWORD=${MEDIAWIKI_DB_PASSWORD} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - mediawiki-db - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=MediaWiki platform" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.mediawiki.rule=Host(`mediawiki.${DOMAIN}`)" - - "traefik.http.routers.mediawiki.entrypoints=websecure" - - "traefik.http.routers.mediawiki.tls.certresolver=letsencrypt" - - "traefik.http.routers.mediawiki.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.mediawiki.loadbalancer.server.port=8086" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-mediawiki" - - "sablier.start-on-demand=true" - - mediawiki-db: - image: mariadb:10.11 - container_name: mediawiki-db - restart: no - networks: - - homelab-network - volumes: - - mediawiki-db-data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${MEDIAWIKI_DB_ROOT_PASSWORD} - - MYSQL_DATABASE=mediawiki - - MYSQL_USER=mediawiki - - MYSQL_PASSWORD=${MEDIAWIKI_DB_PASSWORD} - labels: - - "homelab.category=productivity" - - "homelab.description=MediaWiki database" # Jupyter Lab - Interactive computing notebooks # Access at: https://jupyter.${DOMAIN} @@ -487,39 +311,28 @@ services: - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-jupyter" - "sablier.start-on-demand=true" + volumes: nextcloud-db-data: wordpress-db-data: gitea-db-data: - bookstack-db-data: - mediawiki-db-data: - -# ========================================== -# DOCKGE URL CONFIGURATION -# ========================================== -x-dockge: - urls: - # Proxied URLs (through Traefik) - - https://nextcloud.${DOMAIN} - - https://mealie.${DOMAIN} - - https://wordpress.${DOMAIN} - - https://gitea.${DOMAIN} - - https://bookstack.${DOMAIN} - - https://dokuwiki.${DOMAIN} - - https://mediawiki.${DOMAIN} networks: homelab-network: external: true traefik-network: external: true - nextcloud-network: - driver: bridge - wordpress-network: - driver: bridge - gitea-network: - driver: bridge - bookstack-network: - driver: bridge - mediawiki-network: - driver: bridge + +x-dockge: + urls: + # Proxied URLs (through Traefik) + - https://nextcloud.${DOMAIN} + - https://{$SERVER_IP}:8089 + - https://mealie.${DOMAIN} + - https://{$SERVER_IP}:9000 + - https://wordpress.${DOMAIN} + - https://{$SERVER_IP}:8088 + - https://gitea.${DOMAIN} + - https://{$SERVER_IP}:3010 + - https://jupyter.${DOMAIN} + - https://{$SERVER_IP}:8890 diff --git a/docker-compose/productivity/dokuwiki/config/dokuwiki/lib/plugins/styling/.travis.yml b/docker-compose/productivity/dokuwiki/config/dokuwiki/lib/plugins/styling/.travis.yml deleted file mode 100644 index 75ee0b1..0000000 --- a/docker-compose/productivity/dokuwiki/config/dokuwiki/lib/plugins/styling/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Config file for travis-ci.org - -language: php -php: - - "5.5" - - "5.4" - - "5.3" -env: - - DOKUWIKI=master - - DOKUWIKI=stable -before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh -install: sh travis.sh -script: cd _test && phpunit --stderr --group plugin_styling diff --git a/docker-compose/transcoders/docker-compose.yaml b/docker-compose/transcoders/docker-compose.yaml new file mode 100644 index 0000000..d82f889 --- /dev/null +++ b/docker-compose/transcoders/docker-compose.yaml @@ -0,0 +1,126 @@ +services: + # Tdarr Server - Distributed transcoding server + # Access at: https://tdarr.${DOMAIN} + tdarr-server: + image: ghcr.io/haveagitgat/tdarr:latest + container_name: tdarr-server + restart: no + networks: + - homelab-network + - traefik-network + ports: + - 8265:8265 # Web UI port + - 8266:8266 # Server port + volumes: + - ./tdarr/server:/app/server + - ./tdarr/configs:/app/configs + - ./tdarr/logs:/app/logs + - /mnt/media:/media + - /mnt/tdarr-transcode:/temp # Transcode cache on separate drive + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - serverIP=0.0.0.0 + - serverPort=8266 + - webUIPort=8265 + labels: + # TRAEFIK CONFIGURATION + # ========================================== + # Service metadata + - "homelab.category=media" + - "homelab.description=Distributed transcoding server" + - "com.centurylinklabs.watchtower.enable=true" + # Traefik reverse proxy (comment/uncomment to disable/enable) + # If Traefik is on a remote server: these labels are NOT USED; + # configure external yml files in /traefik/dynamic folder instead. + - "traefik.enable=true" + - "traefik.http.routers.tdarr.rule=Host(`tdarr.${DOMAIN}`)" + - "traefik.http.routers.tdarr.entrypoints=websecure" + - "traefik.http.routers.tdarr.tls.certresolver=letsencrypt" + - "traefik.http.routers.tdarr.middlewares=authelia@docker" + - "traefik.http.services.tdarr.loadbalancer.server.port=8265" + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-tdarr" + - "sablier.start-on-demand=true" + + # Tdarr Node - Transcoding worker + # No web UI - controlled by server + tdarr-node: + image: ghcr.io/haveagitgat/tdarr_node:latest + container_name: tdarr-node + restart: unless-stopped + networks: + - homelab-network + volumes: + - ./tdarr/configs:/app/configs + - ./tdarr/logs:/app/logs + - /mnt/media:/media + - /mnt/tdarr-transcode:/temp + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - nodeID=MainNode + - nodeIP=0.0.0.0 + - nodePort=8267 + - serverIP=tdarr-server + - serverPort=8266 + labels: + - homelab.category=media + - homelab.description=Tdarr transcoding worker node + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-tdarr" + - "sablier.start-on-demand=true" + + # Unmanic - Another transcoding option + # Access at: https://unmanic.${DOMAIN} + unmanic: + image: josh5/unmanic:latest + container_name: unmanic + restart: no + networks: + - homelab-network + - traefik-network + ports: + - "8889:8888" + volumes: + - ./unmanic/config:/config + - /mnt/media:/library + - /mnt/unmanic-cache:/tmp/unmanic # Transcode cache on separate drive + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + labels: + # TRAEFIK CONFIGURATION + # ========================================== + # Service metadata + - "homelab.category=media" + - "homelab.description=Library optimization and transcoding" + - "com.centurylinklabs.watchtower.enable=true" + # Traefik reverse proxy (comment/uncomment to disable/enable) + # If Traefik is on a remote server: these labels are NOT USED; + # configure external yml files in /traefik/dynamic folder instead. + - "traefik.enable=true" + - "traefik.http.routers.unmanic.rule=Host(`unmanic.${DOMAIN}`)" + - "traefik.http.routers.unmanic.entrypoints=websecure" + - "traefik.http.routers.unmanic.tls.certresolver=letsencrypt" + - "traefik.http.routers.unmanic.middlewares=authelia@docker" + - "traefik.http.services.unmanic.loadbalancer.server.port=8889" + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-unmanic" + - "sablier.start-on-demand=true" + +networks: + homelab-network: + external: true + traefik-network: + external: true + +x-dockge: + urls: + - https://tdarr.${DOMAIN} + - http://${SERVER_IP}:8265 + - https://unmanic.${DOMAIN} + - http://${SERVER_IP}:8888 \ No newline at end of file diff --git a/docker-compose/utilities/docker-compose.yml b/docker-compose/utilities/docker-compose.yml index 6bc0739..78665ff 100644 --- a/docker-compose/utilities/docker-compose.yml +++ b/docker-compose/utilities/docker-compose.yml @@ -6,18 +6,6 @@ # - no: Services with Sablier lazy loading (start on-demand) # - See individual service comments for specific reasoning -# Service Access URLs: -# - Backrest: https://backrest.${DOMAIN} -# - Duplicati: https://duplicati.${DOMAIN} -# - Form.io: https://forms.${DOMAIN} -# - Vaultwarden (Bitwarden): https://vault.${DOMAIN} - -x-dockge: - urls: - - https://backrest.${DOMAIN} - - https://duplicati.${DOMAIN} - - https://forms.${DOMAIN} - - https://vault.${DOMAIN} services: # Backrest - Backup solution for restic # Access at: https://backrest.${DOMAIN} @@ -65,6 +53,7 @@ services: - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-backrest" - "sablier.start-on-demand=true" + # Duplicati - Backup solution # Access at: https://duplicati.${DOMAIN} duplicati: @@ -109,6 +98,7 @@ services: - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-duplicati" - "sablier.start-on-demand=true" + # Form.io - Form builder # Uncomment and configure if formio/formio image becomes available formio: @@ -118,7 +108,6 @@ services: networks: - homelab-network - traefik-network - ports: - "3002:3001" environment: @@ -153,6 +142,7 @@ services: - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-formio" - "sablier.start-on-demand=true" + formio-mongo: image: mongo:4.4 container_name: formio-mongo @@ -166,6 +156,7 @@ services: # Bitwarden (Vaultwarden) - Password manager # Access at: https://vault.${DOMAIN} # Note: SSO disabled for browser extension and mobile app compatibility + vaultwarden: image: vaultwarden/server:1.30.1 container_name: vaultwarden @@ -216,6 +207,7 @@ services: - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-vaultwarden" - "sablier.start-on-demand=true" + # Authelia Redis - Session storage for Authelia # No web UI - backend service # authelia-redis: @@ -230,12 +222,25 @@ services: # labels: # - homelab.category=utilities # - homelab.description=Session storage for Authelia + volumes: backrest-cache: null formio-mongo-data: null authelia-redis-data: null + networks: homelab-network: external: true traefik-network: external: true + +x-dockge: + urls: + - https://backrest.${DOMAIN} + - https://{$SERVER_IP}:9898 + - https://duplicati.${DOMAIN} + - https://{$SERVER_IP}:8200 + - https://forms.${DOMAIN} + - https://{$SERVER_IP}:3002 + - https://vault.${DOMAIN} + - https://{$SERVER_IP}:8091 \ No newline at end of file diff --git a/docker-compose/vpn/docker-compose.yml b/docker-compose/vpn/docker-compose.yml index 3bd80fb..8cd71a6 100644 --- a/docker-compose/vpn/docker-compose.yml +++ b/docker-compose/vpn/docker-compose.yml @@ -7,9 +7,6 @@ # - no: Services with Sablier lazy loading (start on-demand) # - See individual service comments for specific reasoning -# Service Access URLs: -# - qBittorrent: https://qbit.${DOMAIN} - services: # Gluetun - VPN client (Surfshark) # Routes download clients through VPN for security @@ -91,4 +88,9 @@ networks: homelab-network: external: true traefik-network: - external: true \ No newline at end of file + external: true + +x-dockge: + urls: + - https://qbit.${DOMAIN} + - https://${SERVER_IP}:8081 \ No newline at end of file diff --git a/docker-compose/wikis/docker-compose.yaml b/docker-compose/wikis/docker-compose.yaml new file mode 100644 index 0000000..3d2c432 --- /dev/null +++ b/docker-compose/wikis/docker-compose.yaml @@ -0,0 +1,188 @@ +services: + # DokuWiki - Wiki without database + # Access at: https://wiki.${DOMAIN} + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity + dokuwiki: + image: lscr.io/linuxserver/dokuwiki:latest + container_name: dokuwiki + restart: no + networks: + - homelab-network + - traefik-network + ports: + - "8087:80" + volumes: + - ./dokuwiki/config:/config + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + labels: + # TRAEFIK CONFIGURATION + # Service metadata + - "com.centurylinklabs.watchtower.enable=true" + - "homelab.category=productivity" + - "homelab.description=File-based wiki" + - "traefik.enable=true" + # Router configuration + - "traefik.http.routers.dokuwiki.rule=Host(`dokuwiki.${DOMAIN}`)" + - "traefik.http.routers.dokuwiki.entrypoints=websecure" + - "traefik.http.routers.dokuwiki.tls.certresolver=letsencrypt" + - "traefik.http.routers.dokuwiki.middlewares=authelia@docker" + # Service configuration + - "traefik.http.services.dokuwiki.loadbalancer.server.port=8087" + # Sablier configuration + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-dokuwiki" + - "sablier.start-on-demand=true" + + # BookStack - Documentation platform + # Access at: https://docs.${DOMAIN} + # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity + bookstack: + image: lscr.io/linuxserver/bookstack:latest + container_name: bookstack + restart: no + networks: + - homelab-network + - traefik-network + ports: + - "6875:80" + volumes: + - ./bookstack/config:/config + environment: + - PUID=${PUID} + - PGID=${PGID} + - APP_URL=https://bookstack.${DOMAIN} + - DB_HOST=bookstack-db + - DB_PORT=3306 + - DB_DATABASE=bookstack + - DB_USERNAME=bookstack + - DB_PASSWORD=${BOOKSTACK_DB_PASSWORD} + - APP_KEY=base64:NsYD8+8MAvtBhK8xw9p8pxQDy4x8aOQi/78M3CsseAw= + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + depends_on: + - bookstack-db + labels: + # TRAEFIK CONFIGURATION + # Service metadata + - "com.centurylinklabs.watchtower.enable=true" + - "homelab.category=productivity" + - "homelab.description=Documentation and wiki platform" + - "traefik.enable=true" + # Router configuration + - "traefik.http.routers.bookstack.rule=Host(`bookstack.${DOMAIN}`)" + - "traefik.http.routers.bookstack.entrypoints=websecure" + - "traefik.http.routers.bookstack.tls.certresolver=letsencrypt" + - "traefik.http.routers.bookstack.middlewares=authelia@docker" + # Service configuration + - "traefik.http.services.bookstack.loadbalancer.server.port=6875" + # Sablier configuration + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-bookstack" + - "sablier.start-on-demand=true" + + bookstack-db: + image: mariadb:10.11 + container_name: bookstack-db + restart: no + networks: + - homelab-network + volumes: + - bookstack-db-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${BOOKSTACK_DB_ROOT_PASSWORD} + - MYSQL_DATABASE=bookstack + - MYSQL_USER=bookstack + - MYSQL_PASSWORD=${BOOKSTACK_DB_PASSWORD} + labels: + - "homelab.category=productivity" + - "homelab.description=BookStack database" + + # MediaWiki - Wiki platform + # Access at: https://mediawiki.${DOMAIN} + mediawiki: + image: mediawiki:latest + container_name: mediawiki + restart: no + networks: + - homelab-network + - traefik-network + ports: + - "8086:80" + volumes: + - ./mediawiki/images:/var/www/html/images + - ./mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php + environment: + - MEDIAWIKI_DB_HOST=mediawiki-db + - MEDIAWIKI_DB_NAME=mediawiki + - MEDIAWIKI_DB_USER=mediawiki + - MEDIAWIKI_DB_PASSWORD=${MEDIAWIKI_DB_PASSWORD} + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + depends_on: + - mediawiki-db + labels: + # TRAEFIK CONFIGURATION + # Service metadata + - "com.centurylinklabs.watchtower.enable=true" + - "homelab.category=productivity" + - "homelab.description=MediaWiki platform" + - "traefik.enable=true" + # Router configuration + - "traefik.http.routers.mediawiki.rule=Host(`mediawiki.${DOMAIN}`)" + - "traefik.http.routers.mediawiki.entrypoints=websecure" + - "traefik.http.routers.mediawiki.tls.certresolver=letsencrypt" + - "traefik.http.routers.mediawiki.middlewares=authelia@docker" + # Service configuration + - "traefik.http.services.mediawiki.loadbalancer.server.port=8086" + # Sablier configuration + - "sablier.enable=true" + - "sablier.group=${SERVER_HOSTNAME}-mediawiki" + - "sablier.start-on-demand=true" + + mediawiki-db: + image: mariadb:10.11 + container_name: mediawiki-db + restart: no + networks: + - homelab-network + volumes: + - mediawiki-db-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${MEDIAWIKI_DB_ROOT_PASSWORD} + - MYSQL_DATABASE=mediawiki + - MYSQL_USER=mediawiki + - MYSQL_PASSWORD=${MEDIAWIKI_DB_PASSWORD} + labels: + - "homelab.category=productivity" + - "homelab.description=MediaWiki database" + +volumes: + bookstack-db-data: + mediawiki-db-data: + +networks: + homelab-network: + external: true + traefik-network: + external: true + +x-dockge: + urls: + # Proxied URLs (through Traefik) + - https://bookstack.${DOMAIN} + - https://{$SERVER_IP}:6875 + - https://dokuwiki.${DOMAIN} + - https://{$SERVER_IP}:8087 + - https://mediawiki.${DOMAIN} + - https://{$SERVER_IP}:8086 diff --git a/docs/docker-guidelines.md b/docs/docker-guidelines.md index 7165a3a..a732461 100644 --- a/docs/docker-guidelines.md +++ b/docs/docker-guidelines.md @@ -512,7 +512,7 @@ services: - TZ=${TIMEZONE} ``` -**Add health checks (if applicable):** +**Add health checks (if compatable):** ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] @@ -551,7 +551,7 @@ services: x-dockge: urls: - https://service-name.${DOMAIN} - - http://localhost:8080 + - http://${SERVER_IP}$:8080 volumes: service-data: @@ -560,6 +560,8 @@ volumes: networks: traefik-network: external: true + homelab-network: + external: true ``` If Traefik & Sablier are on a remote server: @@ -658,8 +660,6 @@ services: image: lscr.io/linuxserver/sonarr:4.0.0 container_name: sonarr # Sonarr - TV Show management and automation - # Access at: https://sonarr.yourdomain.duckdns.org (via Traefik) - # Connects to: Prowlarr (indexers), qBittorrent (downloads) # Protected by: Authelia SSO, Sablier lazy loading restart: no ``` diff --git a/docs/quick-reference.md b/docs/quick-reference.md index fd817d8..d4ffad3 100644 --- a/docs/quick-reference.md +++ b/docs/quick-reference.md @@ -11,13 +11,15 @@ Your homelab uses separate stacks for organization: - **`dashboards.yml`** - Dashboard services (Homepage, Homarr) - 2 services **Available in Dockge (deploy as needed):** -- **`media.yml`** - Media services (Plex, Jellyfin, Sonarr, Radarr, Prowlarr, qBittorrent) -- **`media-extended.yml`** - Additional media tools (Readarr, Lidarr, Mylar, Calibre) +- **`media.yml`** - Media services (Jellyfin, Calibre-Web) +- **`media-management.yml`** - Media automation (Sonarr, Radarr, Prowlarr, *arr services) +- **`transcoders.yml`** - Transcoding services (Tdarr, Unmanic) +- **`wikis.yml`** - Wiki platforms (DokuWiki, BookStack, MediaWiki) - **`homeassistant.yml`** - Home automation (Home Assistant, Node-RED, Zigbee2MQTT, ESPHome) -- **`productivity.yml`** - Productivity apps (Nextcloud, Gitea, Bookstack, Outline, Excalidraw) +- **`productivity.yml`** - Productivity apps (Nextcloud, Gitea, Mealie, WordPress) - **`monitoring.yml`** - Monitoring stack (Grafana, Prometheus, Uptime Kuma, Netdata) -- **`utilities.yml`** - Utility services (Duplicati, Code Server, FreshRSS, Wallabag) -- **`alternatives.yml`** - Alternative tools (Portainer, Authentik) +- **`utilities.yml`** - Utility services (Vaultwarden, Backrest, Duplicati, Form.io) +- **`alternatives.yml`** - Alternative tools (Portainer, Authentik, Plex) > All stacks can be modified by the AI to suit your preferences. @@ -205,14 +207,15 @@ docker image prune -a - **9696**: Prowlarr - **8081**: qBittorrent -### Extended Media (media-extended.yml) +### Media Management (media-management.yml) - **8787**: Readarr - **8686**: Lidarr - **5299**: Lazy Librarian - **8090**: Mylar3 -- **8083**: Calibre-Web - **5055**: Jellyseerr - **9697**: FlareSolverr + +### Transcoders (transcoders.yml) - **7889**: Tdarr Server - **8265**: Unmanic diff --git a/docs/service-docs/calibre-web.md b/docs/service-docs/calibre-web.md index adbf546..ce24dba 100644 --- a/docs/service-docs/calibre-web.md +++ b/docs/service-docs/calibre-web.md @@ -14,7 +14,7 @@ **Category:** Ebook Management **Docker Image:** [linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web) -**Default Stack:** `media-extended.yml` +**Default Stack:** `media.yml` **Web UI:** `https://calibre-web.${DOMAIN}` or `http://SERVER_IP:8083` **Default Login:** admin/admin123 **Ports:** 8083 diff --git a/docs/service-docs/dockge.md b/docs/service-docs/dockge.md index ac16a19..4f4be13 100644 --- a/docs/service-docs/dockge.md +++ b/docs/service-docs/dockge.md @@ -98,7 +98,7 @@ Each folder is a "stack" with its compose file and volumes. ├── infrastructure/ # Management and monitoring ├── dashboards/ # Homepage, Homarr ├── media/ # Plex, Sonarr, Radarr, etc. -├── media-extended/ # Additional media services +├── media-management/ # Media automation services ├── homeassistant/ # Home automation ├── productivity/ # Nextcloud, Gitea, etc. ├── utilities/ # Vaultwarden, backups diff --git a/docs/service-docs/flaresolverr.md b/docs/service-docs/flaresolverr.md index d7e5a1e..b22c6f7 100644 --- a/docs/service-docs/flaresolverr.md +++ b/docs/service-docs/flaresolverr.md @@ -16,7 +16,7 @@ **Category:** Proxy Service **Docker Image:** [ghcr.io/flaresolverr/flaresolverr](https://github.com/FlareSolverr/FlareSolverr/pkgs/container/flaresolverr) -**Default Stack:** `media-extended.yml` +**Default Stack:** `media-management.yml` **API Port:** 8191 **Authentication:** None (internal service) **Used By:** Prowlarr, Jackett, NZBHydra2 diff --git a/docs/service-docs/jellyseerr.md b/docs/service-docs/jellyseerr.md index f11151d..835a529 100644 --- a/docs/service-docs/jellyseerr.md +++ b/docs/service-docs/jellyseerr.md @@ -17,7 +17,7 @@ **Category:** Media Request Management **Docker Image:** [fallenbagel/jellyseerr](https://hub.docker.com/r/fallenbagel/jellyseerr) -**Default Stack:** `media-extended.yml` +**Default Stack:** `media-management.yml` **Web UI:** `https://jellyseerr.${DOMAIN}` or `http://SERVER_IP:5055` **Authentication:** Via Jellyfin (SSO) **Ports:** 5055 diff --git a/docs/service-docs/lazylibrarian.md b/docs/service-docs/lazylibrarian.md index 2594395..2ee5a37 100644 --- a/docs/service-docs/lazylibrarian.md +++ b/docs/service-docs/lazylibrarian.md @@ -13,7 +13,7 @@ **Category:** Book Management **Docker Image:** [linuxserver/lazylibrarian](https://hub.docker.com/r/linuxserver/lazylibrarian) -**Default Stack:** `media-extended.yml` +**Default Stack:** `media-management.yml` **Web UI:** `http://SERVER_IP:5299` **Alternative To:** Readarr **Ports:** 5299 diff --git a/docs/service-docs/lidarr.md b/docs/service-docs/lidarr.md index 818bd18..cf084b1 100644 --- a/docs/service-docs/lidarr.md +++ b/docs/service-docs/lidarr.md @@ -17,7 +17,7 @@ **Category:** Media Management & Automation **Docker Image:** [linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr) -**Default Stack:** `media-extended.yml` +**Default Stack:** `media-management.yml` **Web UI:** `https://lidarr.${DOMAIN}` or `http://SERVER_IP:8686` **Authentication:** Optional (configurable) **Ports:** 8686 diff --git a/docs/service-docs/tdarr.md b/docs/service-docs/tdarr.md index ffaf95e..d0174c3 100644 --- a/docs/service-docs/tdarr.md +++ b/docs/service-docs/tdarr.md @@ -17,7 +17,7 @@ **Category:** Media Transcoding **Docker Image:** [ghcr.io/haveagitgat/tdarr](https://github.com/HaveAGitGat/Tdarr/pkgs/container/tdarr) -**Default Stack:** `media-extended.yml` +**Default Stack:** `transcoders.yml` **Web UI:** `https://tdarr.${DOMAIN}` or `http://SERVER_IP:8265` **Server Port:** 8266 **Authentication:** Built-in diff --git a/docs/service-docs/unmanic.md b/docs/service-docs/unmanic.md index ad5cd23..2a72b38 100644 --- a/docs/service-docs/unmanic.md +++ b/docs/service-docs/unmanic.md @@ -16,7 +16,7 @@ **Category:** Media Optimization **Docker Image:** [josh5/unmanic](https://hub.docker.com/r/josh5/unmanic) -**Default Stack:** `media-extended.yml` +**Default Stack:** `transcoders.yml` **Web UI:** `https://unmanic.${DOMAIN}` or `http://SERVER_IP:8888` **Authentication:** Optional **Ports:** 8888 diff --git a/docs/services-overview-clean.md b/docs/services-overview-clean.md new file mode 100644 index 0000000..1dfdcf8 --- /dev/null +++ b/docs/services-overview-clean.md @@ -0,0 +1,235 @@ +# Services Overview + +This document provides a comprehensive overview of all 50+ pre-configured services available in the AI-Homelab repository. + +## Services Overview + +| Stacks (12) | Services (70 + 6db) | SSO | Storage | Access URLs | +|-------|----------|-----|---------|-------------| +| **📦 core.yaml (4)** | **Deploy First** | | | | +| ├─ DuckDNS | Dynamic DNS updater | - | /opt/stacks/core/duckdns | No UI | +| ├─ Traefik | Reverse proxy + SSL | ✓ | /opt/stacks/core/traefik | traefik.${DOMAIN} | +| ├─ Authelia | SSO authentication | - | /opt/stacks/core/authelia | auth.${DOMAIN} | +| └─ Sablier | Lazy loading service | - | /opt/stacks/core/sablier | No UI | +| **🔒 vpn.yaml (2)** | **VPN Services** | | | | +| ├─ Gluetun | VPN (Surfshark) | - | /opt/stacks/vpn/gluetun | No UI | +| └─ qBittorrent | Torrent (via VPN) | ✓ | /mnt/downloads | qbit.${DOMAIN} | +| **🔧 infrastructure.yaml** (6)** | | | | | +| ├─ Pi-hole | DNS + Ad blocking | ✓ | /opt/stacks/infrastructure | pihole.${DOMAIN} | +| ├─ Watchtower | Auto container updates | - | /opt/stacks/infrastructure | No UI | +| ├─ Dozzle | Docker log viewer | ✓ | /opt/stacks/infrastructure | dozzle.${DOMAIN} | +| ├─ Glances | System monitoring | ✓ | /opt/stacks/infrastructure | glances.${DOMAIN} | +| ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/infrastructure | code.${DOMAIN} | +| └─ Docker Proxy | Secure socket access | - | /opt/stacks/infrastructure | No UI | +| **📊 dashboards.yaml** (2) | | | | | +| ├─ Homepage | App dashboard (AI cfg) | ✓ | /opt/stacks/dashboards | home.${DOMAIN} | +| └─ Homarr | Modern dashboard | ✓ | /opt/stacks/dashboards | homarr.${DOMAIN} | +| **🎬 media.yaml** (2) | | | | | +| ├─ Jellyfin | Media server (OSS) | ✗ | /mnt/media, /mnt/transcode | jellyfin.${DOMAIN} | +| └─ Calibre-Web | Ebook reader | ✓ | /opt/stacks/media, /mnt/media | calibre.${DOMAIN} | +| **📺 media-management.yaml** (9) | | | | | +| ├─ Sonarr | TV automation | ✓ | /opt/stacks/media-management, /mnt/media | sonarr.${DOMAIN} | +| ├─ Radarr | Movie automation | ✓ | /opt/stacks/media-management, /mnt/media | radarr.${DOMAIN} | +| ├─ Prowlarr | Indexer manager | ✓ | /opt/stacks/media-management | prowlarr.${DOMAIN} | +| ├─ Readarr | Ebooks/Audiobooks | ✓ | /opt/stacks/media-management, /mnt/media | readarr.${DOMAIN} | +| ├─ Lidarr | Music manager | ✓ | /opt/stacks/media-management, /mnt/media | lidarr.${DOMAIN} | +| ├─ Lazy Librarian | Book automation | ✓ | /opt/stacks/media-management, /mnt/media | lazylibrarian.${DOMAIN} | +| ├─ Mylar3 | Comic manager | ✓ | /opt/stacks/media-management, /mnt/media | mylar.${DOMAIN} | +| ├─ Jellyseerr | Media requests | ✓ | /opt/stacks/media-management | jellyseerr.${DOMAIN} | +| └─ FlareSolverr | Cloudflare bypass | - | /opt/stacks/media-management | No UI | +| **🔄 transcoders.yaml** (3) | | | | | +| ├─ Tdarr Server | Transcoding server | ✓ | /opt/stacks/transcoders, /mnt/transcode | tdarr.${DOMAIN} | +| ├─ Tdarr Node | Transcoding worker | - | /mnt/transcode-cache | No UI | +| └─ Unmanic | Library optimizer | ✓ | /opt/stacks/transcoders, /mnt/transcode | unmanic.${DOMAIN} | +| **📖 wikis.yaml** (4) | | | | | +| ├─ DokuWiki | File-based wiki | ✓ | /opt/stacks/wikis | dokuwiki.${DOMAIN} | +| ├─ BookStack | Documentation | ✓ | /opt/stacks/wikis | docs.${DOMAIN} | +| │ └─ bookstack-db | MariaDB | - | /opt/stacks/wikis | No UI | +| └─ MediaWiki | Wiki platform | ✓ | /opt/stacks/wikis | mediawiki.${DOMAIN} | +| **🏠 homeassistant.yaml** (6) | | | | | +| ├─ Home Assistant | HA platform | ✗ | /opt/stacks/homeassistant | ha.${DOMAIN} | +| ├─ ESPHome | ESP firmware mgr | ✓ | /opt/stacks/homeassistant | esphome.${DOMAIN} | +| ├─ TasmoAdmin | Tasmota device mgr | ✓ | /opt/stacks/homeassistant | tasmoadmin.${DOMAIN} | +| ├─ Node-RED | Automation flows | ✓ | /opt/stacks/homeassistant | nodered.${DOMAIN} | +| ├─ Mosquitto | MQTT broker | - | /opt/stacks/homeassistant | Ports 1883, 9001 | +| └─ Zigbee2MQTT | Zigbee bridge | ✓ | /opt/stacks/homeassistant | zigbee2mqtt.${DOMAIN} | +| **💼 productivity.yaml** (8 + 6 DBs) | | | | | +| ├─ Nextcloud | File sync platform | ✓ | /opt/stacks/productivity, /mnt/nextcloud | nextcloud.${DOMAIN} | +| │ └─ nextcloud-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Mealie | Recipe manager | ✗ | /opt/stacks/productivity | mealie.${DOMAIN} | +| ├─ WordPress | Blog platform | ✗ | /opt/stacks/productivity | blog.${DOMAIN} | +| │ └─ wordpress-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Gitea | Git service | ✓ | /opt/stacks/productivity, /mnt/git | git.${DOMAIN} | +| │ └─ gitea-db | PostgreSQL | - | /opt/stacks/productivity | No UI | +| └─ Jupyter Lab | Notebooks | ✓ | /opt/stacks/productivity | jupyter.${DOMAIN} | +| **🛠️ utilities.yaml** (5) | | | | | +| ├─ Vaultwarden | Password manager | ✗ | /opt/stacks/utilities | bitwarden.${DOMAIN} | +| ├─ Backrest | Backup (restic) | ✓ | /opt/stacks/utilities, /mnt/backups | backrest.${DOMAIN} | +| ├─ Duplicati | Encrypted backups | ✓ | /opt/stacks/utilities, /mnt/backups | duplicati.${DOMAIN} | +| ├─ Form.io | Form builder | ✓ | /opt/stacks/utilities | forms.${DOMAIN} | +| │ └─ formio-mongo | MongoDB | - | /opt/stacks/utilities | No UI | +| └─ Authelia-Redis | Session storage | - | /opt/stacks/utilities | No UI | +| **📈 monitoring.yaml** (8) | | | | | +| ├─ Prometheus | Metrics collection | ✓ | /opt/stacks/monitoring | prometheus.${DOMAIN} | +| ├─ Grafana | Visualization | ✓ | /opt/stacks/monitoring | grafana.${DOMAIN} | +| ├─ Loki | Log aggregation | - | /opt/stacks/monitoring | Via Grafana | +| ├─ Promtail | Log shipper | - | /opt/stacks/monitoring | No UI | +| ├─ Node Exporter | Host metrics | - | /opt/stacks/monitoring | No UI | +| ├─ cAdvisor | Container metrics | - | /opt/stacks/monitoring | Internal :8080 | +| └─ Uptime Kuma | Uptime monitoring | ✓ | /opt/stacks/monitoring | status.${DOMAIN} | +| **🔧 alternatives.yaml** (6) | | | | | +| ├─ Dockge | Stack manager (PRIMARY) | ✓ | /opt/stacks/alternatives | dockge.${DOMAIN} | +| ├─ Portainer | Container management | ✓ | /opt/stacks/alternatives | portainer.${DOMAIN} | +| ├─ Authentik Server | SSO with web UI | ✓ | /opt/stacks/alternatives | authentik.${DOMAIN} | +| │ ├─ authentik-worker | Background tasks | - | /opt/stacks/alternatives | No UI | +| │ ├─ authentik-db | PostgreSQL | - | /opt/stacks/alternatives | No UI | +| │ └─ authentik-redis | Cache/messaging | - | /opt/stacks/alternatives | No UI | +| └─ Plex | Media server | ✗ | /mnt/media, /mnt/transcode | plex.${DOMAIN} | +| **🏠 homeassistant.yaml** (7) | | | | | +| ├─ Home Assistant | HA platform | ✗ | /opt/stacks/homeassistant | ha.${DOMAIN} | +| ├─ ESPHome | ESP firmware mgr | ✓ | /opt/stacks/homeassistant | esphome.${DOMAIN} | +| ├─ TasmoAdmin | Tasmota device mgr | ✓ | /opt/stacks/homeassistant | tasmoadmin.${DOMAIN} | +| ├─ Node-RED | Automation flows | ✓ | /opt/stacks/homeassistant | nodered.${DOMAIN} | +| ├─ Mosquitto | MQTT broker | - | /opt/stacks/homeassistant | Ports 1883, 9001 | +| ├─ Zigbee2MQTT | Zigbee bridge | ✓ | /opt/stacks/homeassistant | zigbee2mqtt.${DOMAIN} | +| └─ MotionEye | Video surveillance | ✓ | /opt/stacks/homeassistant, /mnt/surveillance | motioneye.${DOMAIN} | +| **💼 productivity.yaml** (8 + 6 DBs) | | | | | +| ├─ Nextcloud | File sync platform | ✓ | /opt/stacks/productivity, /mnt/nextcloud | nextcloud.${DOMAIN} | +| │ └─ nextcloud-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Mealie | Recipe manager | ✗ | /opt/stacks/productivity | mealie.${DOMAIN} | +| ├─ WordPress | Blog platform | ✗ | /opt/stacks/productivity | blog.${DOMAIN} | +| │ └─ wordpress-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Gitea | Git service | ✓ | /opt/stacks/productivity, /mnt/git | git.${DOMAIN} | +| │ └─ gitea-db | PostgreSQL | - | /opt/stacks/productivity | No UI | +| ├─ DokuWiki | File-based wiki | ✓ | /opt/stacks/productivity | wiki.${DOMAIN} | +| ├─ BookStack | Documentation | ✓ | /opt/stacks/productivity | docs.${DOMAIN} | +| │ └─ bookstack-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ MediaWiki | Wiki platform | ✓ | /opt/stacks/productivity | mediawiki.${DOMAIN} | +| │ └─ mediawiki-db | MariaDB | - | /opt/stacks/productivity | No UI | +| └─ Form.io | Form builder | ✓ | /opt/stacks/productivity | forms.${DOMAIN} | +| └─ formio-mongo | MongoDB | - | /opt/stacks/productivity | No UI | +| **🛠️ utilities.yaml** (7) | | | | | +| ├─ Vaultwarden | Password manager | ✗ | /opt/stacks/utilities | bitwarden.${DOMAIN} | +| ├─ Backrest | Backup (restic) | ✓ | /opt/stacks/utilities, /mnt/backups | backrest.${DOMAIN} | +| ├─ Duplicati | Encrypted backups | ✓ | /opt/stacks/utilities, /mnt/backups | duplicati.${DOMAIN} | +| ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/utilities | code.${DOMAIN} | +| ├─ Form.io | Form platform | ✓ | /opt/stacks/utilities | forms.${DOMAIN} | +| │ └─ formio-mongo | MongoDB | - | /opt/stacks/utilities | No UI | +| └─ Authelia-Redis | Session storage | - | /opt/stacks/utilities | No UI | +| **📈 monitoring.yaml** (8) | | | | | +| ├─ Prometheus | Metrics collection | ✓ | /opt/stacks/monitoring | prometheus.${DOMAIN} | +| ├─ Grafana | Visualization | ✓ | /opt/stacks/monitoring | grafana.${DOMAIN} | +| ├─ Loki | Log aggregation | - | /opt/stacks/monitoring | Via Grafana | +| ├─ Promtail | Log shipper | - | /opt/stacks/monitoring | No UI | +| ├─ Node Exporter | Host metrics | - | /opt/stacks/monitoring | No UI | +| ├─ cAdvisor | Container metrics | - | /opt/stacks/monitoring | Internal :8080 | +| └─ Uptime Kuma | Uptime monitoring | ✓ | /opt/stacks/monitoring | status.${DOMAIN} | +| **👨‍💻 development.yaml** (6) | | | | | +| ├─ GitLab CE | Git + CI/CD | ✓ | /opt/stacks/development, /mnt/git | gitlab.${DOMAIN} | +| ├─ PostgreSQL | SQL database | - | /opt/stacks/development | Port 5432 | +| ├─ Redis | In-memory store | - | /opt/stacks/development | Port 6379 | +| ├─ pgAdmin | PostgreSQL UI | ✓ | /opt/stacks/development | pgadmin.${DOMAIN} | +| ├─ Jupyter Lab | Notebooks | ✓ | /opt/stacks/development | jupyter.${DOMAIN} | +| └─ Code Server | VS Code | ✓ | /opt/stacks/development | code.${DOMAIN} | + +**Legend:** ✓ = Protected by SSO | ✗ = Bypasses SSO | - = No web UI + +## Quick Deployment Order + +1. **Create Networks** (one-time setup) + ```bash + docker network create traefik-network + docker network create homelab-network + docker network create dockerproxy-network + ``` + +2. **Deploy Core Stack** (required first) + ```bash + cd /opt/stacks/core/ + docker compose up -d + ``` + +3. **Deploy Infrastructure** + ```bash + cd /opt/stacks/infrastructure/ + docker compose up -d + ``` + +4. **Deploy Dashboards** + ```bash + cd /opt/stacks/dashboards/ + docker compose up -d + ``` + +5. **Deploy Additional Stacks** (as needed) + - Media: `/opt/stacks/media/` + - Media Management: `/opt/stacks/media-management/` + - Transcoders: `/opt/stacks/transcoders/` + - Wikis: `/opt/stacks/wikis/` + - Home Automation: `/opt/stacks/homeassistant/` + - Productivity: `/opt/stacks/productivity/` + - Utilities: `/opt/stacks/utilities/` + - Monitoring: `/opt/stacks/monitoring/` + - Alternatives: `/opt/stacks/alternatives/` + +## Toggling SSO (Authelia) On/Off + +You can easily enable or disable SSO protection for any service by modifying its Traefik labels in the docker-compose.yml file. + +### To Enable SSO on a Service + +Add the Authelia middleware to the service's Traefik labels: + +```yaml +labels: + - "traefik.enable=true" + - "traefik.http.routers.servicename.rule=Host(`servicename.${DOMAIN}`)" + - "traefik.http.routers.servicename.entrypoints=websecure" + - "traefik.http.routers.servicename.tls.certresolver=letsencrypt" + - "traefik.http.routers.servicename.middlewares=authelia@docker" # ← Add this line + - "traefik.http.services.servicename.loadbalancer.server.port=8080" +``` + +### To Disable SSO on a Service + +Comment out (don't remove) the middleware line: + +```yaml +labels: + - "traefik.enable=true" + - "traefik.http.routers.servicename.rule=Host(`servicename.${DOMAIN}`)" + - "traefik.http.routers.servicename.entrypoints=websecure" + - "traefik.http.routers.servicename.tls.certresolver=letsencrypt" + # - "traefik.http.routers.servicename.middlewares=authelia@docker" # ← Commented out (not removed) + - "traefik.http.services.servicename.loadbalancer.server.port=8080" +``` + +After making changes, redeploy the service: + +```bash +# From inside the stack directory +cd /opt/stacks/stack-name/ +docker compose up -d + +# Or from anywhere, using the full path +docker compose -f /opt/stacks/stack-name/docker-compose.yml up -d +``` + +**Stopping a Service:** + +```bash +# From inside the stack directory +cd /opt/stacks/stack-name/ +docker compose down + +# Or from anywhere, using the full path +docker compose -f /opt/stacks/stack-name/docker-compose.yml down +``` + +**Use Cases for Development/Production:** +- **Security First**: All services start with SSO enabled by default for maximum security +- **Development**: Keep SSO enabled to protect services during testing +- **Production**: Disable SSO only for services needing direct app/API access (Plex, Jellyfin) +- **Gradual Exposure**: Comment out SSO only when ready to expose a service +- **Quick Toggle**: AI assistant can modify these labels automatically when you ask + diff --git a/docs/services-overview.md b/docs/services-overview.md index f923f27..939511f 100644 --- a/docs/services-overview.md +++ b/docs/services-overview.md @@ -4,47 +4,24 @@ This document provides a comprehensive overview of all 50+ pre-configured servic ## Services Overview -| Stacks (10) | Services (70 + 6db) | SSO | Storage | Access URLs | +| Stacks (12) | Services (70 + 6db) | SSO | Storage | Access URLs | |-------|----------|-----|---------|-------------| -| **📦 core.yaml (3)** | **Deploy First** | | | | +| **� alternatives.yaml** (6 + 3 DBs) | | | | | +| ├─ Dockge | Stack manager (PRIMARY) | ✓ | /opt/stacks/alternatives | dockge.${DOMAIN} | +| ├─ Portainer | Container management | ✓ | /opt/stacks/alternatives | portainer.${DOMAIN} | +| ├─ Authentik Server | SSO with web UI | ✓ | /opt/stacks/alternatives | authentik.${DOMAIN} | +| │ ├─ authentik-worker | Background tasks | - | /opt/stacks/alternatives | No UI | +| │ ├─ authentik-db | PostgreSQL | - | /opt/stacks/alternatives | No UI | +| │ └─ authentik-redis | Cache/messaging | - | /opt/stacks/alternatives | No UI | +| └─ Plex | Media server | ✗ | /mnt/media, /mnt/transcode | plex.${DOMAIN} | +| **📦 core.yaml (4)** | **Deploy First** | | | | | ├─ DuckDNS | Dynamic DNS updater | - | /opt/stacks/core/duckdns | No UI | | ├─ Traefik | Reverse proxy + SSL | ✓ | /opt/stacks/core/traefik | traefik.${DOMAIN} | -| └─ Authelia | SSO authentication | - | /opt/stacks/core/authelia | auth.${DOMAIN} | -| **🔒 vpn.yaml (2)** | **VPN Services** | | | | -| ├─ Gluetun | VPN (Surfshark) | - | /opt/stacks/vpn/gluetun | No UI | -| └─ qBittorrent | Torrent (via VPN) | ✓ | /mnt/downloads | qbit.${DOMAIN} | -| **🔧 infrastructure.yaml** (12) | | | | | -| ├─ Dockge | Stack manager (PRIMARY) | ✓ | /opt/stacks/infrastructure | dockge.${DOMAIN} | -| ├─ Portainer | Container management | ✓ | /opt/stacks/infrastructure | portainer.${DOMAIN} | -| ├─ Authentik Server | SSO with web UI | ✓ | /opt/stacks/authentik | authentik.${DOMAIN} | -| │ ├─ authentik-worker | Background tasks | - | /opt/stacks/authentik | No UI | -| │ ├─ authentik-db | PostgreSQL | - | /opt/stacks/authentik | No UI | -| │ └─ authentik-redis | Cache/messaging | - | /opt/stacks/authentik | No UI | -| ├─ Pi-hole | DNS + Ad blocking | ✓ | /opt/stacks/infrastructure | pihole.${DOMAIN} | -| ├─ Watchtower | Auto container updates | - | /opt/stacks/infrastructure | No UI | -| ├─ Dozzle | Docker log viewer | ✓ | /opt/stacks/infrastructure | dozzle.${DOMAIN} | -| ├─ Glances | System monitoring | ✓ | /opt/stacks/infrastructure | glances.${DOMAIN} | -| └─ Docker Proxy | Secure socket access | - | /opt/stacks/infrastructure | No UI | +| ├─ Authelia | SSO authentication | - | /opt/stacks/core/authelia | auth.${DOMAIN} | +| └─ Sablier | Lazy loading service | - | /opt/stacks/core/sablier | No UI | | **📊 dashboards.yaml** (2) | | | | | | ├─ Homepage | App dashboard (AI cfg) | ✓ | /opt/stacks/dashboards | home.${DOMAIN} | | └─ Homarr | Modern dashboard | ✓ | /opt/stacks/dashboards | homarr.${DOMAIN} | -| **🎬 media** (6) | | | | | -| ├─ Plex | Media server | ✗ | /mnt/media, /mnt/transcode | plex.${DOMAIN} | -| ├─ Jellyfin | Media server (OSS) | ✗ | /mnt/media, /mnt/transcode | jellyfin.${DOMAIN} | -| ├─ Sonarr | TV automation | ✓ | /opt/stacks/media, /mnt/media | sonarr.${DOMAIN} | -| ├─ Radarr | Movie automation | ✓ | /opt/stacks/media, /mnt/media | radarr.${DOMAIN} | -| └─ Prowlarr | Indexer manager | ✓ | /opt/stacks/media | prowlarr.${DOMAIN} | -| **📚 media-extended.yaml** (10) | | | | | -| ├─ Readarr | Ebooks/Audiobooks | ✓ | /opt/stacks/media-ext, /mnt/media | readarr.${DOMAIN} | -| ├─ Lidarr | Music manager | ✓ | /opt/stacks/media-ext, /mnt/media | lidarr.${DOMAIN} | -| ├─ Lazy Librarian | Book automation | ✓ | /opt/stacks/media-ext, /mnt/media | lazylibrarian.${DOMAIN} | -| ├─ Mylar3 | Comic manager | ✓ | /opt/stacks/media-ext, /mnt/media | mylar.${DOMAIN} | -| ├─ Calibre-Web | Ebook reader | ✓ | /opt/stacks/media-ext, /mnt/media | calibre.${DOMAIN} | -| ├─ Jellyseerr | Media requests | ✓ | /opt/stacks/media-ext | jellyseerr.${DOMAIN} | -| ├─ FlareSolverr | Cloudflare bypass | - | /opt/stacks/media-ext | No UI | -| ├─ Tdarr Server | Transcoding server | ✓ | /opt/stacks/media-ext, /mnt/transcode | tdarr.${DOMAIN} | -| ├─ Tdarr Node | Transcoding worker | - | /mnt/transcode-cache | No UI | -| └─ Unmanic | Library optimizer | ✓ | /opt/stacks/media-ext, /mnt/transcode | unmanic.${DOMAIN} | | **🏠 homeassistant.yaml** (7) | | | | | | ├─ Home Assistant | HA platform | ✗ | /opt/stacks/homeassistant | ha.${DOMAIN} | | ├─ ESPHome | ESP firmware mgr | ✓ | /opt/stacks/homeassistant | esphome.${DOMAIN} | @@ -53,29 +30,26 @@ This document provides a comprehensive overview of all 50+ pre-configured servic | ├─ Mosquitto | MQTT broker | - | /opt/stacks/homeassistant | Ports 1883, 9001 | | ├─ Zigbee2MQTT | Zigbee bridge | ✓ | /opt/stacks/homeassistant | zigbee2mqtt.${DOMAIN} | | └─ MotionEye | Video surveillance | ✓ | /opt/stacks/homeassistant, /mnt/surveillance | motioneye.${DOMAIN} | -| **💼 productivity.yaml** (8 + 6 DBs) | | | | | -| ├─ Nextcloud | File sync platform | ✓ | /opt/stacks/productivity, /mnt/nextcloud | nextcloud.${DOMAIN} | -| │ └─ nextcloud-db | MariaDB | - | /opt/stacks/productivity | No UI | -| ├─ Mealie | Recipe manager | ✗ | /opt/stacks/productivity | mealie.${DOMAIN} | -| ├─ WordPress | Blog platform | ✗ | /opt/stacks/productivity | blog.${DOMAIN} | -| │ └─ wordpress-db | MariaDB | - | /opt/stacks/productivity | No UI | -| ├─ Gitea | Git service | ✓ | /opt/stacks/productivity, /mnt/git | git.${DOMAIN} | -| │ └─ gitea-db | PostgreSQL | - | /opt/stacks/productivity | No UI | -| ├─ DokuWiki | File-based wiki | ✓ | /opt/stacks/productivity | wiki.${DOMAIN} | -| ├─ BookStack | Documentation | ✓ | /opt/stacks/productivity | docs.${DOMAIN} | -| │ └─ bookstack-db | MariaDB | - | /opt/stacks/productivity | No UI | -| ├─ MediaWiki | Wiki platform | ✓ | /opt/stacks/productivity | mediawiki.${DOMAIN} | -| │ └─ mediawiki-db | MariaDB | - | /opt/stacks/productivity | No UI | -| └─ Form.io | Form builder | ✓ | /opt/stacks/productivity | forms.${DOMAIN} | -| └─ formio-mongo | MongoDB | - | /opt/stacks/productivity | No UI | -| **🛠️ utilities.yaml** (7) | | | | | -| ├─ Vaultwarden | Password manager | ✗ | /opt/stacks/utilities | bitwarden.${DOMAIN} | -| ├─ Backrest | Backup (restic) | ✓ | /opt/stacks/utilities, /mnt/backups | backrest.${DOMAIN} | -| ├─ Duplicati | Encrypted backups | ✓ | /opt/stacks/utilities, /mnt/backups | duplicati.${DOMAIN} | -| ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/utilities | code.${DOMAIN} | -| ├─ Form.io | Form platform | ✓ | /opt/stacks/utilities | forms.${DOMAIN} | -| │ └─ formio-mongo | MongoDB | - | /opt/stacks/utilities | No UI | -| └─ Authelia-Redis | Session storage | - | /opt/stacks/utilities | No UI | +| **🔧 infrastructure.yaml** (6)** | | | | | +| ├─ Pi-hole | DNS + Ad blocking | ✓ | /opt/stacks/infrastructure | pihole.${DOMAIN} | +| ├─ Watchtower | Auto container updates | - | /opt/stacks/infrastructure | No UI | +| ├─ Dozzle | Docker log viewer | ✓ | /opt/stacks/infrastructure | dozzle.${DOMAIN} | +| ├─ Glances | System monitoring | ✓ | /opt/stacks/infrastructure | glances.${DOMAIN} | +| ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/infrastructure | code.${DOMAIN} | +| └─ Docker Proxy | Secure socket access | - | /opt/stacks/infrastructure | No UI | +| **📺 media-management.yaml** (9) | | | | | +| ├─ Sonarr | TV automation | ✓ | /opt/stacks/media-management, /mnt/media | sonarr.${DOMAIN} | +| ├─ Radarr | Movie automation | ✓ | /opt/stacks/media-management, /mnt/media | radarr.${DOMAIN} | +| ├─ Prowlarr | Indexer manager | ✓ | /opt/stacks/media-management | prowlarr.${DOMAIN} | +| ├─ Readarr | Ebooks/Audiobooks | ✓ | /opt/stacks/media-management, /mnt/media | readarr.${DOMAIN} | +| ├─ Lidarr | Music manager | ✓ | /opt/stacks/media-management, /mnt/media | lidarr.${DOMAIN} | +| ├─ Lazy Librarian | Book automation | ✓ | /opt/stacks/media-management, /mnt/media | lazylibrarian.${DOMAIN} | +| ├─ Mylar3 | Comic manager | ✓ | /opt/stacks/media-management, /mnt/media | mylar.${DOMAIN} | +| ├─ Jellyseerr | Media requests | ✓ | /opt/stacks/media-management | jellyseerr.${DOMAIN} | +| └─ FlareSolverr | Cloudflare bypass | - | /opt/stacks/media-management | No UI | +| **🎬 media.yaml** (2) | | | | | +| ├─ Jellyfin | Media server (OSS) | ✗ | /mnt/media, /mnt/transcode | jellyfin.${DOMAIN} | +| └─ Calibre-Web | Ebook reader | ✓ | /opt/stacks/media, /mnt/media | calibre.${DOMAIN} | | **📈 monitoring.yaml** (8) | | | | | | ├─ Prometheus | Metrics collection | ✓ | /opt/stacks/monitoring | prometheus.${DOMAIN} | | ├─ Grafana | Visualization | ✓ | /opt/stacks/monitoring | grafana.${DOMAIN} | @@ -84,13 +58,35 @@ This document provides a comprehensive overview of all 50+ pre-configured servic | ├─ Node Exporter | Host metrics | - | /opt/stacks/monitoring | No UI | | ├─ cAdvisor | Container metrics | - | /opt/stacks/monitoring | Internal :8080 | | └─ Uptime Kuma | Uptime monitoring | ✓ | /opt/stacks/monitoring | status.${DOMAIN} | -| **👨‍💻 development.yaml** (6) | | | | | -| ├─ GitLab CE | Git + CI/CD | ✓ | /opt/stacks/development, /mnt/git | gitlab.${DOMAIN} | -| ├─ PostgreSQL | SQL database | - | /opt/stacks/development | Port 5432 | -| ├─ Redis | In-memory store | - | /opt/stacks/development | Port 6379 | -| ├─ pgAdmin | PostgreSQL UI | ✓ | /opt/stacks/development | pgadmin.${DOMAIN} | -| ├─ Jupyter Lab | Notebooks | ✓ | /opt/stacks/development | jupyter.${DOMAIN} | -| └─ Code Server | VS Code | ✓ | /opt/stacks/development | code.${DOMAIN} | +| **💼 productivity.yaml** (5 + 4 DBs) | | | | | +| ├─ Nextcloud | File sync platform | ✓ | /opt/stacks/productivity, /mnt/nextcloud | nextcloud.${DOMAIN} | +| │ └─ nextcloud-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Mealie | Recipe manager | ✗ | /opt/stacks/productivity | mealie.${DOMAIN} | +| ├─ WordPress | Blog platform | ✗ | /opt/stacks/productivity | blog.${DOMAIN} | +| │ └─ wordpress-db | MariaDB | - | /opt/stacks/productivity | No UI | +| ├─ Gitea | Git service | ✓ | /opt/stacks/productivity, /mnt/git | git.${DOMAIN} | +| │ └─ gitea-db | PostgreSQL | - | /opt/stacks/productivity | No UI | +| └─ Jupyter Lab | Notebooks | ✓ | /opt/stacks/productivity | jupyter.${DOMAIN} | +| **🔄 transcoders.yaml** (3) | | | | | +| ├─ Tdarr Server | Transcoding server | ✓ | /opt/stacks/transcoders, /mnt/transcode | tdarr.${DOMAIN} | +| ├─ Tdarr Node | Transcoding worker | - | /mnt/transcode-cache | No UI | +| └─ Unmanic | Library optimizer | ✓ | /opt/stacks/transcoders, /mnt/transcode | unmanic.${DOMAIN} | +| **🛠️ utilities.yaml** (7) | | | | | +| ├─ Vaultwarden | Password manager | ✗ | /opt/stacks/utilities | bitwarden.${DOMAIN} | +| ├─ Backrest | Backup (restic) | ✓ | /opt/stacks/utilities, /mnt/backups | backrest.${DOMAIN} | +| ├─ Duplicati | Encrypted backups | ✓ | /opt/stacks/utilities, /mnt/backups | duplicati.${DOMAIN} | +| ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/utilities | code.${DOMAIN} | +| ├─ Form.io | Form platform | ✓ | /opt/stacks/utilities | forms.${DOMAIN} | +| │ └─ formio-mongo | MongoDB | - | /opt/stacks/utilities | No UI | +| └─ Authelia-Redis | Session storage | - | /opt/stacks/utilities | No UI | +| **🔒 vpn.yaml (2)** | **VPN Services** | | | | +| ├─ Gluetun | VPN (Surfshark) | - | /opt/stacks/vpn/gluetun | No UI | +| └─ qBittorrent | Torrent (via VPN) | ✓ | /mnt/downloads | qbit.${DOMAIN} | +| **📖 wikis.yaml** (4) | | | | | +| ├─ DokuWiki | File-based wiki | ✓ | /opt/stacks/wikis | dokuwiki.${DOMAIN} | +| ├─ BookStack | Documentation | ✓ | /opt/stacks/wikis | docs.${DOMAIN} | +| │ └─ bookstack-db | MariaDB | - | /opt/stacks/wikis | No UI | +| └─ MediaWiki | Wiki platform | ✓ | /opt/stacks/wikis | mediawiki.${DOMAIN} | **Legend:** ✓ = Protected by SSO | ✗ = Bypasses SSO | - = No web UI @@ -122,13 +118,19 @@ This document provides a comprehensive overview of all 50+ pre-configured servic ``` 5. **Deploy Additional Stacks** (as needed) - - Media: `/opt/stacks/media/` - - Extended Media: `/opt/stacks/media-extended/` + - Alternatives: `/opt/stacks/alternatives/` + - Core: `/opt/stacks/core/` (deploy first) + - Dashboards: `/opt/stacks/dashboards/` - Home Automation: `/opt/stacks/homeassistant/` - - Productivity: `/opt/stacks/productivity/` - - Utilities: `/opt/stacks/utilities/` + - Infrastructure: `/opt/stacks/infrastructure/` + - Media: `/opt/stacks/media/` + - Media Management: `/opt/stacks/media-management/` - Monitoring: `/opt/stacks/monitoring/` - - Development: `/opt/stacks/development/` + - Productivity: `/opt/stacks/productivity/` + - Transcoders: `/opt/stacks/transcoders/` + - Utilities: `/opt/stacks/utilities/` + - VPN: `/opt/stacks/vpn/` + - Wikis: `/opt/stacks/wikis/` ## Toggling SSO (Authelia) On/Off @@ -191,137 +193,6 @@ docker compose -f /opt/stacks/stack-name/docker-compose.yml down - **Gradual Exposure**: Comment out SSO only when ready to expose a service - **Quick Toggle**: AI assistant can modify these labels automatically when you ask -## Authelia Customization - -### Available Customization Options - -**1. Branding and Appearance** -Edit `/opt/stacks/core/authelia/configuration.yml`: - -```yaml -# Custom logo and branding -theme: dark # Options: light, dark, grey, auto - -# No built-in web UI for configuration -# All settings managed via YAML files -``` - -**2. User Management** -Users are managed in `/opt/stacks/core/authelia/users_database.yml`: - -```yaml -users: - username: - displayname: "Display Name" - password: "$argon2id$v=19$m=65536..." # Generated with authelia hash-password - email: user@example.com - groups: - - admins - - users -``` - -Generate password hash: -```bash -docker run --rm authelia/authelia:4.37 authelia hash-password 'yourpassword' -``` - -**3. Access Control Rules** -Customize who can access what in `configuration.yml`: - -```yaml -access_control: - default_policy: deny - - rules: - # Public services (no auth) - - domain: - - "jellyfin.yourdomain.com" - - "plex.yourdomain.com" - policy: bypass - - # Admin only services - - domain: - - "dockge.yourdomain.com" - - "portainer.yourdomain.com" - policy: two_factor - subject: - - "group:admins" - - # All authenticated users - - domain: "*.yourdomain.com" - policy: one_factor -``` - -**4. Two-Factor Authentication (2FA)** -- TOTP (Time-based One-Time Password) via apps like Google Authenticator, Authy -- Configure in `configuration.yml` under `totp:` section -- Per-user enrollment via Authelia UI at `https://auth.${DOMAIN}` - -**5. Session Management** -Edit `configuration.yml`: - -```yaml -session: - name: authelia_session - expiration: 1h # How long before re-login required - inactivity: 5m # Timeout after inactivity - remember_me_duration: 1M # "Remember me" checkbox duration -``` - -**6. Notification Settings** -Email notifications for password resets, 2FA enrollment: - -```yaml -notifier: - smtp: - host: smtp.gmail.com - port: 587 - username: your-email@gmail.com - password: app-password - sender: authelia@yourdomain.com -``` - -### No Web UI for Configuration - -⚠️ **Important**: Authelia does **not** have a configuration web UI. All configuration is done via YAML files: -- `/opt/stacks/core/authelia/configuration.yml` - Main settings -- `/opt/stacks/core/authelia/users_database.yml` - User accounts - -This is **by design** and makes Authelia perfect for AI management and security-first approach: -- AI can read and modify YAML files -- Version control friendly -- No UI clicks required -- Infrastructure as code -- Secure by default - -**Web UI Available For:** -- Login page: `https://auth.${DOMAIN}` -- User profile: Change password, enroll 2FA -- Device enrollment: Manage trusted devices - -**Alternative with Web UI: Authentik** -If you need a web UI for user management, Authentik is included in the infrastructure stack: -- **Authentik**: Full-featured SSO with web UI for user/group management -- Access at: `https://authentik.${DOMAIN}` -- Includes PostgreSQL database and Redis cache -- More complex but offers GUI-based configuration -- Deploy only if you need web-based user management - -**Other Alternatives:** -- **Keycloak**: Enterprise-grade SSO with web UI -- **Authelia + LDAP**: Use LDAP with web management (phpLDAPadmin, etc.) - -### Quick Configuration with AI - -Since all Authelia configuration is file-based, you can use the AI assistant to: -- Add/remove users -- Modify access rules -- Change session settings -- Update branding -- Enable/disable features - -Just ask: "Add a new user to Authelia" or "Change session timeout to 2 hours" - ## Storage Recommendations | Data Type | Recommended Location | Reason | @@ -355,3 +226,4 @@ All configuration templates are available in `config-templates/`: - **Quick Reference**: See [docs/quick-reference.md](quick-reference.md) for common commands - **Proxying External Hosts**: See [docs/proxying-external-hosts.md](proxying-external-hosts.md) for Raspberry Pi, NAS, etc. - **AI Assistant**: Use GitHub Copilot in VS Code with `.github/copilot-instructions.md` for intelligent homelab management + diff --git a/scripts/ez-homelab.sh b/scripts/ez-homelab.sh index 232e62b..9de0a97 100755 --- a/scripts/ez-homelab.sh +++ b/scripts/ez-homelab.sh @@ -484,7 +484,7 @@ setup_stacks_for_dockge() { log_info "Setting up all stacks for Dockge..." # List of stacks to setup - STACKS=("vpn" "media" "media-management" "monitoring" "productivity" "utilities" "alternatives" "homeassistant" "nextcloud") + STACKS=("vpn" "media" "media-management" "transcoders" "monitoring" "productivity" "wikis" "utilities" "alternatives" "homeassistant") for stack in "${STACKS[@]}"; do STACK_DIR="/opt/stacks/$stack"