diff --git a/.env.example b/.env.example index 1412d03..4d0477e 100644 --- a/.env.example +++ b/.env.example @@ -1,138 +1,116 @@ -# EZ-Homelab .env template file - Copy to .env and fill in your values +######################################################## +#### EZ-Homelab .env template file #### +#### EZ MODE: just run ez-homelab.sh #### +######################################################## -# ################################ -# #### REQUIRED CONFIGURATION #### +######################################################## +# #### REQUIRED CONFIGURATION #### -# User and Group IDs for file permissions (get with: id -u and id -g) +# Required for file permissions (get with: id -u and id -g) PUID=1000 PGID=1000 TZ=America/New_York -# Servers configuration -SERVER_IP=192.168.1.100 # This server -SERVER_HOSTNAME=debian +# This Server's IP and Hostname +SERVER_IP= +SERVER_HOSTNAME= # Domain Configuration -DUCKDNS_SUBDOMAINS=yourdomain # Without .duckdns.org -DUCKDNS_TOKEN=your-duckdns-token +DUCKDNS_SUBDOMAINS= +DUCKDNS_TOKEN= DOMAIN=${DUCKDNS_SUBDOMAINS}.duckdns.org -# Default credentials (used by multiple services for easier setup) -DEFAULT_USER=admin -DEFAULT_PASSWORD=changeme -DEFAULT_EMAIL=admin@example.com - -# ADMIN_SSH_PUB_KEY= +# Default credentials (used by multiple services) +# For better security: replace each ${DEFAULT_PASSWORD} with unique values +DEFAULT_USER= +DEFAULT_PASSWORD= +DEFAULT_EMAIL= # FOLDER PATHS -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 +STACKS_DIR=/opt/stacks # for Dockge +PROJECTS_DIR=${STACKS_DIR} # for Arcane +MEDIA_DIR=/mnt/media # Large media files on separate drive +DOWNLOAD_DIR=/mnt/downloads # Downloads on separate drive -# If selecting option 3: Deploy Additional Server -# the CORE_SERVER is where the Core Traefik is running -CORE_SERVER_IP=192.168.1.101 -CORE_SERVER_HOSTNAME=debian2 +# PROJECTDIR=~/projects # User's projects folder + +# ########## END REQUIRED CONFIGURATION #### +######################################################## + +######################################################## +# #### OPTION 3: ADDITIONAL SERVER #### +CORE_SERVER_IP= +CORE_SERVER_HOSTNAME= CORE_SERVER_USER=${DEFAULT_USER} CORE_SERVER_PASSWORD=${DEFAULT_PASSWORD} +# #### END ADDITIONAL SERVER #### +######################################################## -# ########################################## -# #### NOTEABLE OPTIONAL CONFIGURATIONS #### - -# Surfshark OpenVPN (RECOMMENDED) -# Wireguard options are below and commented out -SURFSHARK_USERNAME=your-surfshark-username -SURFSHARK_PASSWORD=your-surfshark-password +######################################################## +# #### VPN CONFIGURATIONS #### +SURFSHARK_USERNAME= +SURFSHARK_PASSWORD= VPN_SERVER_COUNTRIES=Netherlands # Preferred VPN server location +# #### END VPN CONFIGURATIONS #### +######################################################## -# Email credentials for services that need SMTP -SMTP_EMAIL_PASSWORD=your-email-app-password -SMTP_EMAIL_SERVER=smtp.gmail.com # change if not using Gmail +######################################################## +# #### EMAIL CONFIGURATIONS #### +SMTP_EMAIL_PASSWORD= +SMTP_EMAIL_SERVER=smtp.gmail.com SMTP_EMAIL_PORT=587 SMTP_EMAIL_FROM=${DEFAULT_EMAIL} SMTP_EMAIL_SECURITY=starttls +ACME_EMAIL=${DEFAULT_EMAIL} +SMTP_USERNAME=${SMTP_EMAIL_FROM} +SMTP_PASSWORD=${SMTP_EMAIL_PASSWORD} +# #### END EMAIL CONFIGURATIONS #### +######################################################## -# ACME Email for Let's Encrypt certificates -ACME_EMAIL=${DEFAULT_EMAIL} +######################################################## +# ########### DELETE AFTER DEPLOYMENT ########### +# #### Used by ez-homelab.sh & deploy scripts #### +# #### Unused by the actual containers #### -# Authelia Admin Account -# These 4 Used by ez-homelab.sh for easy deployment -# Not used by the Authelia container directly -ADMIN_EMAIL=${DEFAULT_EMAIL} # Used for admin user account +# Public SSH key from the pc used to access the homelab +# Will be added to the admin user's authorized_keys +# #### DO NOT INCLUDE YOUR PRIVATE KEY #### +ADMIN_SSH_PUB_KEY= + +# Authelia Admin Credentials +ADMIN_EMAIL=${DEFAULT_EMAIL} AUTHELIA_ADMIN_USER=${DEFAULT_USER} AUTHELIA_ADMIN_EMAIL=${DEFAULT_EMAIL} AUTHELIA_ADMIN_PASSWORD=${DEFAULT_PASSWORD} -AUTHELIA_ADMIN_PASSWORD_HASH=generate-with-openssl-rand-hex-64 -# SMTP for Authelia Notifications -SMTP_USERNAME=${SMTP_EMAIL_FROM} -SMTP_PASSWORD=${SMTP_EMAIL_PASSWORD} +# Use this command to generate AUTHELIA_ADMIN_PASSWORD_HASH: +# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password "YOUR_PASSWORD_HERE" +AUTHELIA_ADMIN_PASSWORD_HASH= -# Let ez-homelab.sh generate these 3 unless you know what your doing -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 +# Use this command to generate each secret +# openssl rand -hex 64 +AUTHELIA_JWT_SECRET= +AUTHELIA_SESSION_SECRET= +AUTHELIA_STORAGE_ENCRYPTION_KEY= -# ARCANE Secrets - Let ez-homelab.sh generate these unless you know what your doing -ARCANE_ENCRYPTION_KEY=generate-with-openssl-rand-hex-64 -ARCANE_JWT_SECRET=generate-with-openssl-rand-hex-64 +# Arcane secrets +ARCANE_ENCRYPTION_KEY= +ARCANE_JWT_SECRET= +# ########## END DELETE AFTER DEPLOYMENT #### +######################################################## -# Surfshark WireGuard (OPTIONAL - Advanced users only) -# Get WireGuard details from Surfshark dashboard -# SURFSHARK_PRIVATE_KEY=your-wireguard-private-key -# SURFSHARK_ADDRESSES=10.14.0.2/16 +######################################################## +# ##################################################### +# #### Application Specific Configurations #### +# ##################################################### -# What domains Homepage will accept requests from -# comma separated list NO SPACES!!! -HOMEPAGE_ALLOWED_HOSTS=homepage.${DOMAIN},${SERVER_IP}:3003 +# ##################################################### +# #### Bitwarden ##### +# #### SET TO FALSE AFTER CREATING USERS #### -# ####################################### -# #### OTHER OPTIONAL CONFIGURATIONS #### +BITWARDEN_SIGNUPS_ALLOWED=true -# BookStack -BOOKSTACK_DB_PASSWORD=${DEFAULT_PASSWORD} -BOOKSTACK_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} - -# DATABASES - GENERAL -POSTGRES_USER=${DEFAULT_USER} -POSTGRES_PASSWORD=${DEFAULT_PASSWORD} -POSTGRES_DB=homelab -PGADMIN_EMAIL=${DEFAULT_EMAIL} -PGADMIN_PASSWORD=${DEFAULT_PASSWORD} - -# Form.io -FORMIO_JWT_SECRET=${DEFAULT_PASSWORD} -FORMIO_DB_SECRET=${DEFAULT_PASSWORD} - -# Gitea -GITEA_DB_PASSWORD=${DEFAULT_PASSWORD} - -# GRAFANA -GRAFANA_ADMIN_PASSWORD=${DEFAULT_PASSWORD} - -# Jupyter Notebook -JUPYTER_TOKEN=${DEFAULT_PASSWORD} - -# MediaWiki -MEDIAWIKI_DB_PASSWORD=${DEFAULT_PASSWORD} -MEDIAWIKI_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} - -# Nextcloud -NEXTCLOUD_ADMIN_USER=${DEFAULT_USER} -NEXTCLOUD_ADMIN_PASSWORD=${DEFAULT_PASSWORD} -NEXTCLOUD_DB_PASSWORD=${DEFAULT_PASSWORD} -NEXTCLOUD_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} - -# Pi-hole -PIHOLE_PASSWORD=${DEFAULT_PASSWORD} - -# qBittorrent -QBITTORRENT_USER=admin -QBITTORRENT_PASS=${DEFAULT_PASSWORD} - -# Vaultwarden BITWARDEN_ADMIN_TOKEN=${DEFAULT_PASSWORD} BITWARDEN_INVITATIONS_ALLOWED=true SMTP_HOST=${SMTP_EMAIL_SERVER} @@ -140,17 +118,90 @@ SMTP_FROM=${SMTP_EMAIL_FROM} SMTP_PORT=${SMTP_EMAIL_PORT} SMTP_SECURITY=${SMTP_EMAIL_SECURITY} -# #### IMPORTANT **************************** -# #### SET TO FALSE AFTER CREATING USERS #### -BITWARDEN_SIGNUPS_ALLOWED=true +# ##################################################### +# #### Bookstack ##### + +BOOKSTACK_DB_PASSWORD=${DEFAULT_PASSWORD} +BOOKSTACK_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} + +# ##################################################### +# #### Code Server ##### -# VS Code Server CODE_SERVER_PASSWORD=${DEFAULT_PASSWORD} CODE_SERVER_SUDO_PASSWORD=${DEFAULT_PASSWORD} -# Watchtower Notifications (optional) +# ##################################################### +# #### Form.io ##### + +FORMIO_JWT_SECRET=${DEFAULT_PASSWORD} +FORMIO_DB_SECRET=${DEFAULT_PASSWORD} + +# ##################################################### +# #### Gitea ##### + +GITEA_DB_PASSWORD=${DEFAULT_PASSWORD} + +# ##################################################### +# #### Grafana ##### + +GRAFANA_ADMIN_PASSWORD=${DEFAULT_PASSWORD} + +# ##################################################### +# #### Homepage ##### + +# comma separated list NO SPACES!!! +HOMEPAGE_ALLOWED_HOSTS=homepage.${DOMAIN},${SERVER_IP}:3003 + +# ##################################################### +# #### Jupyter ##### + +JUPYTER_TOKEN=${DEFAULT_PASSWORD} + +# ##################################################### +# #### MediaWiki ##### + +MEDIAWIKI_DB_PASSWORD=${DEFAULT_PASSWORD} +MEDIAWIKI_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} + +# ##################################################### +# #### Nextcloud ##### + +NEXTCLOUD_ADMIN_USER=${DEFAULT_USER} +NEXTCLOUD_ADMIN_PASSWORD=${DEFAULT_PASSWORD} +NEXTCLOUD_DB_PASSWORD=${DEFAULT_PASSWORD} +NEXTCLOUD_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} +NEXTCLOUD_DIR=./nextcloud/data +# ##################################################### +# #### Pi-hole ##### + +PIHOLE_PASSWORD=${DEFAULT_PASSWORD} + +# ##################################################### +# #### qBittorrent ##### + +QBITTORRENT_USER=admin +QBITTORRENT_PASS=${DEFAULT_PASSWORD} + +# ##################################################### +# #### SURFSHARK OPTIONAL CONFIGURATIONS #### + +# Surfshark WireGuard (OPTIONAL - Advanced users only) +# Get WireGuard details from Surfshark dashboard +# SURFSHARK_PRIVATE_KEY=your-wireguard-private-key +# SURFSHARK_ADDRESSES=10.14.0.2/16 + +# ##################################################### +# #### Watchtower ##### + # WATCHTOWER_NOTIFICATION_URL= -# WordPress +# ##################################################### +# #### WordPress ##### + WORDPRESS_DB_PASSWORD=${DEFAULT_PASSWORD} -WORDPRESS_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} \ No newline at end of file +WORDPRESS_DB_ROOT_PASSWORD=${DEFAULT_PASSWORD} + + + +TDARR_TRANSCODE_DIR=./tdarr/transcode_cache +UNMANIC_TRANSCODE_DIR=./unmanic/cache \ No newline at end of file diff --git a/docker-compose/alternatives/docker-compose.yml b/docker-compose/alternatives/docker-compose.yml index a674e3a..f5c66f4 100644 --- a/docker-compose/alternatives/docker-compose.yml +++ b/docker-compose/alternatives/docker-compose.yml @@ -19,7 +19,7 @@ services: - '9000:9000' volumes: - /var/run/docker.sock:/var/run/docker.sock - - portainer-data:/data + - ./portainer/data:/data security_opt: - no-new-privileges:true labels: @@ -52,8 +52,8 @@ services: ports: - '9000:9000' volumes: - - /opt/stacks/authentik/media:/media - - /opt/stacks/authentik/custom-templates:/templates + - ./authentik/media:/media + - ./authentik/custom-templates:/templates environment: - AUTHENTIK_REDIS__HOST=authentik-redis - AUTHENTIK_POSTGRESQL__HOST=authentik-db @@ -89,9 +89,9 @@ services: networks: - homelab-network volumes: - - /opt/stacks/authentik/media:/media - - /opt/stacks/authentik/certs:/certs - - /opt/stacks/authentik/custom-templates:/templates + - ./authentik/media:/media + - ./authentik/certs:/certs + - ./authentik/custom-templates:/templates environment: - AUTHENTIK_REDIS__HOST=authentik-redis - AUTHENTIK_POSTGRESQL__HOST=authentik-db @@ -119,7 +119,7 @@ services: networks: - homelab-network volumes: - - authentik-db-data:/var/lib/postgresql/data + - ./authentik/db:/var/lib/postgresql/data environment: - POSTGRES_USER=${AUTHENTIK_DB_USER} - POSTGRES_PASSWORD=${AUTHENTIK_DB_PASSWORD} @@ -145,7 +145,7 @@ services: networks: - homelab-network volumes: - - authentik-redis-data:/data + - ./authentik/redis:/data command: --save 60 1 --loglevel warning labels: # TRAEFIK CONFIGURATION @@ -173,7 +173,7 @@ services: - '32400:32400' volumes: - ./plex/config:/config - - /mnt/media:/media:ro # Large media files on separate drive + - ${MEDIA_DIR}:/media:ro # Large media files on separate drive - plex-transcode:/transcode environment: - PUID=1000 @@ -211,18 +211,6 @@ services: - 'traefik.http.routers.plex.entrypoints=websecure' - 'traefik.http.routers.plex.tls.certresolver=letsencrypt' - 'traefik.http.services.plex.loadbalancer.server.port=32400' - - 'x-dockge.url=https://plex.${DOMAIN}' - - 'x-dockge.url=https://plex.${DOMAIN}' - -volumes: - portainer-data: - driver: local - authentik-db-data: - driver: local - authentik-redis-data: - driver: local - plex-transcode: - driver: local networks: homelab-network: diff --git a/docker-compose/arcane/docker-compose.yml b/docker-compose/arcane/docker-compose.yml index 49673b8..f73d645 100644 --- a/docker-compose/arcane/docker-compose.yml +++ b/docker-compose/arcane/docker-compose.yml @@ -6,13 +6,13 @@ services: - '3552:3552' volumes: - /var/run/docker.sock:/var/run/docker.sock - - arcane-data:/app/data - - /opt/stacks:/opt/stacks + - ./arcane/data:/app/data + - ${PROJECTS_DIR}:${PROJECTS_DIR} environment: - APP_URL=http://${SERVER_IP}:3552 - - PROJECTS_DIRECTORY=/opt/stacks - - PUID=1000 - - PGID=1000 + - PROJECTS_DIRECTORY=${PROJECTS_DIR} + - PUID=${PUID} + - PGID=${PGID} - ENCRYPTION_KEY=${ARCANE_ENCRYPTION_KEY} - JWT_SECRET=${ARCANE_JWT_SECRET} restart: unless-stopped @@ -31,7 +31,7 @@ services: # - "3553:3553" # volumes: # - /var/run/docker.sock:/var/run/docker.sock -# - arcane-data:/app/data +# - ./arcane/data:/app/data # networks: # - traefik-network diff --git a/docker-compose/core/docker-compose.yml b/docker-compose/core/docker-compose.yml index abfc7e4..d38398f 100644 --- a/docker-compose/core/docker-compose.yml +++ b/docker-compose/core/docker-compose.yml @@ -12,9 +12,9 @@ services: container_name: duckdns restart: unless-stopped environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} - SUBDOMAINS=${DUCKDNS_SUBDOMAINS} - TOKEN=${DUCKDNS_TOKEN} volumes: @@ -60,7 +60,7 @@ services: container_name: authelia restart: unless-stopped environment: - - TZ=America/New_York + - TZ=${TZ} ports: - '9091:9091' volumes: @@ -112,7 +112,7 @@ services: - ./pihole/etc-pihole:/etc/pihole - ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d environment: - - TZ=America/New_York + - TZ=${TZ} - WEBPASSWORD=${PIHOLE_PASSWORD} - FTLCONF_LOCAL_IPV4=192.168.4.4 dns: diff --git a/docker-compose/core/duckdns/logrotate.conf b/docker-compose/core/duckdns/logrotate.conf deleted file mode 100644 index 828dfc6..0000000 --- a/docker-compose/core/duckdns/logrotate.conf +++ /dev/null @@ -1,5 +0,0 @@ -/config/duck.log { - rotate 5 - size 100k - compress -} diff --git a/docker-compose/dashboards/docker-compose.yml b/docker-compose/dashboards/docker-compose.yml index ae1540d..59c8b00 100644 --- a/docker-compose/dashboards/docker-compose.yml +++ b/docker-compose/dashboards/docker-compose.yml @@ -28,7 +28,7 @@ services: volumes: - ./homepage:/app/config - /var/run/docker.sock:/var/run/docker.sock # For Docker integration do not mount RO - - /opt/stacks:/opt/stacks # To discover other stacks + - ${STACKS_DIR}:${STACKS_DIR} # To discover other stacks environment: - PUID=${PUID} # Must be set to the docker user ID - PGID=${PGID} # Must be set to the docker group ID @@ -83,7 +83,7 @@ services: - ./homarr/icons:/app/public/icons - /var/run/docker.sock:/var/run/docker.sock environment: - - TZ=America/New_York + - TZ=${TZ} - SECRET_ENCRYPTION_KEY=8830c9434b05ebfe3e31340c685fea63446ab3f635c4fad68370006949ed30df healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:7575/'] diff --git a/docker-compose/dashboards/docker-compose.yml.template b/docker-compose/dashboards/docker-compose.yml.template deleted file mode 100644 index 08b0dcb..0000000 --- a/docker-compose/dashboards/docker-compose.yml.template +++ /dev/null @@ -1,127 +0,0 @@ -# Dashboard Services -# Homepage and Homarr for homelab dashboards - -# SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml - -# Service Access URLs: -# - Homepage: https://homepage.${DOMAIN} -# - Homarr: https://homarr.${DOMAIN} - -services: - # Homepage - Default Application Dashboard - homepage: - image: ghcr.io/gethomepage/homepage:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: homepage - restart: unless-stopped # change to 'no' to enable Sablier lazy loading - networks: - - homelab-network - - traefik-network - ports: - - "3003:3000" - volumes: - - ./homepage:/app/config - - /var/run/docker.sock:/var/run/docker.sock # For Docker integration do not mount RO - - /opt/stacks:/opt/stacks # To discover other stacks - environment: - - PUID=995 # Must be set to the docker user ID - - PGID=995 # Must be set to the docker group ID - - TZ=${TZ} - - HOMEPAGE_ALLOWED_HOSTS=homepage.${DOMAIN} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=dashboard" - - "homelab.description=Application dashboard" - # Traefik reverse proxy (comment/uncomment to disable/enable) - # IMPORTANT: On REMOTE SERVERS (where Traefik runs elsewhere): - # - COMMENT OUT all traefik.* labels below (don't delete them) - # - Routes are configured via external YAML files on the core server - # - This prevents conflicts between Docker labels and file provider - - "traefik.enable=true" - - "traefik.http.routers.homepage.rule=Host(`homepage.${DOMAIN}`)" - - "traefik.http.routers.homepage.entrypoints=websecure" - - "traefik.http.routers.homepage.tls=true" - - "traefik.http.routers.homepage.middlewares=authelia@docker" - - "traefik.http.services.homepage.loadbalancer.server.port=3003" - # Sablier lazy loading (disabled by default - uncomment to enable) - # - "sablier.enable=true" - # - "sablier.group=${SERVER_HOSTNAME}-homarr" - # - "sablier.start-on-demand=true" - - # Homarr - Modern dashboard - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - - homarr: - image: ghcr.io/ajnart/homarr:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: homarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "7575:7575" - volumes: - - ./homarr/config:/app/config/configs - - ./homarr/data:/data - - ./homarr/icons:/app/public/icons - - /var/run/docker.sock:/var/run/docker.sock - environment: - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:7575/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=dashboard" - - "homelab.description=Modern homelab dashboard" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.homarr.rule=Host(`homarr.${DOMAIN}`)" - - "traefik.http.routers.homarr.entrypoints=websecure" - - "traefik.http.routers.homarr.tls=true" - - "traefik.http.routers.homarr.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.homarr.loadbalancer.server.port=7575" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-homarr" - - "sablier.start-on-demand=true" - -# DOCKGE URL CONFIGURATION -x-dockge: - urls: - # Proxied URLs (through Traefik) - - https://homepage.${DOMAIN} - - https://${SERVER_IP}:3003 - - https://homarr.${DOMAIN} - - https://${SERVER_IP}:7575 - -networks: - homelab-network: - external: true - traefik-network: - external: true diff --git a/docker-compose/dockge/docker-compose.yml b/docker-compose/dockge/docker-compose.yml index c564b8b..36750d1 100644 --- a/docker-compose/dockge/docker-compose.yml +++ b/docker-compose/dockge/docker-compose.yml @@ -27,11 +27,11 @@ services: - '5001:5001' # Optional: direct access volumes: - /var/run/docker.sock:/var/run/docker.sock - - /opt/stacks:/opt/stacks # Dockge manages stacks in this directory + - ${STACKS_DIR}:${STACKS_DIR} # Dockge manages stacks in this directory - ./data:/app/data - /usr/bin/docker:/usr/bin/docker:ro # Mount docker binary for CLI access environment: - - DOCKGE_STACKS_DIR=/opt/stacks + - DOCKGE_STACKS_DIR=${STACKS_DIR} - DOCKGE_ENABLE_CONSOLE=true labels: - 'homelab.category=infrastructure' diff --git a/docker-compose/homeassistant/docker-compose.yml b/docker-compose/homeassistant/docker-compose.yml index 387c947..d4a3040 100644 --- a/docker-compose/homeassistant/docker-compose.yml +++ b/docker-compose/homeassistant/docker-compose.yml @@ -25,7 +25,7 @@ services: - ./homeassistant/config:/config - /etc/localtime:/etc/localtime:ro environment: - - TZ=America/New_York + - TZ=${TZ} privileged: true labels: - 'homelab.category=iot' @@ -56,7 +56,7 @@ services: - ./esphome/config:/config - /etc/localtime:/etc/localtime:ro environment: - - TZ=America/New_York + - TZ=${TZ} - ESPHOME_DASHBOARD_USE_PING=true privileged: true # For USB device access labels: @@ -87,9 +87,9 @@ services: ports: - '8084:80' volumes: - - /opt/stacks/tasmoadmin/data:/data + - ./tasmoadmin/data:/data environment: - - TZ=America/New_York + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -118,10 +118,10 @@ services: ports: - '8765:8765' volumes: - - ./$(basename $file .yml)/config:/etc/motioneye - - /mnt/surveillance:/var/lib/motioneye # Large video files on separate drive + - ./motioneye/config:/etc/motioneye + - ./motioneye/video:/var/lib/motioneye environment: - - TZ=America/New_York + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -159,9 +159,9 @@ services: ports: - '1880:1880' volumes: - - /opt/stacks/nodered/data:/data + - ./nodered/data:/data environment: - - TZ=America/New_York + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -217,7 +217,7 @@ services: # # Common paths: /dev/ttyACM0, /dev/ttyUSB0, /dev/serial/by-id/... # # Run 'ls -l /dev/serial/by-id/' to find your adapter # environment: - # - TZ=America/New_York + # - TZ=${TZ} # labels: # - 'homelab.category=iot' # - 'homelab.description=Zigbee to MQTT bridge' diff --git a/docker-compose/homeassistant/docker-compose.yml.template b/docker-compose/homeassistant/docker-compose.yml.template deleted file mode 100644 index 50d8c7a..0000000 --- a/docker-compose/homeassistant/docker-compose.yml.template +++ /dev/null @@ -1,258 +0,0 @@ -# Home Assistant and IoT Services -# Home automation platform and related tools -# Place in /opt/stacks/homeassistant/docker-compose.yml - -# Service Access URLs: -# - Home Assistant: https://ha.${DOMAIN} (configure via Traefik file provider - uses host network) -# - ESPHome: https://esphome.${DOMAIN} -# - Node-RED: https://nodered.${DOMAIN} -# - Mosquitto MQTT: mqtt://server-ip:1883 (no web UI) -# - Zigbee2MQTT: https://zigbee2mqtt.${DOMAIN} (requires USB adapter) - -services: - # Home Assistant - Home automation platform - # Access at: https://ha.${DOMAIN} - # NOTE: No Authelia - HA has its own authentication - homeassistant: - image: ghcr.io/home-assistant/home-assistant:2024.1 - deploy: - resources: - limits: - cpus: '1.5' - memory: 1G - pids: 2048 - reservations: - cpus: '0.75' - memory: 512M - container_name: homeassistant - restart: unless-stopped - network_mode: host # Required for device discovery - volumes: - - ./homeassistant/config:/config - - /etc/localtime:/etc/localtime:ro - environment: - - TZ=${TZ} - privileged: true - labels: - - "homelab.category=iot" - - "homelab.description=Home automation platform" - # Note: network_mode: host means Traefik can't proxy this directly - # Use Traefik's file provider or external host routing - - # ESPHome - ESP8266/ESP32 firmware manager - # Access at: https://esphome.${DOMAIN} - esphome: - image: ghcr.io/esphome/esphome:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: esphome - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "6052:6052" - volumes: - - ./esphome/config:/config - - /etc/localtime:/etc/localtime:ro - environment: - - TZ=${TZ} - - ESPHOME_DASHBOARD_USE_PING=true - privileged: true # For USB device access - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=iot" - - "homelab.description=ESP8266/ESP32 firmware manager" - # 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.esphome.rule=Host(`esphome.${DOMAIN}`)" - - "traefik.http.routers.esphome.entrypoints=websecure" - - "traefik.http.routers.esphome.tls.certresolver=letsencrypt" - - "traefik.http.routers.esphome.middlewares=authelia@docker" - - "traefik.http.services.esphome.loadbalancer.server.port=6052" - - # TasmoAdmin - Tasmota device manager - # Access at: https://tasmoadmin.${DOMAIN} - tasmoadmin: - image: ghcr.io/tasmoadmin/tasmoadmin:latest - container_name: tasmoadmin - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "8084:80" - volumes: - - /opt/stacks/tasmoadmin/data:/data - environment: - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=iot" - - "homelab.description=Tasmota device management" - # 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.tasmoadmin.rule=Host(`tasmoadmin.${DOMAIN}`)" - - "traefik.http.routers.tasmoadmin.entrypoints=websecure" - - "traefik.http.routers.tasmoadmin.tls.certresolver=letsencrypt" - - "traefik.http.routers.tasmoadmin.middlewares=authelia@docker" - - "traefik.http.services.tasmoadmin.loadbalancer.server.port=80" - - # MotionEye - Video surveillance - # Access at: https://motioneye.${DOMAIN} - motioneye: - image: ccrisan/motioneye:master-amd64 - container_name: motioneye - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "8765:8765" # Optional: direct access - volumes: - - ./$(basename $file .yml)/config:/etc/motioneye - - /mnt/surveillance:/var/lib/motioneye # Large video files on separate drive - environment: - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=iot" - - "homelab.description=Video surveillance system" - # 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.motioneye.rule=Host(`motioneye.${DOMAIN}`)" - - "traefik.http.routers.motioneye.entrypoints=websecure" - - "traefik.http.routers.motioneye.tls.certresolver=letsencrypt" - - "traefik.http.routers.motioneye.middlewares=authelia@docker" - - "traefik.http.services.motioneye.loadbalancer.server.port=8765" - - # Node-RED - Flow-based automation (Home Assistant addon alternative) - # Access at: https://nodered.${DOMAIN} - nodered: - image: nodered/node-red:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: nodered - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "1880:1880" - volumes: - - /opt/stacks/nodered/data:/data - environment: - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=iot" - - "homelab.description=Flow-based automation programming" - # 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.nodered.rule=Host(`nodered.${DOMAIN}`)" - - "traefik.http.routers.nodered.entrypoints=websecure" - - "traefik.http.routers.nodered.tls.certresolver=letsencrypt" - - "traefik.http.routers.nodered.middlewares=authelia@docker" - - "traefik.http.services.nodered.loadbalancer.server.port=1880" - - # Mosquitto - MQTT broker (Home Assistant addon alternative) - # Used by: Home Assistant, ESPHome, Tasmota devices - mosquitto: - image: eclipse-mosquitto:latest - container_name: mosquitto - restart: unless-stopped - networks: - - homelab-network - ports: - - "1883:1883" # MQTT - - "9001:9001" # Websockets - volumes: - - ./mosquitto/config:/mosquitto/config - - ./mosquitto/data:/mosquitto/data - - ./mosquitto/log:/mosquitto/log - labels: - - "homelab.category=iot" - - "homelab.description=MQTT message broker" - - # Zigbee2MQTT - Zigbee to MQTT bridge (DISABLED - requires USB adapter) - # Access at: https://zigbee2mqtt.${DOMAIN} - # NOTE: Requires USB Zigbee adapter (e.g., ConBee II, Sonoff ZBDongle) - # Uncomment after connecting adapter - # zigbee2mqtt: - # image: koenkk/zigbee2mqtt:1.35.1 - # container_name: zigbee2mqtt - # restart: unless-stopped - # networks: - # - homelab-network - # - traefik-network - # volumes: - # - ./zigbee2mqtt/data:/app/data - # - /run/udev:/run/udev:ro - # # Uncomment and adjust device path after connecting USB adapter: - # # devices: - # # - /dev/ttyACM0:/dev/ttyACM0 # Adjust based on your adapter - # # Common paths: /dev/ttyACM0, /dev/ttyUSB0, /dev/serial/by-id/... - # # Run 'ls -l /dev/serial/by-id/' to find your adapter - # environment: - # - TZ=${TZ} - # labels: - # - "homelab.category=iot" - # - "homelab.description=Zigbee to MQTT bridge" - # - "traefik.enable=true" - # - "traefik.http.routers.zigbee2mqtt.rule=Host(`zigbee2mqtt.${DOMAIN}`)" - # - "traefik.http.routers.zigbee2mqtt.entrypoints=websecure" - # - "traefik.http.routers.zigbee2mqtt.tls.certresolver=letsencrypt" - # - "traefik.http.routers.zigbee2mqtt.middlewares=authelia@docker" - # - "traefik.http.services.zigbee2mqtt.loadbalancer.server.port=8080" - -networks: - homelab-network: - external: true - traefik-network: - external: true - -x-dockge: - urls: - # Proxied URLs (through Traefik) - - https://ha.${DOMAIN} - - http://${SERVER_IP}:8123 - - https://esphome.${DOMAIN} - - http://${SERVER_IP}:6052 - - https://tasmoadmin.${DOMAIN} - - http://${SERVER_IP}:8084 - - https://motioneye.${DOMAIN} - - http://${SERVER_IP}:8765 - - https://nodered.${DOMAIN} - - http://${SERVER_IP}:1880 - - mqtt://${SERVER_IP}:1883 - - https://zigbee2mqtt.${DOMAIN} \ No newline at end of file diff --git a/docker-compose/infrastructure/docker-compose.yml b/docker-compose/infrastructure/docker-compose.yml index d313deb..e2b1592 100644 --- a/docker-compose/infrastructure/docker-compose.yml +++ b/docker-compose/infrastructure/docker-compose.yml @@ -8,12 +8,6 @@ services: dockerproxy: # Docker socket proxy for security - provides safe Docker API access, must always run - # REQUIREMENTS FOR SABLIER INTEGRATION: - # 1. Docker daemon must be configured to listen on TCP port 2375 (not just unix socket) - # 2. Firewall must allow access to port 2375 from Sablier service - # 3. Docker daemon config should include: 'hosts': ['tcp://0.0.0.0:2375', 'unix:///var/run/docker.sock'] - # 4. For security, consider restricting access to specific IP ranges or using TLS - # 5. dockerproxy runs for additional security but doesn't expose port 2375 (handled by Docker daemon) image: tecnativa/docker-socket-proxy:latest container_name: dockerproxy privileged: true @@ -36,7 +30,6 @@ services: - homelab.category=infrastructure - homelab.description=Docker socket proxy for security - # Watchtower - Automatic container updates watchtower: image: containrrr/watchtower:latest @@ -171,12 +164,12 @@ services: - '8079:8443' volumes: - ./code-server/config:/config - - /opt/stacks:/opt/stacks # Access to all stacks + - ${STACKS_DIR}:${STACKS_DIR} # Access to all stacks - /mnt:/mnt:ro # Read-only access to data environment: - PUID=1000 - PGID=1000 - - TZ=America/New_York + - TZ=${TZ} - PASSWORD=${CODE_SERVER_PASSWORD} - SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD} healthcheck: diff --git a/docker-compose/infrastructure/docker-compose.yml.template b/docker-compose/infrastructure/docker-compose.yml.template deleted file mode 100644 index 628a623..0000000 --- a/docker-compose/infrastructure/docker-compose.yml.template +++ /dev/null @@ -1,294 +0,0 @@ -# Infrastructure Services -# Core services that other services depend on -# Place in /opt/stacks/infrastructure/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) -# - See individual service comments for specific reasoning - -services: - dockerproxy: - # Docker socket proxy for security - provides safe Docker API access, must always run - # REQUIREMENTS FOR SABLIER INTEGRATION: - # 1. Docker daemon must be configured to listen on TCP port 2375 (not just unix socket) - # 2. Firewall must allow access to port 2375 from Sablier service - # 3. Docker daemon config should include: "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"] - # 4. For security, consider restricting access to specific IP ranges or using TLS - # 5. dockerproxy runs for additional security but doesn't expose port 2375 (handled by Docker daemon) - image: tecnativa/docker-socket-proxy:latest - container_name: dockerproxy - privileged: true - restart: unless-stopped - # Note: Port 2375 is handled directly by Docker daemon for Sablier access - # dockerproxy provides additional security features but doesn't expose the port - volumes: - - /var/run/docker.sock:/var/run/docker.sock - environment: - - CONTAINERS=1 - - SERVICES=1 - - TASKS=1 - - NETWORKS=1 - - NODES=1 - - EXEC=1 - - IMAGES=1 - - VOLUMES=1 - - SWARM=1 - labels: - - homelab.category=infrastructure - - homelab.description=Docker socket proxy for security - - # Pi-hole - Network-wide ad blocker and DNS server - # Access at: https://pihole.${DOMAIN} - # DNS service must always run for network-wide ad blocking - pihole: - image: pihole/pihole:2024.01.0 - deploy: - resources: - limits: - cpus: '0.25' - memory: 128M - pids: 256 - reservations: - cpus: '0.10' - memory: 64M - container_name: pihole - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "53:53/tcp" # DNS TCP - - "53:53/udp" # DNS UDP - volumes: - - ./pihole/etc-pihole:/etc/pihole - - ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d - environment: - - TZ=${TZ} - - WEBPASSWORD=${PIHOLE_PASSWORD} - - FTLCONF_LOCAL_IPV4=${SERVER_IP} - dns: - - 127.0.0.1 - - 1.1.1.1 - cap_add: - - NET_ADMIN - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=infrastructure" - - "homelab.description=Network-wide ad blocking and DNS" - # Traefik reverse proxy (comment/uncomment to disable/enable) - # IMPORTANT: On REMOTE SERVERS (where Traefik runs elsewhere): - # - COMMENT OUT all traefik.* labels below (don't delete them) - # - Routes are configured via external YAML files on the core server - # - This prevents conflicts between Docker labels and file provider - - "traefik.enable=true" - - "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN}`)" - - "traefik.http.routers.pihole.entrypoints=websecure" - - "traefik.http.routers.pihole.tls.certresolver=letsencrypt" - - "traefik.http.routers.pihole.middlewares=authelia@docker" - - "traefik.http.services.pihole.loadbalancer.server.port=80" - - # Watchtower - Automatic container updates - # Monitors and updates Docker containers to latest versions - # Runs daily at 4 AM - watchtower: - image: containrrr/watchtower:latest - container_name: watchtower - restart: unless-stopped - networks: - - homelab-network - volumes: - - /var/run/docker.sock:/var/run/docker.sock - environment: - - DOCKER_API_VERSION=1.52 - - WATCHTOWER_CLEANUP=true - - WATCHTOWER_INCLUDE_RESTARTING=true - - WATCHTOWER_SCHEDULE=0 0 4 * * * # 4 AM daily - - WATCHTOWER_NOTIFICATIONS=shoutrrr - - WATCHTOWER_NOTIFICATION_URL=${WATCHTOWER_NOTIFICATION_URL} - labels: - - "homelab.category=infrastructure" - - "homelab.description=Automatic Docker container updates" - - # Dozzle - Real-time Docker log viewer - # Access at: https://dozzle.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - dozzle: - image: amir20/dozzle:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: dozzle - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8085:8080" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - - DOZZLE_LEVEL=info - - DOZZLE_TAILSIZE=300 - - DOZZLE_FILTER=status=running - healthcheck: - test: ["CMD", "/dozzle", "healthcheck"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=infrastructure" - - "homelab.description=Real-time Docker log viewer" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.dozzle.rule=Host(`dozzle.${SERVER_HOSTNAME}.${DOMAIN}`)" - - "traefik.http.routers.dozzle.entrypoints=websecure" - - "traefik.http.routers.dozzle.tls=true" - - "traefik.http.routers.dozzle.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.dozzle.loadbalancer.server.port=8085" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-dozzle" - - "sablier.start-on-demand=true" - - # Glances - System monitoring - # Access at: https://glances.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity - glances: - image: nicolargo/glances:latest-full - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: glances - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "61208:61208" - pid: host - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - ./glances/config:/glances/conf - environment: - - GLANCES_OPT=-w - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:61208/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=infrastructure" - - "homelab.description=System and Docker monitoring" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.glances.rule=Host(`glances.${SERVER_HOSTNAME}.${DOMAIN}`)" - - "traefik.http.routers.glances.entrypoints=websecure" - - "traefik.http.routers.glances.tls=true" - - "traefik.http.routers.glances.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.glances.loadbalancer.server.port=61208" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-glances" - - "sablier.start-on-demand=true" - - # Code Server - VS Code in browser - # Access at: https://code.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity - code-server: - image: lscr.io/linuxserver/code-server:latest - deploy: - resources: - limits: - cpus: '1.5' - memory: 1G - pids: 2048 - reservations: - cpus: '0.75' - memory: 512M - container_name: code-server - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8079:8443" - volumes: - - ./code-server/config:/config - - /opt/stacks:/opt/stacks # Access to all stacks - - /mnt:/mnt:ro # Read-only access to data - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - PASSWORD=${CODE_SERVER_PASSWORD} - - SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8443/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=infrastructure" - - "homelab.description=VS Code in browser" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.code-server.rule=Host(`code.${DOMAIN}`)" - - "traefik.http.routers.code-server.entrypoints=websecure" - - "traefik.http.routers.code-server.tls.certresolver=letsencrypt" - - "traefik.http.routers.code-server.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.code-server.loadbalancer.server.port=8443" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-code-server" - - "sablier.start-on-demand=true" - -x-dockge: - urls: - - https://pihole.${DOMAIN} - - https://${SERVER_IP}:53 - - https://dozzle.${DOMAIN} - - https://${SERVER_IP}:8085 - - https://glances.${DOMAIN} - - https://${SERVER_IP}:61208 - - https://code.${DOMAIN} - - https://${SERVER_IP}:8079 - - http://${SERVER_IP}:2375 # Docker Proxy - - http://${SERVER_IP}:19999 # Netdata - -networks: - homelab-network: - external: true - traefik-network: - external: true diff --git a/docker-compose/media-management/docker-compose.yml b/docker-compose/media-management/docker-compose.yml index 1b8f7ba..b7e8948 100644 --- a/docker-compose/media-management/docker-compose.yml +++ b/docker-compose/media-management/docker-compose.yml @@ -17,12 +17,12 @@ services: - '8989:8989' volumes: - ./sonarr/config:/config - - /mnt/media:/media - - /mnt/downloads:/downloads # Large downloads on separate drive + - ${MEDIA_DIR}:/media + - ${DOWNLOADS_DIR}:/downloads # Large downloads on separate drive environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8989/'] interval: 30s @@ -62,12 +62,12 @@ services: - '7878:7878' volumes: - ./radarr/config:/config - - /mnt/media:/media - - /mnt/downloads:/downloads # Large downloads on separate drive + - ${MEDIA_DIR}:/media + - ${DOWNLOADS_DIR}:/downloads # Large downloads on separate drive environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:7878/'] interval: 30s @@ -109,9 +109,9 @@ services: volumes: - ./prowlarr/config:/config environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:9696/'] interval: 30s @@ -151,12 +151,12 @@ services: - '8787:8787' volumes: - ./readarr/config:/config - - /mnt/media/books:/books - - /mnt/downloads:/downloads + - ${MEDIA_DIR}/books:/books + - ${DOWNLOADS_DIR}:/downloads environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -190,12 +190,12 @@ services: - '8686:8686' volumes: - ./lidarr/config:/config - - /mnt/media/music:/music - - /mnt/downloads:/downloads + - ${MEDIA_DIR}/music:/music + - ${DOWNLOADS_DIR}:/downloads environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -229,12 +229,12 @@ services: - '5299:5299' volumes: - ./lazylibrarian/config:/config - - /mnt/media/books:/books - - /mnt/downloads:/downloads + - ${MEDIA_DIR}/books:/books + - ${DOWNLOADS_DIR}:/downloads environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} - DOCKER_MODS=linuxserver/mods:lazylibrarian-ffmpeg labels: # TRAEFIK CONFIGURATION @@ -269,12 +269,12 @@ services: - '8090:8090' volumes: - ./mylar3/config:/config - - /mnt/media/comics:/comics - - /mnt/downloads:/downloads + - ${MEDIA_DIR}/comics:/comics + - ${DOWNLOADS_DIR}:/downloads environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== @@ -310,7 +310,7 @@ services: - ./jellyseerr/config:/app/config environment: - LOG_LEVEL=info - - TZ=America/New_York + - TZ=${TZ} healthcheck: test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:5055/'] interval: 30s @@ -348,7 +348,7 @@ services: - homelab-network environment: - LOG_LEVEL=info - - TZ=America/New_York + - TZ=${TZ} labels: - homelab.category=media - homelab.description=Cloudflare bypass for indexers diff --git a/docker-compose/media-management/docker-compose.yml.template b/docker-compose/media-management/docker-compose.yml.template deleted file mode 100644 index 77a9079..0000000 --- a/docker-compose/media-management/docker-compose.yml.template +++ /dev/null @@ -1,384 +0,0 @@ -# Media Management Services -# Content automation and library management (*arr apps, transcoders, etc.) -# Place in /opt/stacks/media-management/docker-compose.yml - -# RESTART POLICY GUIDE: -# - unless-stopped: Core infrastructure services that should always run -# - no: Services with Sablier lazy loading (start on-demand) -# - See individual service comments for specific reasoning - -services: - # Sonarr - TV show automation - # Access at: https://sonarr.yourdomain.duckdns.org - sonarr: - image: linuxserver/sonarr:4.0.0 - container_name: sonarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8989:8989" - volumes: - - ./sonarr/config:/config - - /mnt/media:/media - - /mnt/downloads:/downloads # Large downloads on separate drive - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8989/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=TV show management and automation" - - "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.sonarr.rule=Host(`sonarr.${DOMAIN}`)" - - "traefik.http.routers.sonarr.entrypoints=websecure" - - "traefik.http.routers.sonarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.sonarr.middlewares=authelia@docker" - - "traefik.http.services.sonarr.loadbalancer.server.port=8989" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Radarr - Movie automation - # Access at: https://radarr.yourdomain.duckdns.org - radarr: - image: linuxserver/radarr:5.2.6 - container_name: radarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "7878:7878" - volumes: - - ./radarr/config:/config - - /mnt/media:/media - - /mnt/downloads:/downloads # Large downloads on separate drive - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:7878/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Movie management and automation" - - "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.radarr.rule=Host(`radarr.${DOMAIN}`)" - - "traefik.http.routers.radarr.entrypoints=websecure" - - "traefik.http.routers.radarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.radarr.middlewares=authelia@docker" - - "traefik.http.services.radarr.loadbalancer.server.port=7878" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Prowlarr - Indexer manager - # Access at: https://prowlarr.yourdomain.duckdns.org - prowlarr: - image: linuxserver/prowlarr:1.11.4 - container_name: prowlarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "9696:9696" - volumes: - - ./prowlarr/config:/config - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9696/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Indexer manager for Sonarr/Radarr" - - "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.prowlarr.rule=Host(`prowlarr.${DOMAIN}`)" - - "traefik.http.routers.prowlarr.entrypoints=websecure" - - "traefik.http.routers.prowlarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.prowlarr.middlewares=authelia@docker" - - "traefik.http.services.prowlarr.loadbalancer.server.port=9696" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Readarr - Ebook and audiobook management - # Access at: https://readarr.${DOMAIN} - readarr: - image: linuxserver/readarr:0.4.19-nightly - container_name: readarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8787:8787" - volumes: - - ./readarr/config:/config - - /mnt/media/books:/books - - /mnt/downloads:/downloads - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Ebook and audiobook management" - - "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.readarr.rule=Host(`readarr.${DOMAIN}`)" - - "traefik.http.routers.readarr.entrypoints=websecure" - - "traefik.http.routers.readarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.readarr.middlewares=authelia@docker" - - "traefik.http.services.readarr.loadbalancer.server.port=8787" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Lidarr - Music collection manager - # Access at: https://lidarr.${DOMAIN} - lidarr: - image: linuxserver/lidarr:2.0.7 - container_name: lidarr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8686:8686" - volumes: - - ./lidarr/config:/config - - /mnt/media/music:/music - - /mnt/downloads:/downloads - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Music collection manager" - - "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.lidarr.rule=Host(`lidarr.${DOMAIN}`)" - - "traefik.http.routers.lidarr.entrypoints=websecure" - - "traefik.http.routers.lidarr.tls.certresolver=letsencrypt" - - "traefik.http.routers.lidarr.middlewares=authelia@docker" - - "traefik.http.services.lidarr.loadbalancer.server.port=8686" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Lazy Librarian - Book manager - # Access at: https://lazylibrarian.${DOMAIN} - lazylibrarian: - image: linuxserver/lazylibrarian:latest - container_name: lazylibrarian - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "5299:5299" - volumes: - - ./lazylibrarian/config:/config - - /mnt/media/books:/books - - /mnt/downloads:/downloads - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - DOCKER_MODS=linuxserver/mods:lazylibrarian-ffmpeg - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Book download automation" - - "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.lazylibrarian.rule=Host(`lazylibrarian.${DOMAIN}`)" - - "traefik.http.routers.lazylibrarian.entrypoints=websecure" - - "traefik.http.routers.lazylibrarian.tls.certresolver=letsencrypt" - - "traefik.http.routers.lazylibrarian.middlewares=authelia@docker" - - "traefik.http.services.lazylibrarian.loadbalancer.server.port=5299" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Mylar3 - Comic book manager - # Access at: https://mylar.${DOMAIN} - mylar3: - image: linuxserver/mylar3:latest - container_name: mylar3 - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8090:8090" - volumes: - - ./mylar3/config:/config - - /mnt/media/comics:/comics - - /mnt/downloads:/downloads - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Comic book collection manager" - - "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.mylar.rule=Host(`mylar.${DOMAIN}`)" - - "traefik.http.routers.mylar.entrypoints=websecure" - - "traefik.http.routers.mylar.tls.certresolver=letsencrypt" - - "traefik.http.routers.mylar.middlewares=authelia@docker" - - "traefik.http.services.mylar.loadbalancer.server.port=8090" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # Jellyseerr - Request management for Jellyfin/Plex - # Access at: https://jellyseerr.${DOMAIN} - jellyseerr: - image: fallenbagel/jellyseerr:latest - container_name: jellyseerr - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "5055:5055" - volumes: - - ./jellyseerr/config:/app/config - environment: - - LOG_LEVEL=info - - TZ=${TZ} - healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5055/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=media" - - "homelab.description=Media request management" - - "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.jellyseerr.rule=Host(`jellyseerr.${DOMAIN}`)" - - "traefik.http.routers.jellyseerr.entrypoints=websecure" - - "traefik.http.routers.jellyseerr.tls.certresolver=letsencrypt" - - "traefik.http.routers.jellyseerr.middlewares=authelia@docker" - - "traefik.http.services.jellyseerr.loadbalancer.server.port=5055" - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - - # FlareSolverr - Cloudflare bypass for Prowlarr - # No web UI - used by Prowlarr - flaresolverr: - image: flaresolverr/flaresolverr:latest - container_name: flaresolverr - restart: unless-stopped - networks: - - homelab-network - environment: - - LOG_LEVEL=info - - TZ=${TZ} - labels: - - homelab.category=media - - homelab.description=Cloudflare bypass for indexers - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-arr" - - "sablier.start-on-demand=true" - -x-dockge: - urls: - - https://sonarr.${DOMAIN} - - http://${SERVER_IP}:8989 - - https://radarr.${DOMAIN} - - http://${SERVER_IP}:7878 - - https://prowlarr.${DOMAIN} - - http://${SERVER_IP}:9696 - - https://readarr.${DOMAIN} - - http://${SERVER_IP}:8787 - - https://lidarr.${DOMAIN} - - http://${SERVER_IP}:8686 - - https://lazylibrarian.${DOMAIN} - - http://${SERVER_IP}:5299 - - https://mylar.${DOMAIN} - - http://${SERVER_IP}:8090 - - https://jellyseerr.${DOMAIN} - - http://${SERVER_IP}:5055 - -networks: - homelab-network: - external: true - traefik-network: - external: true diff --git a/docker-compose/media/docker-compose.yml b/docker-compose/media/docker-compose.yml index c9c3604..5cec789 100644 --- a/docker-compose/media/docker-compose.yml +++ b/docker-compose/media/docker-compose.yml @@ -32,11 +32,11 @@ services: volumes: - ./jellyfin/config:/config - ./jellyfin/cache:/cache - - /mnt/media:/media:ro # Large media files on separate drive + - ${MEDIA_DIR}:/media:ro # Large media files on separate drive environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8096/'] interval: 30s @@ -88,11 +88,11 @@ services: - '8083:8083' volumes: - ./calibre-web/config:/config - - /mnt/media/books:/books + - ${MEDIA_DIR}/books:/books environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PUID} + - TZ=${TZ} - DOCKER_MODS=linuxserver/mods:universal-calibre # TRAEFIK CONFIGURATION labels: diff --git a/docker-compose/media/docker-compose.yml.template b/docker-compose/media/docker-compose.yml.template deleted file mode 100644 index 555b2a8..0000000 --- a/docker-compose/media/docker-compose.yml.template +++ /dev/null @@ -1,139 +0,0 @@ -# Media Services -# 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) -# - See individual service comments for specific reasoning - -# Service Access URLs: -# - Jellyfin: https://jellyfin.${DOMAIN} (no SSO - app access) -# - Plex: https://plex.${DOMAIN} (no SSO - app access) -# - qBittorrent: https://qbit.${DOMAIN} (routed through Gluetun VPN) - -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 5min inactivity - jellyfin: - image: jellyfin/jellyfin:10.8.13 - deploy: - resources: - limits: - cpus: '2.0' - memory: 2G - pids: 2048 - reservations: - cpus: '1.0' - memory: 1G - container_name: jellyfin - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8096:8096" - volumes: - - ./jellyfin/config:/config - - ./jellyfin/cache:/cache - - /mnt/media:/media:ro # Large media files on separate drive - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8096/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - # Uncomment for hardware transcoding - # devices: - # - /dev/dri:/dev/dri - # TRAEFIK CONFIGURATION - labels: - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=media" - - "homelab.description=Open-source media streaming server" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.${DOMAIN}`)" - - "traefik.http.routers.jellyfin.entrypoints=websecure" - - "traefik.http.routers.jellyfin.tls=true" - - "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt" - # Service configuration - - "traefik.http.services.jellyfin.loadbalancer.server.port=8096" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-jellyfin" - - "sablier.start-on-demand=true" - - "sablier.theme=hacker-terminal" - - # Calibre-Web - Ebook reader and server - # Access at: https://calibre.${DOMAIN} - calibre-web: - image: lscr.io/linuxserver/calibre-web:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: calibre-web - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "8083:8083" - volumes: - - ./calibre-web/config:/config - - /mnt/media/books:/books - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - DOCKER_MODS=linuxserver/mods:universal-calibre - # TRAEFIK CONFIGURATION - labels: - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=media" - - "homelab.description=Ebook reader and library management" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.calibre.rule=Host(`calibre.${DOMAIN}`)" - - "traefik.http.routers.calibre.entrypoints=websecure" - - "traefik.http.routers.calibre.tls.certresolver=letsencrypt" - - "traefik.http.routers.calibre.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.calibre.loadbalancer.server.port=8083" - # Sablier configuration (disabled by default) - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-calibre-web" - - "sablier.start-on-demand=true" - -# ========================================== -# DOCKGE URL CONFIGURATION -# ========================================== -x-dockge: - urls: - # Proxied URLs (through Traefik) - - https://jellyfin.${DOMAIN} - - http://${SERVER_IP}:8096 - - https://calibre.${DOMAIN} - - http://${SERVER_IP}:8083 - -networks: - homelab-network: - external: true - traefik-network: - external: true diff --git a/docker-compose/monitoring/docker-compose.yml b/docker-compose/monitoring/docker-compose.yml index 3213f52..bb47ba2 100644 --- a/docker-compose/monitoring/docker-compose.yml +++ b/docker-compose/monitoring/docker-compose.yml @@ -25,8 +25,8 @@ services: ports: - '9090:9090' volumes: - - ./config/prometheus:/etc/prometheus - - prometheus-data:/prometheus + - ./prometheus/config:/etc/prometheus + - ./prometheus/data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' @@ -73,14 +73,14 @@ services: ports: - '3000:3000' volumes: - - grafana-data:/var/lib/grafana - - ./config/grafana/provisioning:/etc/grafana/provisioning + - ./grafana/data:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_ROOT_URL=https://grafana.${DOMAIN} - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel - user: '1000:1000' + user: '${PUID}:${PGID}' depends_on: - prometheus labels: @@ -112,8 +112,8 @@ services: ports: - '9100:9100' volumes: - - /proc:/host/proc:ro - - /sys:/host/sys:ro + - ./node-exporter/proc:/host/proc:ro + - ./node-exporter/sys:/host/sys:ro - /:/rootfs:ro command: - '--path.procfs=/host/proc' @@ -182,7 +182,7 @@ services: ports: - '3001:3001' volumes: - - uptime-kuma-data:/app/data + - ./uptime-kuma:/app/data - /var/run/docker.sock:/var/run/docker.sock:ro labels: # TRAEFIK CONFIGURATION @@ -219,12 +219,11 @@ services: restart: unless-stopped networks: - homelab-network - - traefik-network ports: - '3100:3100' volumes: - - ./config/loki:/etc/loki - - loki-data:/loki + - ./loki/config:/etc/loki + - ./loki/data:/loki command: -config.file=/etc/loki/loki-config.yml labels: # TRAEFIK CONFIGURATION @@ -253,7 +252,7 @@ services: networks: - homelab-network volumes: - - ./config/promtail:/etc/promtail + - ./promtail/config:/etc/promtail - /var/log:/var/log:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro command: -config.file=/etc/promtail/promtail-config.yml @@ -263,16 +262,6 @@ services: - 'homelab.category=monitoring' - 'homelab.description=Log collector for Loki' -volumes: - prometheus-data: - driver: local - grafana-data: - driver: local - uptime-kuma-data: - driver: local - loki-data: - driver: local - networks: homelab-network: external: true diff --git a/docker-compose/monitoring/docker-compose.yml.template b/docker-compose/monitoring/docker-compose.yml.template deleted file mode 100644 index 4b1cb96..0000000 --- a/docker-compose/monitoring/docker-compose.yml.template +++ /dev/null @@ -1,301 +0,0 @@ -# Monitoring and Observability Services -# Services for monitoring your homelab infrastructure -# Place in /opt/stacks/monitoring/docker-compose.yml - -# RESTART POLICY GUIDE: -# - unless-stopped: Core infrastructure services that should always run -# - no: Services with Sablier lazy loading (start on-demand) -# - See individual service comments for specific reasoning - -# Service Access URLs: -# - Prometheus: http://${SERVER_IP}:9090 (or configure Traefik) -# - Grafana: http://${SERVER_IP}:3000 (or configure Traefik) -# - Uptime Kuma: https://status.${DOMAIN} -# - Node Exporter: http://${SERVER_IP}:9100/metrics -# - cAdvisor: http://${SERVER_IP}:8082 -# - Loki: http://${SERVER_IP}:3100 -# NOTE: Prometheus, Grafana, Loki use ports because they need to be accessible to other services -# Add Traefik labels if you want https://prometheus.${DOMAIN} access - -services: - # Prometheus - Metrics collection and storage - # Access at: http://${SERVER_IP}:9090 - prometheus: - image: prom/prometheus:v2.48.1 - deploy: - resources: - limits: - cpus: '0.75' - memory: 512M - pids: 1024 - reservations: - cpus: '0.25' - memory: 256M - container_name: prometheus - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "9090:9090" - volumes: - - ./config/prometheus:/etc/prometheus - - prometheus-data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--storage.tsdb.path=/prometheus' - - '--storage.tsdb.retention.time=30d' - - '--web.console.libraries=/etc/prometheus/console_libraries' - - '--web.console.templates=/etc/prometheus/consoles' - - '--web.enable-lifecycle' - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=monitoring" - - "homelab.description=Metrics collection and time-series database" - # 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.prometheus.rule=Host(`prometheus.${DOMAIN}`)" - - "traefik.http.routers.prometheus.entrypoints=websecure" - - "traefik.http.routers.prometheus.tls=true" - - "traefik.http.routers.prometheus.tls.certresolver=letsencrypt" - - "traefik.http.routers.prometheus.middlewares=authelia@docker" - - "traefik.http.services.prometheus.loadbalancer.server.port=9090" - - # Grafana - Metrics visualization - # Access at: http://${SERVER_IP}:3000 - # Default credentials: admin / admin (change on first login) - grafana: - image: grafana/grafana:10.2.3 - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: grafana - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "3000:3000" - volumes: - - grafana-data:/var/lib/grafana - - ./config/grafana/provisioning:/etc/grafana/provisioning - environment: - - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} - - GF_USERS_ALLOW_SIGN_UP=false - - GF_SERVER_ROOT_URL=https://grafana.${DOMAIN} - - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel - user: "${PUID}:${PGID}" - depends_on: - - prometheus - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=monitoring" - - "homelab.description=Metrics visualization and dashboards" - # 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.grafana.rule=Host(`grafana.${DOMAIN}`)" - - "traefik.http.routers.grafana.entrypoints=websecure" - - "traefik.http.routers.grafana.tls=true" - - "traefik.http.routers.grafana.tls.certresolver=letsencrypt" - - "traefik.http.routers.grafana.middlewares=authelia@docker" - - "traefik.http.services.grafana.loadbalancer.server.port=3000" - - # Node Exporter - Host metrics exporter - # Metrics at: http://${SERVER_IP}:9100/metrics - node-exporter: - image: prom/node-exporter:v1.7.0 - container_name: node-exporter - restart: unless-stopped - networks: - - homelab-network - ports: - - "9100:9100" - volumes: - - /proc:/host/proc:ro - - /sys:/host/sys:ro - - /:/rootfs:ro - command: - - '--path.procfs=/host/proc' - - '--path.rootfs=/rootfs' - - '--path.sysfs=/host/sys' - - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' - labels: - - "homelab.category=monitoring" - - "homelab.description=Hardware and OS metrics exporter" - - # cAdvisor - Container metrics exporter - # Access at: http://${SERVER_IP}:8082 - cadvisor: - image: gcr.io/cadvisor/cadvisor:v0.47.2 - container_name: cadvisor - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "8082:8080" - volumes: - - /:/rootfs:ro - - /var/run:/var/run:ro - - /sys:/sys:ro - - /var/lib/docker:/var/lib/docker:ro - - /dev/disk:/dev/disk:ro - privileged: true - devices: - - /dev/kmsg - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=monitoring" - - "homelab.description=Container metrics and performance monitoring" - # 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.cadvisor.rule=Host(`cadvisor.${DOMAIN}`)" - - "traefik.http.routers.cadvisor.entrypoints=websecure" - - "traefik.http.routers.cadvisor.tls=true" - - "traefik.http.routers.cadvisor.tls.certresolver=letsencrypt" - - "traefik.http.routers.cadvisor.middlewares=authelia@docker" - - "traefik.http.services.cadvisor.loadbalancer.server.port=8080" - - # Uptime Kuma - Uptime monitoring - # Access at: https://uptime-kuma.${DOMAIN} - uptime-kuma: - image: louislam/uptime-kuma:1 - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: uptime-kuma - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "3001:3001" - volumes: - - uptime-kuma-data:/app/data - - /var/run/docker.sock:/var/run/docker.sock:ro - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=monitoring" - - "homelab.description=Service uptime monitoring and alerts" - # 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.uptime-kuma.rule=Host(`uptime-kuma.${DOMAIN}`)" - - "traefik.http.routers.uptime-kuma.entrypoints=websecure" - - "traefik.http.routers.uptime-kuma.tls=true" - - "traefik.http.routers.uptime-kuma.tls.certresolver=letsencrypt" - - "traefik.http.routers.uptime-kuma.middlewares=authelia@docker" - - "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001" - - # Loki - Log aggregation - # Access at: http://${SERVER_IP}:3100 - loki: - image: grafana/loki:2.9.3 - deploy: - resources: - limits: - cpus: '0.75' - memory: 512M - pids: 1024 - reservations: - cpus: '0.25' - memory: 256M - container_name: loki - restart: unless-stopped - networks: - - homelab-network - - traefik-network - ports: - - "3100:3100" - volumes: - - ./config/loki:/etc/loki - - loki-data:/loki - command: -config.file=/etc/loki/loki-config.yml - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=monitoring" - - "homelab.description=Log aggregation system" - # 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.loki.rule=Host(`loki.${DOMAIN}`)" - - "traefik.http.routers.loki.entrypoints=websecure" - - "traefik.http.routers.loki.tls=true" - - "traefik.http.routers.loki.tls.certresolver=letsencrypt" - - "traefik.http.routers.loki.middlewares=authelia@docker" - - "traefik.http.services.loki.loadbalancer.server.port=3100" - - # Promtail - Log shipper for Loki - # Ships Docker container logs to Loki - promtail: - image: grafana/promtail:2.9.3 - container_name: promtail - restart: unless-stopped - networks: - - homelab-network - volumes: - - ./config/promtail:/etc/promtail - - /var/log:/var/log:ro - - /var/lib/docker/containers:/var/lib/docker/containers:ro - command: -config.file=/etc/promtail/promtail-config.yml - depends_on: - - loki - labels: - - "homelab.category=monitoring" - - "homelab.description=Log collector for Loki" - -volumes: - prometheus-data: - driver: local - grafana-data: - driver: local - uptime-kuma-data: - driver: local - loki-data: - driver: local - -networks: - homelab-network: - external: true - traefik-network: - external: true - -x-dockge: - urls: - # Proxied URLs (through Traefik) - - http://${SERVER_IP}:9090 - - http://${SERVER_IP}:3000 - - https://uptime-kuma.${DOMAIN} - - http://${SERVER_IP}:9100/metrics - - http://${SERVER_IP}:8082 - - http://${SERVER_IP}:3100 diff --git a/docker-compose/productivity/docker-compose.yml b/docker-compose/productivity/docker-compose.yml index b2d9c96..21cae44 100644 --- a/docker-compose/productivity/docker-compose.yml +++ b/docker-compose/productivity/docker-compose.yml @@ -28,7 +28,7 @@ services: - '8089:80' volumes: - ./nextcloud/html:/var/www/html - - /mnt/nextcloud-data:/var/www/html/data # Large data on separate drive + - ${NEXTCLOUD_DIR}:/var/www/html/data environment: - MYSQL_HOST=nextcloud-db - MYSQL_DATABASE=nextcloud @@ -75,7 +75,7 @@ services: networks: - homelab-network volumes: - - nextcloud-db-data:/var/lib/mysql + - ./nextcloud/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_DB_ROOT_PASSWORD} - MYSQL_DATABASE=nextcloud @@ -99,9 +99,9 @@ services: volumes: - ./mealie/data:/app/data environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} - BASE_URL=https://mealie.${DOMAIN} - DB_ENGINE=sqlite labels: @@ -176,7 +176,7 @@ services: networks: - homelab-network volumes: - - wordpress-db-data:/var/lib/mysql + - ./wordpress/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${WORDPRESS_DB_ROOT_PASSWORD} - MYSQL_DATABASE=wordpress @@ -210,8 +210,8 @@ services: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro environment: - - USER_UID=1000 - - USER_GID=1000 + - USER_UID=${PUID} + - USER_GID=${PGID} - GITEA__database__DB_TYPE=postgres - GITEA__database__HOST=gitea-db:5432 - GITEA__database__NAME=gitea @@ -252,7 +252,7 @@ services: networks: - homelab-network volumes: - - gitea-db-data:/var/lib/postgresql/data + - ./gitea/db:/var/lib/postgresql/data environment: - POSTGRES_USER=gitea - POSTGRES_PASSWORD=${GITEA_DB_PASSWORD} @@ -309,11 +309,6 @@ services: - 'sablier.group=jasper-jupyter' - 'sablier.start-on-demand=true' -volumes: - nextcloud-db-data: - wordpress-db-data: - gitea-db-data: - networks: homelab-network: external: true diff --git a/docker-compose/productivity/docker-compose.yml.template b/docker-compose/productivity/docker-compose.yml.template deleted file mode 100644 index dcda945..0000000 --- a/docker-compose/productivity/docker-compose.yml.template +++ /dev/null @@ -1,338 +0,0 @@ -# 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) -# - See individual service comments for specific reasoning - -services: - # Nextcloud - File sync and collaboration - # Access at: https://nextcloud.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - nextcloud: - image: nextcloud:28 - deploy: - resources: - limits: - cpus: '1.5' - memory: 1G - pids: 2048 - reservations: - cpus: '0.75' - memory: 512M - container_name: nextcloud - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8089:80" - volumes: - - ./nextcloud/html:/var/www/html - - /mnt/nextcloud-data:/var/www/html/data # Large data on separate drive - environment: - - MYSQL_HOST=nextcloud-db - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD} - - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} - - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.${DOMAIN} - - TRUSTED_PROXIES=172.18.0.0/16 - - OVERWRITEPROTOCOL=https - - OVERWRITEHOST=nextcloud.${DOMAIN} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/status.php"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - nextcloud-db - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=File sync and collaboration" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`)" - - "traefik.http.routers.nextcloud.entrypoints=websecure" - - "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt" - - "traefik.http.routers.nextcloud.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.nextcloud.loadbalancer.server.port=8089" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-nextcloud" - - "sablier.start-on-demand=true" - - nextcloud-db: - image: mariadb:10.11 - container_name: nextcloud-db - restart: no - networks: - - homelab-network - volumes: - - nextcloud-db-data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_DB_ROOT_PASSWORD} - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD} - command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW - labels: - - "homelab.category=productivity" - - "homelab.description=Nextcloud database" - - # Mealie - Recipe manager - # Access at: https://mealie.${DOMAIN} - mealie: - image: ghcr.io/mealie-recipes/mealie:latest - container_name: mealie - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "9000:9000" - volumes: - - ./mealie/data:/app/data - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - BASE_URL=https://mealie.${DOMAIN} - - DB_ENGINE=sqlite - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=Recipe manager and meal planner" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.mealie.rule=Host(`mealie.${DOMAIN}`)" - - "traefik.http.routers.mealie.entrypoints=websecure" - - "traefik.http.routers.mealie.tls.certresolver=letsencrypt" - - "traefik.http.routers.mealie.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.mealie.loadbalancer.server.port=9000" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-mealie" - - "sablier.start-on-demand=true" - - # WordPress - Blog/website platform - # Access at: https://blog.${DOMAIN} - wordpress: - image: wordpress:latest - container_name: wordpress - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8088:80" - volumes: - - ./wordpress/html:/var/www/html - environment: - - WORDPRESS_DB_HOST=wordpress-db - - WORDPRESS_DB_USER=wordpress - - WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD} - - WORDPRESS_DB_NAME=wordpress - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - wordpress-db - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=Blog and website platform" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.wordpress.rule=Host(`wordpress.${DOMAIN}`)" - - "traefik.http.routers.wordpress.entrypoints=websecure" - - "traefik.http.routers.wordpress.tls.certresolver=letsencrypt" - - "traefik.http.routers.wordpress.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.wordpress.loadbalancer.server.port=8088" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-wordpress" - - "sablier.start-on-demand=true" - - wordpress-db: - image: mariadb:10.11 - container_name: wordpress-db - restart: no - networks: - - homelab-network - volumes: - - wordpress-db-data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${WORDPRESS_DB_ROOT_PASSWORD} - - MYSQL_DATABASE=wordpress - - MYSQL_USER=wordpress - - MYSQL_PASSWORD=${WORDPRESS_DB_PASSWORD} - labels: - - "homelab.category=productivity" - - "homelab.description=WordPress database" - - # Gitea - Self-hosted Git service - # Access at: https://git.${DOMAIN} - gitea: - image: gitea/gitea:latest - deploy: - resources: - limits: - cpus: '0.50' - memory: 256M - pids: 512 - reservations: - cpus: '0.25' - memory: 128M - container_name: gitea - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "3010:3000" - volumes: - - ./gitea/data:/data - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - environment: - - USER_UID=${PUID} - - USER_GID=${PGID} - - GITEA__database__DB_TYPE=postgres - - GITEA__database__HOST=gitea-db:5432 - - GITEA__database__NAME=gitea - - GITEA__database__USER=gitea - - GITEA__database__PASSWD=${GITEA_DB_PASSWORD} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - gitea-db - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=productivity" - - "homelab.description=Self-hosted Git service" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.gitea.rule=Host(`gitea.${DOMAIN}`)" - - "traefik.http.routers.gitea.entrypoints=websecure" - - "traefik.http.routers.gitea.tls.certresolver=letsencrypt" - - "traefik.http.routers.gitea.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.gitea.loadbalancer.server.port=3010" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-gitea" - - "sablier.start-on-demand=true" - - gitea-db: - image: postgres:14-alpine - container_name: gitea-db - restart: no - networks: - - homelab-network - volumes: - - gitea-db-data:/var/lib/postgresql/data - environment: - - POSTGRES_USER=gitea - - POSTGRES_PASSWORD=${GITEA_DB_PASSWORD} - - POSTGRES_DB=gitea - labels: - - "homelab.category=productivity" - - "homelab.description=Gitea database" - - - # Jupyter Lab - Interactive computing notebooks - # Access at: https://jupyter.${DOMAIN} - # Token displayed in logs on first start - jupyter: - image: jupyter/scipy-notebook:latest - container_name: jupyter - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8890:8888" - volumes: - - ./config/jupyter:/home/jovyan/work - environment: - - JUPYTER_ENABLE_LAB=yes - - GRANT_SUDO=yes - user: root - command: start-notebook.sh --NotebookApp.token='${JUPYTER_TOKEN}' - # Uncomment for GPU support (NVIDIA, requires nvidia-container-toolkit) - # runtime: nvidia - # devices: - # - /dev/nvidia0:/dev/nvidia0 - # - /dev/nvidiactl:/dev/nvidiactl - # Add these to environment above: - # - NVIDIA_VISIBLE_DEVICES=all - # - NVIDIA_DRIVER_CAPABILITIES=compute,utility - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=productivity" - - "homelab.description=Jupyter Lab for data science and ML" - # 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.jupyter.rule=Host(`jupyter.${DOMAIN}`)" - - "traefik.http.routers.jupyter.entrypoints=websecure" - - "traefik.http.routers.jupyter.tls.certresolver=letsencrypt" - - "traefik.http.routers.jupyter.middlewares=authelia@docker" - - "traefik.http.services.jupyter.loadbalancer.server.port=8890" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-jupyter" - - "sablier.start-on-demand=true" - -volumes: - nextcloud-db-data: - wordpress-db-data: - gitea-db-data: - -networks: - homelab-network: - external: true - traefik-network: - external: true - -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/transcoders/docker-compose.yml b/docker-compose/transcoders/docker-compose.yml index 704d3eb..d0055f4 100644 --- a/docker-compose/transcoders/docker-compose.yml +++ b/docker-compose/transcoders/docker-compose.yml @@ -20,12 +20,12 @@ services: - ./tdarr/server:/app/server - ./tdarr/configs:/app/configs - ./tdarr/logs:/app/logs - - /mnt/media:/media - - /mnt/tdarr-transcode:/temp # Transcode cache on separate drive + - ${MEDIA_DIR}:/media + - ${TDARR_TRANSCODE_DIR}:/temp # Transcode cache on separate drive environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} - serverIP=0.0.0.0 - serverPort=8266 - webUIPort=8265 @@ -61,12 +61,12 @@ services: volumes: - ./tdarr/configs:/app/configs - ./tdarr/logs:/app/logs - - /mnt/media:/media - - /mnt/tdarr-transcode:/temp + - ${MEDIA_DIR}:/media + - ${TDARR_TRANSCODE_DIR}:/temp environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} - nodeID=MainNode - nodeIP=0.0.0.0 - nodePort=8267 @@ -91,12 +91,12 @@ services: - '8889:8888' volumes: - ./unmanic/config:/config - - /mnt/media:/library - - /mnt/unmanic-cache:/tmp/unmanic # Transcode cache on separate drive + - ${MEDIA_DIR}:/library + - ${UNMANIC_TRANSCODE_DIR}:/tmp/unmanic # Transcode cache on separate drive environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # ========================================== diff --git a/docker-compose/transcoders/docker-compose.yml.template b/docker-compose/transcoders/docker-compose.yml.template deleted file mode 100644 index d82f889..0000000 --- a/docker-compose/transcoders/docker-compose.yml.template +++ /dev/null @@ -1,126 +0,0 @@ -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 456477e..b601771 100644 --- a/docker-compose/utilities/docker-compose.yml +++ b/docker-compose/utilities/docker-compose.yml @@ -19,13 +19,13 @@ services: volumes: - ./backrest/data:/data - ./backrest/config:/config - - /opt/stacks:/opt/stacks:ro # Backup source + - ${STACKS_DIR}:${STACKS_DIR}:ro # Backup source - /mnt:/mnt:ro # Backup additional drives - - backrest-cache:/cache + - ./backrest/cache:/cache environment: - BACKREST_DATA=/data - BACKREST_CONFIG=/config/config.json - - TZ=America/New_York + - TZ=${TZ} healthcheck: test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:9898/'] interval: 30s @@ -64,13 +64,13 @@ services: - '8200:8200' volumes: - ./duplicati/config:/config - - /opt/stacks:/source/stacks:ro + - ${STACKS_DIR}:${STACKS_DIR}:ro - /mnt:/source/mnt:ro - /mnt/backups:/backups environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8200/'] interval: 30s @@ -151,7 +151,7 @@ services: - 'homelab.category=utilities' - 'homelab.description=Form.io database' - # Bitwarden (Vaultwarden) - Password manager + # Vaultwarden - Password manager # Note: SSO disabled for browser extension and mobile app compatibility vaultwarden: @@ -205,25 +205,8 @@ services: - 'sablier.group=jasper-vaultwarden' - 'sablier.start-on-demand=true' - # Authelia Redis - Session storage for Authelia - # No web UI - backend service -# authelia-redis: -# image: redis:7-alpine -# container_name: authelia-redis -# restart: unless-stopped -# networks: -# - homelab-network -# volumes: -# - authelia-redis-data:/data -# command: redis-server --save 60 1 --loglevel warning -# 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: diff --git a/docker-compose/utilities/docker-compose.yml.template b/docker-compose/utilities/docker-compose.yml.template deleted file mode 100644 index d1cfd33..0000000 --- a/docker-compose/utilities/docker-compose.yml.template +++ /dev/null @@ -1,246 +0,0 @@ -# Backup and Utility Services -# Place in /opt/stacks/utilities/docker-compose.yml - -# RESTART POLICY GUIDE: -# - unless-stopped: Core infrastructure services that should always run -# - no: Services with Sablier lazy loading (start on-demand) -# - See individual service comments for specific reasoning - -services: - # Backrest - Backup solution for restic - # Access at: https://backrest.${DOMAIN} - # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity - backrest: - image: garethgeorge/backrest:latest - container_name: backrest - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "9898:9898" - volumes: - - ./backrest/data:/data - - ./backrest/config:/config - - /opt/stacks:/opt/stacks:ro # Backup source - - /mnt:/mnt:ro # Backup additional drives - - backrest-cache:/cache - environment: - - BACKREST_DATA=/data - - BACKREST_CONFIG=/config/config.json - - TZ=${TZ} - healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9898/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=utilities" - - "homelab.description=Backup management with restic" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.backrest.rule=Host(`backrest.${DOMAIN}`)" - - "traefik.http.routers.backrest.entrypoints=websecure" - - "traefik.http.routers.backrest.tls.certresolver=letsencrypt" - - "traefik.http.routers.backrest.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.backrest.loadbalancer.server.port=9898" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-backrest" - - "sablier.start-on-demand=true" - - # Duplicati - Backup solution - # Access at: https://duplicati.${DOMAIN} - duplicati: - image: lscr.io/linuxserver/duplicati:2.0.7 - container_name: duplicati - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8200:8200" - volumes: - - ./duplicati/config:/config - - /opt/stacks:/source/stacks:ro - - /mnt:/source/mnt:ro - - /mnt/backups:/backups - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8200/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - labels: - # TRAEFIK CONFIGURATION - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=utilities" - - "homelab.description=Backup software with encryption" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.duplicati.rule=Host(`duplicati.${DOMAIN}`)" - - "traefik.http.routers.duplicati.entrypoints=websecure" - - "traefik.http.routers.duplicati.tls.certresolver=letsencrypt" - - "traefik.http.routers.duplicati.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.duplicati.loadbalancer.server.port=8200" - # Sablier configuration - - "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: - image: calipseo/formio:latest - container_name: formio - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "3002:3001" - environment: - - MONGO=mongodb://formio-mongo:27017/formio - - JWT_SECRET=${FORMIO_JWT_SECRET} - - DB_SECRET=${FORMIO_DB_SECRET} - healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - depends_on: - - formio-mongo - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=utilities" - - "homelab.description=Form builder platform" - # Traefik labels - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.formio.rule=Host(`forms.${DOMAIN}`)" - - "traefik.http.routers.formio.entrypoints=websecure" - - "traefik.http.routers.formio.tls.certresolver=letsencrypt" - - "traefik.http.routers.formio.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.formio.loadbalancer.server.port=3001" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-formio" - - "sablier.start-on-demand=true" - - formio-mongo: - image: mongo:4.4 - container_name: formio-mongo - restart: unless-stopped - networks: - - homelab-network - labels: - - "homelab.category=utilities" - - "homelab.description=Form.io database" - - # 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 - restart: no - networks: - - homelab-network - - traefik-network - ports: - - "8091:80" - volumes: - - ./vaultwarden/data:/data - environment: - - DOMAIN=https://vault.${DOMAIN} - - SIGNUPS_ALLOWED=${BITWARDEN_SIGNUPS_ALLOWED} - - INVITATIONS_ALLOWED=${BITWARDEN_INVITATIONS_ALLOWED} - - ADMIN_TOKEN=${BITWARDEN_ADMIN_TOKEN} - # SMTP disabled - uncomment and configure to enable email - # - SMTP_HOST=${SMTP_HOST} - # - SMTP_FROM=${SMTP_FROM} - # - SMTP_PORT=${SMTP_PORT} - # - SMTP_SECURITY=${SMTP_SECURITY} - # - SMTP_USERNAME=${SMTP_USERNAME} - # - SMTP_PASSWORD=${SMTP_PASSWORD} - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:80/"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - labels: - # TRAEFIK CONFIGURATION - # ========================================== - # Service metadata - - "homelab.category=utilities" - - "homelab.description=Self-hosted password manager (Bitwarden)" - # 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.vaultwarden.rule=Host(`vault.${DOMAIN}`)" - - "traefik.http.routers.vaultwarden.entrypoints=websecure" - - "traefik.http.routers.vaultwarden.tls=true" - - "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt" - # SSO disabled for browser extension and mobile app compatibility - # - "traefik.http.routers.vaultwarden.middlewares=authelia@docker" - - "traefik.http.services.vaultwarden.loadbalancer.server.port=80" - # Sablier configuration - - "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: -# image: redis:7-alpine -# container_name: authelia-redis -# restart: unless-stopped -# networks: -# - homelab-network -# volumes: -# - authelia-redis-data:/data -# command: redis-server --save 60 1 --loglevel warning -# 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 cab6c23..e957423 100644 --- a/docker-compose/vpn/docker-compose.yml +++ b/docker-compose/vpn/docker-compose.yml @@ -33,7 +33,7 @@ services: - OPENVPN_USER=${SURFSHARK_USERNAME} - OPENVPN_PASSWORD=${SURFSHARK_PASSWORD} - SERVER_COUNTRIES=${VPN_SERVER_COUNTRIES} - - TZ=America/New_York + - TZ=${TZ} # TRAEFIK CONFIGURATION labels: # Service metadata @@ -43,7 +43,7 @@ services: - 'traefik.enable=true' - 'traefik.docker.network=traefik-network' # Router configuration - - 'traefik.http.routers.qbittorrent.rule=Host(`qbit.${DOMAIN}`)' + - 'traefik.http.routers.qbittorrent.rule=Host(`qbittorrent.${DOMAIN}`)' - 'traefik.http.routers.qbittorrent.entrypoints=websecure' - 'traefik.http.routers.qbittorrent.tls=true' - 'traefik.http.routers.qbittorrent.middlewares=authelia@docker' @@ -71,11 +71,11 @@ services: network_mode: 'service:gluetun' # Routes through VPN in same compose file volumes: - ./qbittorrent/config:/config - - /mnt/downloads:/downloads + - ${DOWNLOADS_DIR}:/downloads environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} - WEBUI_PORT=8080 depends_on: - gluetun @@ -88,5 +88,5 @@ networks: x-dockge: urls: - - https://qbit.${DOMAIN} + - https://qbittorrent.${DOMAIN} - https://192.168.4.4:8081 \ No newline at end of file diff --git a/docker-compose/vpn/docker-compose.yml.template b/docker-compose/vpn/docker-compose.yml.template deleted file mode 100644 index 44183f5..0000000 --- a/docker-compose/vpn/docker-compose.yml.template +++ /dev/null @@ -1,96 +0,0 @@ -# VPN Stack -# VPN client and VPN-routed download clients -# Place in /opt/stacks/vpn/docker-compose.yml - -# RESTART POLICY GUIDE: -# - unless-stopped: Core infrastructure services that should always run -# - no: Services with Sablier lazy loading (start on-demand) -# - See individual service comments for specific reasoning - -services: - # Gluetun - VPN client (Surfshark) - # Routes download clients through VPN for security - # VPN service should always run to maintain secure connections - gluetun: - image: qmcgaw/gluetun:latest - container_name: gluetun - restart: unless-stopped - cap_add: - - NET_ADMIN - devices: - - /dev/net/tun:/dev/net/tun - networks: - - homelab-network - - traefik-network - ports: - - "8888:8888/tcp" # HTTP proxy - - "8388:8388/tcp" # Shadowsocks - - "8388:8388/udp" # Shadowsocks - - "8081:8080" # qBittorrent web UI - - "6881:6881" # qBittorrent - - "6881:6881/udp" # qBittorrent - volumes: - - ./gluetun:/gluetun - environment: - - VPN_SERVICE_PROVIDER=surfshark - - VPN_TYPE=openvpn - - OPENVPN_USER=${SURFSHARK_USERNAME} - - OPENVPN_PASSWORD=${SURFSHARK_PASSWORD} - - SERVER_COUNTRIES=${VPN_SERVER_COUNTRIES} - - TZ=${TZ} - # TRAEFIK CONFIGURATION - labels: - # Service metadata - - "com.centurylinklabs.watchtower.enable=true" - - "homelab.category=downloaders" - - "homelab.description=VPN client for secure downloads" - - "traefik.enable=true" - # Router configuration - - "traefik.http.routers.qbittorrent.rule=Host(`qbit.${DOMAIN}`)" - - "traefik.http.routers.qbittorrent.entrypoints=websecure" - - "traefik.http.routers.qbittorrent.tls=true" - - "traefik.http.routers.qbittorrent.middlewares=authelia@docker" - # Service configuration - - "traefik.http.services.qbittorrent.loadbalancer.server.port=8081" - # Sablier configuration - - "sablier.enable=true" - - "sablier.group=${SERVER_HOSTNAME}-qbittorrent" - - "sablier.sessionDuration=1h" - - # qBittorrent - Torrent client - # Routes through Gluetun VPN - qbittorrent: - image: lscr.io/linuxserver/qbittorrent:latest - deploy: - resources: - limits: - cpus: '1.0' - memory: 512M - pids: 1024 - reservations: - cpus: '0.50' - memory: 256M - container_name: qbittorrent - restart: unless-stopped - network_mode: "service:gluetun" # Routes through VPN in same compose file - volumes: - - ./qbittorrent/config:/config - - /mnt/downloads:/downloads - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - WEBUI_PORT=8080 - depends_on: - - gluetun - -networks: - homelab-network: - external: true - traefik-network: - 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.yml b/docker-compose/wikis/docker-compose.yml index 8063726..282044f 100644 --- a/docker-compose/wikis/docker-compose.yml +++ b/docker-compose/wikis/docker-compose.yml @@ -19,9 +19,9 @@ services: volumes: - ./dokuwiki/config:/config environment: - - PUID=1000 - - PGID=1000 - - TZ=America/New_York + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} labels: # TRAEFIK CONFIGURATION # Service metadata @@ -56,8 +56,8 @@ services: volumes: - ./bookstack/config:/config environment: - - PUID=1000 - - PGID=1000 + - PUID=${PUID} + - PGID=${PGID} - APP_URL=https://bookstack.${DOMAIN} - DB_HOST=bookstack-db - DB_PORT=3306 @@ -100,7 +100,7 @@ services: networks: - homelab-network volumes: - - bookstack-db-data:/var/lib/mysql + - ./bookstack/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${BOOKSTACK_DB_ROOT_PASSWORD} - MYSQL_DATABASE=bookstack @@ -163,7 +163,7 @@ services: networks: - homelab-network volumes: - - mediawiki-db-data:/var/lib/mysql + - ./mediawiki/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MEDIAWIKI_DB_ROOT_PASSWORD} - MYSQL_DATABASE=mediawiki @@ -173,10 +173,6 @@ services: - 'homelab.category=productivity' - 'homelab.description=MediaWiki database' -volumes: - bookstack-db-data: - mediawiki-db-data: - networks: homelab-network: external: true diff --git a/docker-compose/wikis/docker-compose.yml.template b/docker-compose/wikis/docker-compose.yml.template deleted file mode 100644 index 3693699..0000000 --- a/docker-compose/wikis/docker-compose.yml.template +++ /dev/null @@ -1,188 +0,0 @@ -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