Refactor docker-compose configurations and add new services
- Reorganize Authelia configuration files - Add new dynamic routing files for Traefik - Update various service docker-compose files - Remove outdated templates and scripts
This commit is contained in:
@@ -16,7 +16,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- '9000:9000'
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- portainer-data:/data
|
||||
@@ -26,15 +26,15 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=Docker container management UI (Alternative to Dockge)"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'traefik.http.routers.portainer.rule=Host(`portainer.${DOMAIN}`)"
|
||||
- 'traefik.http.routers.portainer.entrypoints=websecure"
|
||||
- 'traefik.http.routers.portainer.tls.certresolver=letsencrypt"
|
||||
- 'traefik.http.routers.portainer.middlewares=authelia@docker"
|
||||
- 'traefik.http.services.portainer.loadbalancer.server.port=9000"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=Docker container management UI (Alternative to Dockge)'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- 'traefik.http.routers.portainer.rule=Host(`portainer.${DOMAIN}`)'
|
||||
- 'traefik.http.routers.portainer.entrypoints=websecure'
|
||||
- 'traefik.http.routers.portainer.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.portainer.middlewares=authelia@docker'
|
||||
- 'traefik.http.services.portainer.loadbalancer.server.port=9000'
|
||||
|
||||
# Authentik - Alternative SSO/Identity Provider with Web UI
|
||||
# Access at: https://authentik.${DOMAIN}
|
||||
@@ -50,7 +50,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- '9000:9000'
|
||||
volumes:
|
||||
- /opt/stacks/authentik/media:/media
|
||||
- /opt/stacks/authentik/custom-templates:/templates
|
||||
@@ -66,15 +66,15 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=SSO/Identity provider with web UI (Alternative to Authelia)"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'traefik.http.routers.authentik.rule=Host(`authentik.${DOMAIN}`)"
|
||||
- 'traefik.http.routers.authentik.entrypoints=websecure"
|
||||
- 'traefik.http.routers.authentik.tls.certresolver=letsencrypt"
|
||||
- 'traefik.http.routers.authentik.middlewares=authelia@docker"
|
||||
- 'traefik.http.services.authentik.loadbalancer.server.port=9000"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=SSO/Identity provider with web UI (Alternative to Authelia)'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- 'traefik.http.routers.authentik.rule=Host(`authentik.${DOMAIN}`)'
|
||||
- 'traefik.http.routers.authentik.entrypoints=websecure'
|
||||
- 'traefik.http.routers.authentik.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.authentik.middlewares=authelia@docker'
|
||||
- 'traefik.http.services.authentik.loadbalancer.server.port=9000'
|
||||
depends_on:
|
||||
- authentik-db
|
||||
- authentik-redis
|
||||
@@ -104,8 +104,8 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=Authentik background worker"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=Authentik background worker'
|
||||
depends_on:
|
||||
- authentik-db
|
||||
- authentik-redis
|
||||
@@ -128,10 +128,10 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=Authentik database"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=Authentik database'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${AUTHENTIK_DB_USER}"]
|
||||
test: ['CMD-SHELL', 'pg_isready -U ${AUTHENTIK_DB_USER}']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
@@ -151,10 +151,10 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=Authentik cache and messaging"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=Authentik cache and messaging'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||
test: ['CMD-SHELL', 'redis-cli ping | grep PONG']
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
@@ -170,7 +170,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "32400:32400"
|
||||
- '32400:32400'
|
||||
volumes:
|
||||
- ./plex/config:/config
|
||||
- /mnt/media:/media:ro # Large media files on separate drive
|
||||
@@ -202,17 +202,17 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=alternatives"
|
||||
- 'homelab.description=Alternative media streaming server to Jellyfin"
|
||||
- 'homelab.category=alternatives'
|
||||
- 'homelab.description=Alternative media streaming server to Jellyfin'
|
||||
# Traefik labels - NO Authelia for app access
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'traefik.http.routers.plex.rule=Host(`plex.${DOMAIN}`)"
|
||||
- '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}"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- 'traefik.http.routers.plex.rule=Host(`plex.${DOMAIN}`)'
|
||||
- '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:
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
# Alternative Services Stack
|
||||
# This stack contains alternative/optional services that are not deployed by default
|
||||
# Deploy manually through Dockge if you want to use these alternatives
|
||||
# Place in /opt/stacks/alternatives/docker-compose.yml
|
||||
|
||||
# RESTART POLICY GUIDE:
|
||||
# - unless-stopped: Core infrastructure services that should always run
|
||||
# - no: Services with Sablier lazy loading (start on-demand)
|
||||
# - See individual service comments for specific reasoning
|
||||
|
||||
services:
|
||||
# Portainer - Docker management UI (Alternative to Dockge)
|
||||
# Access at: https://portainer.${DOMAIN}
|
||||
# NOTE: Dockge is the default Docker management UI. Deploy Portainer only if you prefer its interface
|
||||
# Docker management interface should always run when deployed
|
||||
portainer:
|
||||
image: portainer/portainer-ce:2.19.4
|
||||
container_name: portainer
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9000:9000"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- portainer-data:/data
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=Docker container management UI (Alternative to Dockge)"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.portainer.rule=Host(`portainer.${DOMAIN}`)"
|
||||
- "traefik.http.routers.portainer.entrypoints=websecure"
|
||||
- "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.portainer.middlewares=authelia@docker"
|
||||
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
|
||||
|
||||
# Authentik - Alternative SSO/Identity Provider with Web UI
|
||||
# Access at: https://authentik.${DOMAIN}
|
||||
# NOTE: Authelia is the default SSO. Deploy Authentik only if you need a web UI for user management
|
||||
# WARNING: Do not run both Authelia and Authentik at the same time
|
||||
# SSO service should always run when deployed as alternative to Authelia
|
||||
authentik-server:
|
||||
image: ghcr.io/goauthentik/server:2024.2.0
|
||||
container_name: authentik-server
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
networks:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9000:9000"
|
||||
volumes:
|
||||
- /opt/stacks/authentik/media:/media
|
||||
- /opt/stacks/authentik/custom-templates:/templates
|
||||
environment:
|
||||
- AUTHENTIK_REDIS__HOST=authentik-redis
|
||||
- AUTHENTIK_POSTGRESQL__HOST=authentik-db
|
||||
- AUTHENTIK_POSTGRESQL__USER=${AUTHENTIK_DB_USER}
|
||||
- AUTHENTIK_POSTGRESQL__NAME=${AUTHENTIK_DB_NAME}
|
||||
- AUTHENTIK_POSTGRESQL__PASSWORD=${AUTHENTIK_DB_PASSWORD}
|
||||
- AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
|
||||
- AUTHENTIK_ERROR_REPORTING__ENABLED=false
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=SSO/Identity provider with web UI (Alternative to Authelia)"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.authentik.rule=Host(`authentik.${DOMAIN}`)"
|
||||
- "traefik.http.routers.authentik.entrypoints=websecure"
|
||||
- "traefik.http.routers.authentik.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.authentik.middlewares=authelia@docker"
|
||||
- "traefik.http.services.authentik.loadbalancer.server.port=9000"
|
||||
depends_on:
|
||||
- authentik-db
|
||||
- authentik-redis
|
||||
|
||||
# Authentik Worker - Background task processor
|
||||
# SSO background worker should always run when Authentik is deployed
|
||||
authentik-worker:
|
||||
image: ghcr.io/goauthentik/server:2024.2.0
|
||||
container_name: authentik-worker
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
networks:
|
||||
- homelab-network
|
||||
volumes:
|
||||
- /opt/stacks/authentik/media:/media
|
||||
- /opt/stacks/authentik/certs:/certs
|
||||
- /opt/stacks/authentik/custom-templates:/templates
|
||||
environment:
|
||||
- AUTHENTIK_REDIS__HOST=authentik-redis
|
||||
- AUTHENTIK_POSTGRESQL__HOST=authentik-db
|
||||
- AUTHENTIK_POSTGRESQL__USER=${AUTHENTIK_DB_USER}
|
||||
- AUTHENTIK_POSTGRESQL__NAME=${AUTHENTIK_DB_NAME}
|
||||
- AUTHENTIK_POSTGRESQL__PASSWORD=${AUTHENTIK_DB_PASSWORD}
|
||||
- AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
|
||||
- AUTHENTIK_ERROR_REPORTING__ENABLED=false
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=Authentik background worker"
|
||||
depends_on:
|
||||
- authentik-db
|
||||
- authentik-redis
|
||||
|
||||
# Authentik Database - PostgreSQL
|
||||
# Database must always run for Authentik to function
|
||||
authentik-db:
|
||||
image: postgres:16-alpine
|
||||
container_name: authentik-db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab-network
|
||||
volumes:
|
||||
- authentik-db-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=${AUTHENTIK_DB_USER}
|
||||
- POSTGRES_PASSWORD=${AUTHENTIK_DB_PASSWORD}
|
||||
- POSTGRES_DB=${AUTHENTIK_DB_NAME}
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=Authentik database"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${AUTHENTIK_DB_USER}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Authentik Redis - Cache and message queue
|
||||
# Cache service must always run for Authentik performance
|
||||
authentik-redis:
|
||||
image: redis:7-alpine
|
||||
container_name: authentik-redis
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab-network
|
||||
volumes:
|
||||
- authentik-redis-data:/data
|
||||
command: --save 60 1 --loglevel warning
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=Authentik cache and messaging"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
|
||||
# Plex Media Server - Alternative to Jellyfin
|
||||
# Access at: https://plex.yourdomain.duckdns.org
|
||||
# NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc.
|
||||
# Media server should always run when deployed as alternative to Jellyfin
|
||||
plex:
|
||||
image: plexinc/pms-docker:1.40.0.7998-f68041501
|
||||
container_name: plex
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab-network
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "32400:32400"
|
||||
volumes:
|
||||
- ./plex/config:/config
|
||||
- /mnt/media:/media:ro # Large media files on separate drive
|
||||
- plex-transcode:/transcode
|
||||
environment:
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- TZ=${TZ}
|
||||
- PLEX_CLAIM=${PLEX_CLAIM}
|
||||
# Hardware transcoding support
|
||||
# Uncomment ONE of the following options:
|
||||
|
||||
# Option 1: Intel QuickSync (most common)
|
||||
# devices:
|
||||
# - /dev/dri:/dev/dri
|
||||
|
||||
# Option 2: NVIDIA GPU (requires nvidia-container-toolkit installed)
|
||||
# runtime: nvidia
|
||||
# devices:
|
||||
# - /dev/nvidia0:/dev/nvidia0
|
||||
# - /dev/nvidiactl:/dev/nvidiactl
|
||||
# - /dev/nvidia-modeset:/dev/nvidia-modeset
|
||||
# - /dev/nvidia-uvm:/dev/nvidia-uvm
|
||||
# - /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
|
||||
# environment:
|
||||
# - NVIDIA_VISIBLE_DEVICES=all
|
||||
# - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=alternatives"
|
||||
- "homelab.description=Alternative media streaming server to Jellyfin"
|
||||
# Traefik labels - NO Authelia for app access
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.plex.rule=Host(`plex.${DOMAIN}`)"
|
||||
- "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:
|
||||
external: true
|
||||
traefik-network:
|
||||
external: true
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# Environment Variables Template for Core Services
|
||||
# Copy this file to .env and fill in your values
|
||||
|
||||
# User and Group IDs for file permissions (get with: id -u and id -g)
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
|
||||
TZ=America/New_York
|
||||
|
||||
SERVER_IP=192.168.1.100
|
||||
SERVER_HOSTNAME=your-server-name
|
||||
|
||||
# Domain & DuckDNS Configuration
|
||||
DUCKDNS_SUBDOMAINS=your-subdomain # Without .duckdns.org
|
||||
DOMAIN=your-subdomain.duckdns.org
|
||||
DUCKDNS_TOKEN=your-duckdns-token-here
|
||||
|
||||
# Default credentials (used by multiple services for easier setup)
|
||||
DEFAULT_USER=admin
|
||||
DEFAULT_PASSWORD=change-this-password
|
||||
|
||||
# Authelia Configuration
|
||||
AUTHELIA_JWT_SECRET=your-jwt-secret-here
|
||||
AUTHELIA_SESSION_SECRET=your-session-secret-here
|
||||
AUTHELIA_STORAGE_ENCRYPTION_KEY=your-encryption-key-here
|
||||
|
||||
# Let's Encrypt Configuration
|
||||
ACME_EMAIL=your-email@example.com
|
||||
@@ -1,6 +1,6 @@
|
||||
# Authelia Configuration
|
||||
# Copy to /opt/stacks/authelia/configuration.yml
|
||||
# IMPORTANT: Replace 'kelinreij.duckdns.org' with your actual DuckDNS domain
|
||||
# IMPORTANT: Replace 'your-domain.duckdns.org' with your actual DuckDNS domain
|
||||
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
@@ -11,18 +11,18 @@ log:
|
||||
|
||||
theme: dark
|
||||
|
||||
jwt_secret: generate-with-openssl-rand-hex-64
|
||||
jwt_secret: ${AUTHELIA_JWT_SECRET}
|
||||
|
||||
default_redirection_url: https://auth.kelinreij.duckdns.org
|
||||
default_redirection_url: https://auth.${DOMAIN}
|
||||
|
||||
totp:
|
||||
issuer: kelinreij.duckdns.org
|
||||
issuer: ${DOMAIN}
|
||||
period: 30
|
||||
skew: 1
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
path: /secrets/users_database.yml
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
@@ -36,40 +36,34 @@ access_control:
|
||||
|
||||
rules:
|
||||
# Bypass Authelia for Jellyfin (allow app access)
|
||||
- domain: jellyfin.kelinreij.duckdns.org
|
||||
- domain: jellyfin.${DOMAIN}
|
||||
policy: bypass
|
||||
|
||||
# Bypass for Plex (allow app access)
|
||||
- domain: plex.kelinreij.duckdns.org
|
||||
- domain: plex.${DOMAIN}
|
||||
policy: bypass
|
||||
|
||||
# Bypass for Home Assistant (has its own auth)
|
||||
- domain: ha.kelinreij.duckdns.org
|
||||
policy: bypass
|
||||
|
||||
# Bypass for development services (they have their own auth or setup)
|
||||
- domain: pgadmin.kelinreij.duckdns.org
|
||||
policy: bypass
|
||||
- domain: gitlab.kelinreij.duckdns.org
|
||||
- domain: ha.${DOMAIN}
|
||||
policy: bypass
|
||||
|
||||
# Protected: All other services require authentication
|
||||
- domain: "*.kelinreij.duckdns.org"
|
||||
- domain: "*.${DOMAIN}"
|
||||
policy: one_factor
|
||||
|
||||
# Two-factor for admin services (optional)
|
||||
# - domain:
|
||||
# - "admin.kelinreij.duckdns.org"
|
||||
# - "portainer.kelinreij.duckdns.org"
|
||||
# - "admin.${DOMAIN}"
|
||||
# - "portainer.${DOMAIN}"
|
||||
# policy: two_factor
|
||||
|
||||
session:
|
||||
name: authelia_session
|
||||
secret: generate-with-openssl-rand-hex-64
|
||||
secret: ${AUTHELIA_SESSION_SECRET}
|
||||
expiration: 24h # Session expires after 24 hours
|
||||
inactivity: 24h # Session expires after 24 hours of inactivity
|
||||
remember_me_duration: 1M
|
||||
domain: kelinreij.duckdns.org
|
||||
domain: ${DOMAIN}
|
||||
|
||||
regulation:
|
||||
max_retries: 3
|
||||
@@ -77,11 +71,11 @@ regulation:
|
||||
ban_time: 5m
|
||||
|
||||
storage:
|
||||
encryption_key: generate-with-openssl-rand-hex-64
|
||||
encryption_key: ${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
||||
local:
|
||||
path: /data/db.sqlite3
|
||||
path: /config/db.sqlite3
|
||||
|
||||
notifier:
|
||||
# File-based notifications (for development/testing)
|
||||
filesystem:
|
||||
filename: /data/notification.txt
|
||||
filename: /config/notification.txt
|
||||
20
docker-compose/core/authelia/config/users_database.yml
Normal file
20
docker-compose/core/authelia/config/users_database.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
# Authelia Users Database
|
||||
# Copy to /opt/stacks/authelia/users_database.yml
|
||||
# Generate password hashes with: docker run authelia/authelia:latest authelia crypto hash generate argon2 --password 'yourpassword'
|
||||
|
||||
users:
|
||||
${AUTHELIA_ADMIN_USER}:
|
||||
displayname: ${AUTHELIA_ADMIN_USER}
|
||||
password: "${AUTHELIA_ADMIN_PASSWORD_HASH}"
|
||||
email: ${AUTHELIA_ADMIN_EMAIL}
|
||||
groups:
|
||||
- admins
|
||||
- users
|
||||
|
||||
# Example: Additional user
|
||||
# user1:
|
||||
# displayname: "User One"
|
||||
# password: "$argon2id$v=19$m=65536,t=3,p=4$CHANGEME"
|
||||
# email: user1@example.com
|
||||
# groups:
|
||||
# - users
|
||||
@@ -10,4 +10,3 @@ users:
|
||||
groups:
|
||||
- admins
|
||||
- users
|
||||
- users
|
||||
@@ -1,12 +0,0 @@
|
||||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
|
||||
users:
|
||||
${DEFAULT_USER}:
|
||||
displayname: "Admin User"
|
||||
password: "${AUTHELIA_ADMIN_PASSWORD_HASH}"
|
||||
email: ${DEFAULT_EMAIL}
|
||||
groups:
|
||||
- admins
|
||||
- users
|
||||
@@ -56,7 +56,7 @@ services:
|
||||
|
||||
authelia:
|
||||
# Single sign-on authentication service - must always run for user authentication
|
||||
image: authelia/authelia:latest
|
||||
image: authelia/authelia:4.37.5
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# Core Infrastructure Services
|
||||
# These services form the foundation of the homelab and should always be running
|
||||
# Place in /opt/stacks/core/docker-compose.yml
|
||||
|
||||
# RESTART POLICY GUIDE:
|
||||
# - unless-stopped: Core infrastructure services that should always run
|
||||
# - no: Services with Sablier lazy loading (start on-demand)
|
||||
# - See individual service comments for specific reasoning
|
||||
|
||||
services:
|
||||
|
||||
duckdns:
|
||||
# Dynamic DNS service - must always run to maintain domain resolution
|
||||
image: lscr.io/linuxserver/duckdns:latest
|
||||
container_name: duckdns
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- TZ=${TZ}
|
||||
- SUBDOMAINS=${DUCKDNS_SUBDOMAINS}
|
||||
- TOKEN=${DUCKDNS_TOKEN}
|
||||
volumes:
|
||||
- ./duckdns/config:/config
|
||||
networks:
|
||||
- traefik-network
|
||||
|
||||
traefik:
|
||||
# Reverse proxy and SSL termination - core routing service, must always run
|
||||
# CONFIGURATION REQUIREMENT: traefik.yml MUST be in ./traefik/config/ directory
|
||||
# VOLUME MOUNT: ./traefik/config:/config - config file location is critical
|
||||
image: traefik:v3
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
command: ["--configFile=/config/traefik.yml"]
|
||||
environment:
|
||||
- DUCKDNS_TOKEN=${DUCKDNS_TOKEN}
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- ./traefik/config:/config
|
||||
- ./traefik/letsencrypt:/letsencrypt
|
||||
- ./traefik/dynamic:/dynamic
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
networks:
|
||||
- traefik-network
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=core"
|
||||
- "homelab.description=Reverse proxy and SSL termination"
|
||||
# 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.traefik.rule=Host(`traefik.${DOMAIN}`)"
|
||||
- "traefik.http.routers.traefik.entrypoints=websecure"
|
||||
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.traefik.middlewares=authelia@docker"
|
||||
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
|
||||
|
||||
authelia:
|
||||
# Single sign-on authentication service - must always run for user authentication
|
||||
# VERSION PINNING: Pinned to v4.37.5 due to breaking changes in v4.39.15+
|
||||
# BREAKING CHANGES: v4.39.15+ has incompatible configuration and database changes
|
||||
# UPGRADE NOTES: Test in separate environment before upgrading. Backup config and DB.
|
||||
image: authelia/authelia:4.37.5
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
ports:
|
||||
- "9091:9091"
|
||||
volumes:
|
||||
- ./authelia/config:/config
|
||||
- ./authelia/secrets:/secrets
|
||||
networks:
|
||||
- traefik-network
|
||||
depends_on:
|
||||
- traefik
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "homelab.category=core"
|
||||
- "homelab.description=Single sign-on authentication"
|
||||
# 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.authelia.rule=Host(`auth.${DOMAIN}`)"
|
||||
- "traefik.http.routers.authelia.entrypoints=websecure"
|
||||
- "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.authelia.service=authelia"
|
||||
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
|
||||
# Authelia forward auth middleware configuration
|
||||
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.${DOMAIN}/"
|
||||
- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=X-Secret"
|
||||
- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
|
||||
|
||||
# Sablier - Lazy loading service for Docker containers
|
||||
# Controls startup/shutdown of lazy-loaded services, must always run
|
||||
# REQUIREMENTS FOR DOCKER API ACCESS:
|
||||
# 1. Docker daemon must be configured to listen on TCP port 2376 with TLS
|
||||
# 2. DOCKER_HOST environment variable must point to accessible Docker API endpoint
|
||||
# 3. Firewall must allow TCP connections to Docker API port (2376)
|
||||
# 4. TLS certificates must be mounted and environment variables set
|
||||
# 5. Ensure dockerproxy service is running and accessible
|
||||
sablier-service:
|
||||
image: sablierapp/sablier:latest
|
||||
container_name: sablier-service
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik-network
|
||||
environment:
|
||||
- SABLIER_PROVIDER=docker
|
||||
- SABLIER_DOCKER_API_VERSION=1.51
|
||||
- SABLIER_DOCKER_NETWORK=traefik-network
|
||||
- SABLIER_LOG_LEVEL=debug
|
||||
- DOCKER_HOST=tcp://${SERVER_IP}:2376
|
||||
- DOCKER_TLS_VERIFY=1
|
||||
- DOCKER_CERT_PATH=/certs
|
||||
volumes:
|
||||
- ./shared-ca:/certs:ro
|
||||
ports:
|
||||
- 10000:10000
|
||||
labels:
|
||||
# Service metadata
|
||||
- "homelab.category=core"
|
||||
- "homelab.description=Lazy loading service for Docker containers"
|
||||
|
||||
networks:
|
||||
traefik-network:
|
||||
external: true
|
||||
|
||||
x-dockge:
|
||||
urls:
|
||||
- https://auth.${DOMAIN}
|
||||
- http://${SERVER_IP}:9091
|
||||
- https://traefik.${DOMAIN}
|
||||
- http://${SERVER_IP}:8080
|
||||
@@ -0,0 +1,19 @@
|
||||
http:
|
||||
routers:
|
||||
# Individual Services
|
||||
homeassistant:
|
||||
rule: "Host(`hass.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: homeassistant
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
services:
|
||||
# Individual Services
|
||||
homeassistant:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://${HOMEASSISTANT_IP}:8123"
|
||||
passHostHeader: true
|
||||
399
docker-compose/core/traefik/dynamic/local-host-production.yml
Normal file
399
docker-compose/core/traefik/dynamic/local-host-production.yml
Normal file
@@ -0,0 +1,399 @@
|
||||
http:
|
||||
routers:
|
||||
# Remote Server Services (${REMOTE_SERVER_HOSTNAME})
|
||||
dockge-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`dockge.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: dockge-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
dozzle-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`dozzle.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: dozzle-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
glances-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`glances.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: glances-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
backrest-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`backrest.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: backrest-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
duplicati-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`duplicati.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: duplicati-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
homepage-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`homepage.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: homepage-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
homarr-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`homarr.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: homarr-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
grafana-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`grafana.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: grafana-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
prometheus-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`prometheus.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: prometheus-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
uptime-kuma-${REMOTE_SERVER_HOSTNAME}:
|
||||
rule: "Host(`status.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: uptime-kuma-${REMOTE_SERVER_HOSTNAME}
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
|
||||
# Service Definitions
|
||||
services:
|
||||
backrest-${SERVER_HOSTNAME}:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:9898"
|
||||
passHostHeader: true
|
||||
|
||||
vaultwarden-${SERVER_HOSTNAME}:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8091"
|
||||
passHostHeader: true
|
||||
|
||||
bookstack-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:6875"
|
||||
passHostHeader: true
|
||||
|
||||
calibre-web-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8083"
|
||||
passHostHeader: true
|
||||
|
||||
code-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8079"
|
||||
passHostHeader: true
|
||||
|
||||
dockge-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:5001"
|
||||
passHostHeader: true
|
||||
|
||||
dockhand-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:3003"
|
||||
passHostHeader: true
|
||||
|
||||
dokuwiki-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8087"
|
||||
passHostHeader: true
|
||||
|
||||
dozzle-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8085"
|
||||
passHostHeader: true
|
||||
|
||||
duplicati-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8200"
|
||||
passHostHeader: true
|
||||
|
||||
ez-assistant-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:18789" # Internal IP of ${SERVER_HOSTNAME} server
|
||||
passHostHeader: true
|
||||
|
||||
formio-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:3002"
|
||||
passHostHeader: true
|
||||
|
||||
gitea-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:3010"
|
||||
passHostHeader: true
|
||||
|
||||
glances-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:61208"
|
||||
passHostHeader: true
|
||||
|
||||
homarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:7575"
|
||||
passHostHeader: true
|
||||
|
||||
homepage-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:3000"
|
||||
passHostHeader: true
|
||||
|
||||
jellyfin-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8096"
|
||||
passHostHeader: true
|
||||
|
||||
jupyter-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8890"
|
||||
passHostHeader: true
|
||||
|
||||
kopia-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:51515"
|
||||
passHostHeader: true
|
||||
|
||||
mealie-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:9000"
|
||||
passHostHeader: true
|
||||
|
||||
mediawiki-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8086"
|
||||
passHostHeader: true
|
||||
|
||||
motioneye-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8081"
|
||||
passHostHeader: true
|
||||
|
||||
nextcloud-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8089"
|
||||
passHostHeader: true
|
||||
|
||||
openkm-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:18080"
|
||||
passHostHeader: true
|
||||
|
||||
openwebui-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:3000"
|
||||
passHostHeader: true
|
||||
|
||||
qbittorrent-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8081"
|
||||
passHostHeader: true
|
||||
|
||||
tdarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8265"
|
||||
passHostHeader: true
|
||||
|
||||
unmanic-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8889"
|
||||
passHostHeader: true
|
||||
|
||||
wordpress-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8088"
|
||||
passHostHeader: true
|
||||
|
||||
# Arr Services
|
||||
|
||||
jellyseerr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:5055"
|
||||
passHostHeader: true
|
||||
|
||||
prowlarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:9696"
|
||||
passHostHeader: true
|
||||
|
||||
radarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:7878"
|
||||
passHostHeader: true
|
||||
|
||||
sonarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8989"
|
||||
passHostHeader: true
|
||||
|
||||
lidarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8686"
|
||||
passHostHeader: true
|
||||
|
||||
readarr-${SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8787"
|
||||
passHostHeader: true
|
||||
|
||||
mylar3-${SERVER_HOSTNAME}:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://${SERVER_IP}:8090"
|
||||
passHostHeader: true
|
||||
|
||||
|
||||
|
||||
|
||||
# Remote Server Service Definitions (${REMOTE_SERVER_HOSTNAME})
|
||||
dockge-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:5001"
|
||||
passHostHeader: true
|
||||
|
||||
dozzle-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:8085"
|
||||
passHostHeader: true
|
||||
|
||||
glances-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:61208"
|
||||
passHostHeader: true
|
||||
|
||||
backrest-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:9898"
|
||||
passHostHeader: true
|
||||
|
||||
duplicati-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:8200"
|
||||
passHostHeader: true
|
||||
|
||||
homepage-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:3000"
|
||||
passHostHeader: true
|
||||
|
||||
homarr-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:7575"
|
||||
passHostHeader: true
|
||||
|
||||
grafana-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:3000"
|
||||
passHostHeader: true
|
||||
|
||||
prometheus-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:9090"
|
||||
passHostHeader: true
|
||||
|
||||
uptime-kuma-${REMOTE_SERVER_HOSTNAME}:
|
||||
loadbalancer:
|
||||
servers:
|
||||
- url: "http://${REMOTE_SERVER_IP}:3001"
|
||||
passHostHeader: true
|
||||
|
||||
# Middleware Definitions
|
||||
middlewares:
|
||||
ez-assistant-websocket:
|
||||
headers:
|
||||
accessControlAllowHeaders:
|
||||
- "Connection"
|
||||
- "Upgrade"
|
||||
accessControlAllowMethods:
|
||||
- "GET"
|
||||
- "POST"
|
||||
- "OPTIONS"
|
||||
accessControlMaxAge: 86400
|
||||
31
docker-compose/core/traefik/dynamic/routes.yml
Normal file
31
docker-compose/core/traefik/dynamic/routes.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
# Traefik Dynamic Configuration
|
||||
# Copy to /opt/stacks/traefik/dynamic/routes.yml
|
||||
# Add custom routes here that aren't defined via Docker labels
|
||||
|
||||
http:
|
||||
routers:
|
||||
# Example custom route
|
||||
# custom-service:
|
||||
# rule: "Host(`custom.example.com`)"
|
||||
# entryPoints:
|
||||
# - websecure
|
||||
# middlewares:
|
||||
# - authelia@docker
|
||||
# tls:
|
||||
# certResolver: letsencrypt
|
||||
# service: custom-service
|
||||
|
||||
services:
|
||||
# Example custom service
|
||||
# custom-service:
|
||||
# loadBalancer:
|
||||
# servers:
|
||||
# - url: "http://192.168.1.100:8080"
|
||||
|
||||
middlewares:
|
||||
# Additional middlewares can be defined here
|
||||
# Example: Rate limiting
|
||||
# rate-limit:
|
||||
# rateLimit:
|
||||
# average: 100
|
||||
# burst: 50
|
||||
454
docker-compose/core/traefik/dynamic/sablier.yml
Normal file
454
docker-compose/core/traefik/dynamic/sablier.yml
Normal file
@@ -0,0 +1,454 @@
|
||||
# Session duration set to 5m for testing. Increase to 30m for production.
|
||||
http:
|
||||
middlewares:
|
||||
authelia:
|
||||
forwardauth:
|
||||
address: http://authelia:9091/api/verify?rd=https://auth.${DOMAIN}/
|
||||
authResponseHeaders:
|
||||
- X-Secret
|
||||
trustForwardHeader: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-arr:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-arr
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Arr Apps
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-backrest:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-backrest
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Backrest
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-vaultwarden:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-vaultwarden
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Vaultwarden
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-bookstack:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-bookstack
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Bookstack
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-calibre-web:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-calibre-web
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Calibre Web
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-code-server:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-code-server
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Code Server
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-dozzle:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-dozzle
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: dozzle
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-dokuwiki:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-dokuwiki
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: DokuWiki
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-duplicati:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-duplicati
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Duplicati
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-assistant:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-assistant
|
||||
sessionDuration: 30m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: EZ-Assistant
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-formio:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-formio
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: FormIO
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-gitea:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-gitea
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Gitea
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-glances:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-glances
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Glances
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-homarr:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-homarr
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Homarr
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-jellyfin:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-jellyfin
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Jellyfin
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-jupyter:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-jupyter
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Jupyter
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-komodo:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-komodo
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Komodo
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-kopia:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-kopia
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Kopia
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-mealie:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-mealie
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Mealie
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-mediawiki:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-mediawiki
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: mediawiki
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-nextcloud:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-nextcloud
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: NextCloud
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-openkm:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-openkm
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: OpenKM
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-openwebui:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-openwebui
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: OpenWebUI
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-pulse:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-pulse
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Pulse
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-tdarr:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-tdarr
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Tdarr
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-unmanic:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-unmanic
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Unmanic
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${SERVER_HOSTNAME}-wordpress:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${SERVER_HOSTNAME}-wordpress
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: wordpress
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
# Remote Server (${REMOTE_SERVER_HOSTNAME}) Sablier Middlewares
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-dockge:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-dockge
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Dockge (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-dozzle:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-dozzle
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Dozzle (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-glances:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-glances
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Glances (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-backrest:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-backrest
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Backrest (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-duplicati:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-duplicati
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Duplicati (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-homepage:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-homepage
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Homepage (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-homarr:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-homarr
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Homarr (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-grafana:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-grafana
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Grafana (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-prometheus:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-prometheus
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Prometheus (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
|
||||
sablier-${REMOTE_SERVER_HOSTNAME}-uptime-kuma:
|
||||
plugin:
|
||||
sablier:
|
||||
sablierUrl: http://sablier-service:10000
|
||||
group: ${REMOTE_SERVER_HOSTNAME}-uptime-kuma
|
||||
sessionDuration: 5m
|
||||
ignoreUserAgent: curl
|
||||
dynamic:
|
||||
displayName: Uptime Kuma (${REMOTE_SERVER_HOSTNAME})
|
||||
theme: ghost
|
||||
show-details-by-default: true
|
||||
35
docker-compose/dashboards/deploy-dashboards.sh
Executable file
35
docker-compose/dashboards/deploy-dashboards.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Deploy dashboards stack script
|
||||
# Run from /opt/stacks/dashboards/
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="/home/kelin/EZ-Homelab" # Fixed repo path since script runs from /opt/stacks/dashboards
|
||||
source "$REPO_DIR/scripts/common.sh"
|
||||
|
||||
log_info "Deploying dashboards stack..."
|
||||
|
||||
# Load environment
|
||||
load_env_file_safely .env
|
||||
|
||||
# Localize labels in compose file
|
||||
localize_compose_labels docker-compose.yml
|
||||
|
||||
# Localize config files
|
||||
for config_file in $(find . -name "*.yml" -o -name "*.yaml" | grep -v docker-compose.yml); do
|
||||
localize_config_file "$config_file"
|
||||
done
|
||||
|
||||
# Deploy
|
||||
run_cmd docker compose up -d
|
||||
|
||||
# Validate
|
||||
if docker ps | grep -q homepage; then
|
||||
log_success "Dashboards stack deployed successfully"
|
||||
exit 0
|
||||
else
|
||||
log_error "Dashboards stack deployment failed"
|
||||
exit 1
|
||||
fi
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3003:3000"
|
||||
- '3003:3000'
|
||||
volumes:
|
||||
- ./homepage:/app/config
|
||||
- /var/run/docker.sock:/var/run/docker.sock # For Docker integration do not mount RO
|
||||
@@ -38,24 +38,24 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=dashboard"
|
||||
- 'homelab.description=Application dashboard"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=3000"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=3000'
|
||||
# Sablier lazy loading (disabled by default - uncomment to enable)
|
||||
# - "sablier.enable=true"
|
||||
# - "sablier.group=jasper-homarr"
|
||||
# - "sablier.start-on-demand=true"
|
||||
# - 'sablier.enable=true'
|
||||
# - 'sablier.group=jasper-homarr'
|
||||
# - 'sablier.start-on-demand=true'
|
||||
|
||||
# Homarr - Modern dashboard
|
||||
# Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity
|
||||
@@ -76,7 +76,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "7575:7575"
|
||||
- '7575:7575'
|
||||
volumes:
|
||||
- ./homarr/config:/app/config/configs
|
||||
- ./homarr/data:/data
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
environment:
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:7575/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:7575/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -93,21 +93,21 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=dashboard"
|
||||
- 'homelab.description=Modern homelab dashboard"
|
||||
- 'traefik.enable=true"
|
||||
- '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"
|
||||
- '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"
|
||||
- 'traefik.http.services.homarr.loadbalancer.server.port=7575'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-homarr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-homarr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# DOCKGE URL CONFIGURATION
|
||||
x-dockge:
|
||||
|
||||
36
docker-compose/dockge/deploy-dockge.sh
Executable file
36
docker-compose/dockge/deploy-dockge.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# Deploy Dockge stack script
|
||||
# Run from /opt/dockge/
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="/home/kelin/EZ-Homelab" # Fixed repo path since script runs from /opt/dockge
|
||||
source "$REPO_DIR/scripts/common.sh"
|
||||
|
||||
log_info "Deploying Dockge stack..."
|
||||
|
||||
# Load environment
|
||||
load_env_file_safely .env
|
||||
|
||||
# Remove sensitive variables from dockge .env (Dockge doesn't need them)
|
||||
sed -i '/^AUTHELIA_ADMIN_PASSWORD_HASH=/d' .env
|
||||
sed -i '/^AUTHELIA_JWT_SECRET=/d' .env
|
||||
sed -i '/^AUTHELIA_SESSION_SECRET=/d' .env
|
||||
sed -i '/^AUTHELIA_STORAGE_ENCRYPTION_KEY=/d' .env
|
||||
|
||||
# Localize labels in compose file
|
||||
localize_compose_labels docker-compose.yml
|
||||
|
||||
# Deploy
|
||||
run_cmd docker compose up -d
|
||||
|
||||
# Validate
|
||||
if docker ps | grep -q dockge; then
|
||||
log_success "Dockge stack deployed successfully"
|
||||
exit 0
|
||||
else
|
||||
log_error "Dockge stack deployment failed"
|
||||
exit 1
|
||||
fi
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "5001:5001" # Optional: direct access
|
||||
- '5001:5001' # Optional: direct access
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /opt/stacks:/opt/stacks # Dockge manages stacks in this directory
|
||||
@@ -37,18 +37,18 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=Docker Compose stack manager (PRIMARY)"
|
||||
- 'homelab.category=infrastructure'
|
||||
- 'homelab.description=Docker Compose stack manager (PRIMARY)'
|
||||
# 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.docker.network=traefik-network"
|
||||
- 'traefik.http.routers.dockge.rule=Host(`dockge.${DOMAIN}`)"
|
||||
- 'traefik.http.routers.dockge.entrypoints=websecure"
|
||||
- 'traefik.http.routers.dockge.tls.certresolver=letsencrypt"
|
||||
- 'traefik.http.routers.dockge.middlewares=authelia@docker"
|
||||
- 'traefik.http.services.dockge.loadbalancer.server.port=5001"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- 'traefik.http.routers.dockge.rule=Host(`dockge.${DOMAIN}`)'
|
||||
- 'traefik.http.routers.dockge.entrypoints=websecure'
|
||||
- 'traefik.http.routers.dockge.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.dockge.middlewares=authelia@docker'
|
||||
- 'traefik.http.services.dockge.loadbalancer.server.port=5001'
|
||||
|
||||
networks:
|
||||
homelab-network:
|
||||
|
||||
@@ -28,8 +28,8 @@ services:
|
||||
- TZ=America/New_York
|
||||
privileged: true
|
||||
labels:
|
||||
- 'homelab.category=iot"
|
||||
- 'homelab.description=Home automation platform"
|
||||
- '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
|
||||
|
||||
@@ -51,7 +51,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "6052:6052"
|
||||
- '6052:6052'
|
||||
volumes:
|
||||
- ./esphome/config:/config
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
@@ -63,18 +63,18 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=iot"
|
||||
- 'homelab.description=ESP8266/ESP32 firmware manager"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
tasmoadmin:
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8084:80"
|
||||
- '8084:80'
|
||||
volumes:
|
||||
- /opt/stacks/tasmoadmin/data:/data
|
||||
environment:
|
||||
@@ -94,18 +94,18 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=iot"
|
||||
- 'homelab.description=Tasmota device management"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
motioneye:
|
||||
@@ -116,7 +116,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8765:8765"
|
||||
- '8765:8765'
|
||||
volumes:
|
||||
- ./$(basename $file .yml)/config:/etc/motioneye
|
||||
- /mnt/surveillance:/var/lib/motioneye # Large video files on separate drive
|
||||
@@ -126,18 +126,18 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=iot"
|
||||
- 'homelab.description=Video surveillance system"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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)
|
||||
nodered:
|
||||
@@ -157,7 +157,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "1880:1880"
|
||||
- '1880:1880'
|
||||
volumes:
|
||||
- /opt/stacks/nodered/data:/data
|
||||
environment:
|
||||
@@ -166,18 +166,18 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=iot"
|
||||
- 'homelab.description=Flow-based automation programming"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
@@ -188,15 +188,15 @@ services:
|
||||
networks:
|
||||
- homelab-network
|
||||
ports:
|
||||
- "1883:1883" # MQTT
|
||||
- "9001:9001" # Websockets
|
||||
- '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"
|
||||
- 'homelab.category=iot'
|
||||
- 'homelab.description=MQTT message broker'
|
||||
|
||||
# Zigbee2MQTT - Zigbee to MQTT bridge (DISABLED - requires USB adapter)
|
||||
# NOTE: Requires USB Zigbee adapter (e.g., ConBee II, Sonoff ZBDongle)
|
||||
@@ -219,14 +219,14 @@ services:
|
||||
# environment:
|
||||
# - TZ=America/New_York
|
||||
# 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"
|
||||
# - '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:
|
||||
|
||||
35
docker-compose/infrastructure/deploy-infrastructure.sh
Executable file
35
docker-compose/infrastructure/deploy-infrastructure.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Deploy infrastructure stack script
|
||||
# Run from /opt/stacks/infrastructure/
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="/home/kelin/EZ-Homelab" # Fixed repo path since script runs from /opt/stacks/infrastructure
|
||||
source "$REPO_DIR/scripts/common.sh"
|
||||
|
||||
log_info "Deploying infrastructure stack..."
|
||||
|
||||
# Load environment
|
||||
load_env_file_safely .env
|
||||
|
||||
# Localize labels in compose file
|
||||
localize_compose_labels docker-compose.yml
|
||||
|
||||
# Localize config files
|
||||
for config_file in $(find . -name "*.yml" -o -name "*.yaml" | grep -v docker-compose.yml); do
|
||||
localize_config_file "$config_file"
|
||||
done
|
||||
|
||||
# Deploy
|
||||
run_cmd docker compose up -d
|
||||
|
||||
# Validate
|
||||
if docker ps | grep -q pihole && docker ps | grep -q watchtower; then
|
||||
log_success "Infrastructure stack deployed successfully"
|
||||
exit 0
|
||||
else
|
||||
log_error "Infrastructure stack deployment failed"
|
||||
exit 1
|
||||
fi
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
# 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"]
|
||||
# 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
|
||||
@@ -55,8 +55,8 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "53:53/tcp" # DNS TCP
|
||||
- "53:53/udp" # DNS UDP
|
||||
- '53:53/tcp' # DNS TCP
|
||||
- '53:53/udp' # DNS UDP
|
||||
volumes:
|
||||
- ./pihole/etc-pihole:/etc/pihole
|
||||
- ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d
|
||||
@@ -73,20 +73,20 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=Network-wide ad blocking and DNS"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
watchtower:
|
||||
@@ -105,8 +105,8 @@ services:
|
||||
- WATCHTOWER_NOTIFICATIONS=shoutrrr
|
||||
- WATCHTOWER_NOTIFICATION_URL=${WATCHTOWER_NOTIFICATION_URL}
|
||||
labels:
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=Automatic Docker container updates"
|
||||
- 'homelab.category=infrastructure'
|
||||
- 'homelab.description=Automatic Docker container updates'
|
||||
|
||||
# Dozzle - Real-time Docker log viewer
|
||||
# Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity
|
||||
@@ -127,7 +127,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8085:8080"
|
||||
- '8085:8080'
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
@@ -135,7 +135,7 @@ services:
|
||||
- DOZZLE_TAILSIZE=300
|
||||
- DOZZLE_FILTER=status=running
|
||||
healthcheck:
|
||||
test: ["CMD", "/dozzle", "healthcheck"]
|
||||
test: ['CMD', '/dozzle', 'healthcheck']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -143,22 +143,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=Real-time Docker log viewer"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=infrastructure'
|
||||
- 'homelab.description=Real-time Docker log viewer'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# Router configuration
|
||||
- 'traefik.http.routers.dozzle.rule=Host(`dozzle.jasper.${DOMAIN}`)"
|
||||
- 'traefik.http.routers.dozzle.entrypoints=websecure"
|
||||
- 'traefik.http.routers.dozzle.tls=true"
|
||||
- 'traefik.http.routers.dozzle.middlewares=authelia@docker"
|
||||
- 'traefik.http.routers.dozzle.rule=Host(`dozzle.jasper.${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"
|
||||
- 'traefik.http.services.dozzle.loadbalancer.server.port=8085'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-dozzle"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-dozzle'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Glances - System monitoring
|
||||
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
|
||||
@@ -179,7 +179,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "61208:61208"
|
||||
- '61208:61208'
|
||||
pid: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
@@ -187,7 +187,7 @@ services:
|
||||
environment:
|
||||
- GLANCES_OPT=-w
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:61208/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:61208/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -195,22 +195,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=System and Docker monitoring"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=infrastructure'
|
||||
- 'homelab.description=System and Docker monitoring'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# Router configuration
|
||||
- 'traefik.http.routers.glances.rule=Host(`glances.jasper.${DOMAIN}`)"
|
||||
- 'traefik.http.routers.glances.entrypoints=websecure"
|
||||
- 'traefik.http.routers.glances.tls=true"
|
||||
- 'traefik.http.routers.glances.middlewares=authelia@docker"
|
||||
- 'traefik.http.routers.glances.rule=Host(`glances.jasper.${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"
|
||||
- 'traefik.http.services.glances.loadbalancer.server.port=61208'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-glances"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-glances'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Code Server - VS Code in browser
|
||||
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
|
||||
@@ -231,7 +231,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8079:8443"
|
||||
- '8079:8443'
|
||||
volumes:
|
||||
- ./code-server/config:/config
|
||||
- /opt/stacks:/opt/stacks # Access to all stacks
|
||||
@@ -243,7 +243,7 @@ services:
|
||||
- PASSWORD=${CODE_SERVER_PASSWORD}
|
||||
- SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8443/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:8443/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -251,22 +251,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=infrastructure"
|
||||
- 'homelab.description=VS Code in browser"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=infrastructure'
|
||||
- 'homelab.description=VS Code in browser'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.code-server.loadbalancer.server.port=8443'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-code-server"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-code-server'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
x-dockge:
|
||||
urls:
|
||||
|
||||
@@ -14,7 +14,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8989:8989"
|
||||
- '8989:8989'
|
||||
volumes:
|
||||
- ./sonarr/config:/config
|
||||
- /mnt/media:/media
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8989/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:8989/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -33,22 +33,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=TV show management and automation"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Radarr - Movie automation
|
||||
radarr:
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "7878:7878"
|
||||
- '7878:7878'
|
||||
volumes:
|
||||
- ./radarr/config:/config
|
||||
- /mnt/media:/media
|
||||
@@ -69,7 +69,7 @@ services:
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:7878/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:7878/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -78,22 +78,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Movie management and automation"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Prowlarr - Indexer manager
|
||||
# Access at: https://prowlarr.yourdomain.duckdns.org
|
||||
@@ -105,7 +105,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9696:9696"
|
||||
- '9696:9696'
|
||||
volumes:
|
||||
- ./prowlarr/config:/config
|
||||
environment:
|
||||
@@ -113,7 +113,7 @@ services:
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9696/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:9696/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -122,22 +122,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Indexer manager for Sonarr/Radarr"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Readarr - Ebook and audiobook management
|
||||
readarr:
|
||||
@@ -148,7 +148,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8787:8787"
|
||||
- '8787:8787'
|
||||
volumes:
|
||||
- ./readarr/config:/config
|
||||
- /mnt/media/books:/books
|
||||
@@ -161,22 +161,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Ebook and audiobook management"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Lidarr - Music collection manager
|
||||
lidarr:
|
||||
@@ -187,7 +187,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8686:8686"
|
||||
- '8686:8686'
|
||||
volumes:
|
||||
- ./lidarr/config:/config
|
||||
- /mnt/media/music:/music
|
||||
@@ -200,22 +200,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Music collection manager"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Lazy Librarian - Book manager
|
||||
lazylibrarian:
|
||||
@@ -226,7 +226,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "5299:5299"
|
||||
- '5299:5299'
|
||||
volumes:
|
||||
- ./lazylibrarian/config:/config
|
||||
- /mnt/media/books:/books
|
||||
@@ -240,22 +240,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Book download automation"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Mylar3 - Comic book manager
|
||||
mylar3:
|
||||
@@ -266,7 +266,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8090:8090"
|
||||
- '8090:8090'
|
||||
volumes:
|
||||
- ./mylar3/config:/config
|
||||
- /mnt/media/comics:/comics
|
||||
@@ -279,22 +279,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Comic book collection manager"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Jellyseerr - Request management for Jellyfin/Plex
|
||||
jellyseerr:
|
||||
@@ -305,14 +305,14 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "5055:5055"
|
||||
- '5055:5055'
|
||||
volumes:
|
||||
- ./jellyseerr/config:/app/config
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5055/"]
|
||||
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:5055/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -321,22 +321,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Media request management"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# FlareSolverr - Cloudflare bypass for Prowlarr
|
||||
# No web UI - used by Prowlarr
|
||||
@@ -352,9 +352,9 @@ services:
|
||||
labels:
|
||||
- homelab.category=media
|
||||
- homelab.description=Cloudflare bypass for indexers
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-arr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-arr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
x-dockge:
|
||||
urls:
|
||||
|
||||
@@ -28,7 +28,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8096:8096"
|
||||
- '8096:8096'
|
||||
volumes:
|
||||
- ./jellyfin/config:/config
|
||||
- ./jellyfin/cache:/cache
|
||||
@@ -38,7 +38,7 @@ services:
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8096/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:8096/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -49,23 +49,23 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
labels:
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Open-source media streaming server"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=media'
|
||||
- 'homelab.description=Open-source media streaming server'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.jellyfin.loadbalancer.server.port=8096'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-jellyfin"
|
||||
- "sablier.start-on-demand=true"
|
||||
- "sablier.theme=hacker-terminal"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-jellyfin'
|
||||
- 'sablier.start-on-demand=true'
|
||||
- 'sablier.theme=hacker-terminal'
|
||||
|
||||
# Calibre-Web - Ebook reader and server
|
||||
calibre-web:
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8083:8083"
|
||||
- '8083:8083'
|
||||
volumes:
|
||||
- ./calibre-web/config:/config
|
||||
- /mnt/media/books:/books
|
||||
@@ -97,22 +97,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
labels:
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Ebook reader and library management"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=media'
|
||||
- 'homelab.description=Ebook reader and library management'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.calibre.loadbalancer.server.port=8083'
|
||||
# Sablier configuration (disabled by default)
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-calibre-web"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-calibre-web'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
x-dockge:
|
||||
urls:
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
server:
|
||||
http_listen_port: 3100
|
||||
grpc_listen_port: 9096
|
||||
|
||||
common:
|
||||
path_prefix: /loki
|
||||
storage:
|
||||
filesystem:
|
||||
chunks_directory: /loki/chunks
|
||||
rules_directory: /loki/rules
|
||||
replication_factor: 1
|
||||
ring:
|
||||
instance_addr: 127.0.0.1
|
||||
kvstore:
|
||||
store: inmemory
|
||||
|
||||
query_range:
|
||||
results_cache:
|
||||
cache:
|
||||
embedded_cache:
|
||||
enabled: true
|
||||
max_size_mb: 100
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2020-10-24
|
||||
store: tsdb
|
||||
object_store: filesystem
|
||||
schema: v13
|
||||
index:
|
||||
prefix: index_
|
||||
period: 24h
|
||||
|
||||
ruler:
|
||||
alertmanager_url: http://localhost:9093
|
||||
@@ -1,16 +0,0 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'node-exporter'
|
||||
static_configs:
|
||||
- targets: ['node-exporter:9100']
|
||||
|
||||
- job_name: 'cadvisor'
|
||||
static_configs:
|
||||
- targets: ['cadvisor:8080']
|
||||
@@ -1,18 +0,0 @@
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
- job_name: system
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: varlogs
|
||||
__path__: /var/log/*log
|
||||
@@ -23,7 +23,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9090:9090"
|
||||
- '9090:9090'
|
||||
volumes:
|
||||
- ./config/prometheus:/etc/prometheus
|
||||
- prometheus-data:/prometheus
|
||||
@@ -38,19 +38,19 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Metrics collection and time-series database"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
# Default credentials: admin / admin (change on first login)
|
||||
@@ -71,7 +71,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- '3000:3000'
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
- ./config/grafana/provisioning:/etc/grafana/provisioning
|
||||
@@ -80,26 +80,26 @@ services:
|
||||
- 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: '1000:1000'
|
||||
depends_on:
|
||||
- prometheus
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Metrics visualization and dashboards"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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://192.168.4.4:9100/metrics
|
||||
@@ -110,7 +110,7 @@ services:
|
||||
networks:
|
||||
- homelab-network
|
||||
ports:
|
||||
- "9100:9100"
|
||||
- '9100:9100'
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
@@ -121,8 +121,8 @@ services:
|
||||
- '--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"
|
||||
- 'homelab.category=monitoring'
|
||||
- 'homelab.description=Hardware and OS metrics exporter'
|
||||
|
||||
# cAdvisor - Container metrics exporter
|
||||
# Access at: http://192.168.4.4:8082
|
||||
@@ -134,7 +134,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8082:8080"
|
||||
- '8082:8080'
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:ro
|
||||
@@ -148,19 +148,19 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Container metrics and performance monitoring"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
uptime-kuma:
|
||||
@@ -180,7 +180,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3001:3001"
|
||||
- '3001:3001'
|
||||
volumes:
|
||||
- uptime-kuma-data:/app/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
@@ -188,19 +188,19 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Service uptime monitoring and alerts"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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://192.168.4.4:3100
|
||||
@@ -221,7 +221,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3100:3100"
|
||||
- '3100:3100'
|
||||
volumes:
|
||||
- ./config/loki:/etc/loki
|
||||
- loki-data:/loki
|
||||
@@ -230,19 +230,19 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Log aggregation system"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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
|
||||
@@ -260,8 +260,8 @@ services:
|
||||
depends_on:
|
||||
- loki
|
||||
labels:
|
||||
- 'homelab.category=monitoring"
|
||||
- 'homelab.description=Log collector for Loki"
|
||||
- 'homelab.category=monitoring'
|
||||
- 'homelab.description=Log collector for Loki'
|
||||
|
||||
volumes:
|
||||
prometheus-data:
|
||||
|
||||
46
docker-compose/monitoring/loki/loki-config.yml
Normal file
46
docker-compose/monitoring/loki/loki-config.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
# Loki Configuration Template
|
||||
# Copy this file to ./config/loki/loki-config.yml
|
||||
|
||||
auth_enabled: false
|
||||
|
||||
server:
|
||||
http_listen_port: 3100
|
||||
grpc_listen_port: 9096
|
||||
|
||||
common:
|
||||
path_prefix: /loki
|
||||
storage:
|
||||
filesystem:
|
||||
chunks_directory: /loki/chunks
|
||||
rules_directory: /loki/rules
|
||||
replication_factor: 1
|
||||
ring:
|
||||
instance_addr: 127.0.0.1
|
||||
kvstore:
|
||||
store: inmemory
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2020-10-24
|
||||
store: boltdb-shipper
|
||||
object_store: filesystem
|
||||
schema: v11
|
||||
index:
|
||||
prefix: index_
|
||||
period: 24h
|
||||
|
||||
ruler:
|
||||
alertmanager_url: http://localhost:9093
|
||||
|
||||
# Retention configuration (delete logs older than 30 days)
|
||||
limits_config:
|
||||
retention_period: 720h # 30 days
|
||||
|
||||
# Compactor to delete old data
|
||||
compactor:
|
||||
working_directory: /loki/compactor
|
||||
shared_store: filesystem
|
||||
compaction_interval: 10m
|
||||
retention_enabled: true
|
||||
retention_delete_delay: 2h
|
||||
retention_delete_worker_count: 150
|
||||
49
docker-compose/monitoring/prometheus/prometheus.yml
Normal file
49
docker-compose/monitoring/prometheus/prometheus.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
# Prometheus Configuration Template
|
||||
# Copy this file to ./config/prometheus/prometheus.yml
|
||||
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
external_labels:
|
||||
monitor: 'homelab'
|
||||
|
||||
# Alertmanager configuration (optional)
|
||||
# alerting:
|
||||
# alertmanagers:
|
||||
# - static_configs:
|
||||
# - targets:
|
||||
# - alertmanager:9093
|
||||
|
||||
# Load rules once and periodically evaluate them
|
||||
# rule_files:
|
||||
# - "alerts/*.yml"
|
||||
|
||||
# Scrape configurations
|
||||
scrape_configs:
|
||||
# Prometheus itself
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
# Node Exporter - System metrics
|
||||
- job_name: 'node-exporter'
|
||||
static_configs:
|
||||
- targets: ['node-exporter:9100']
|
||||
labels:
|
||||
instance: 'homelab-server'
|
||||
|
||||
# cAdvisor - Container metrics
|
||||
- job_name: 'cadvisor'
|
||||
static_configs:
|
||||
- targets: ['cadvisor:8080']
|
||||
labels:
|
||||
instance: 'homelab-server'
|
||||
|
||||
# Add your own services here
|
||||
# Example: Monitor a service with /metrics endpoint
|
||||
# - job_name: 'my-service'
|
||||
# static_configs:
|
||||
# - targets: ['my-service:8080']
|
||||
# labels:
|
||||
# instance: 'homelab-server'
|
||||
# service: 'my-service'
|
||||
53
docker-compose/monitoring/promtail/promtail-config.yml
Normal file
53
docker-compose/monitoring/promtail/promtail-config.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
# Promtail Configuration Template
|
||||
# Copy this file to ./config/promtail/promtail-config.yml
|
||||
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
# Docker container logs
|
||||
- job_name: docker
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: docker
|
||||
__path__: /var/lib/docker/containers/*/*-json.log
|
||||
|
||||
pipeline_stages:
|
||||
# Parse Docker JSON logs
|
||||
- json:
|
||||
expressions:
|
||||
output: log
|
||||
stream: stream
|
||||
attrs: attrs
|
||||
|
||||
# Extract container name from path
|
||||
- regex:
|
||||
expression: '/var/lib/docker/containers/(?P<container_id>[^/]+)/.*'
|
||||
source: filename
|
||||
|
||||
# Add labels
|
||||
- labels:
|
||||
stream:
|
||||
container_id:
|
||||
|
||||
# Output the log line
|
||||
- output:
|
||||
source: output
|
||||
|
||||
# System logs (optional)
|
||||
# - job_name: system
|
||||
# static_configs:
|
||||
# - targets:
|
||||
# - localhost
|
||||
# labels:
|
||||
# job: varlogs
|
||||
# __path__: /var/log/*.log
|
||||
42
docker-compose/monitoring/redis/redis.conf
Normal file
42
docker-compose/monitoring/redis/redis.conf
Normal file
@@ -0,0 +1,42 @@
|
||||
# Redis Configuration Template
|
||||
# Copy this file to ./config/redis/redis.conf
|
||||
|
||||
# Network
|
||||
bind 0.0.0.0
|
||||
protected-mode yes
|
||||
port 6379
|
||||
|
||||
# General
|
||||
daemonize no
|
||||
supervised no
|
||||
pidfile /var/run/redis_6379.pid
|
||||
loglevel notice
|
||||
logfile ""
|
||||
|
||||
# Persistence - AOF (Append Only File)
|
||||
appendonly yes
|
||||
appendfilename "appendonly.aof"
|
||||
appendfsync everysec
|
||||
no-appendfsync-on-rewrite no
|
||||
auto-aof-rewrite-percentage 100
|
||||
auto-aof-rewrite-min-size 64mb
|
||||
|
||||
# Persistence - RDB (Snapshotting)
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
stop-writes-on-bgsave-error yes
|
||||
rdbcompression yes
|
||||
rdbchecksum yes
|
||||
dbfilename dump.rdb
|
||||
dir /data
|
||||
|
||||
# Memory Management
|
||||
maxmemory 256mb
|
||||
maxmemory-policy allkeys-lru
|
||||
|
||||
# Security
|
||||
# requirepass yourpassword # Uncomment and set a strong password
|
||||
|
||||
# Limits
|
||||
maxclients 10000
|
||||
@@ -25,7 +25,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8089:80"
|
||||
- '8089:80'
|
||||
volumes:
|
||||
- ./nextcloud/html:/var/www/html
|
||||
- /mnt/nextcloud-data:/var/www/html/data # Large data on separate drive
|
||||
@@ -41,7 +41,7 @@ services:
|
||||
- OVERWRITEPROTOCOL=https
|
||||
- OVERWRITEHOST=nextcloud.${DOMAIN}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/status.php"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost/status.php']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -51,22 +51,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=File sync and collaboration"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=File sync and collaboration'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.nextcloud.loadbalancer.server.port=8089'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-nextcloud"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-nextcloud'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
nextcloud-db:
|
||||
image: mariadb:10.11
|
||||
@@ -83,8 +83,8 @@ services:
|
||||
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
|
||||
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
|
||||
labels:
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Nextcloud database"
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Nextcloud database'
|
||||
|
||||
# Mealie - Recipe manager
|
||||
mealie:
|
||||
@@ -95,7 +95,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- '9000:9000'
|
||||
volumes:
|
||||
- ./mealie/data:/app/data
|
||||
environment:
|
||||
@@ -107,22 +107,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Recipe manager and meal planner"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Recipe manager and meal planner'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.mealie.loadbalancer.server.port=9000'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-mealie"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-mealie'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# WordPress - Blog/website platform
|
||||
wordpress:
|
||||
@@ -133,7 +133,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8088:80"
|
||||
- '8088:80'
|
||||
volumes:
|
||||
- ./wordpress/html:/var/www/html
|
||||
environment:
|
||||
@@ -142,7 +142,7 @@ services:
|
||||
- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD}
|
||||
- WORDPRESS_DB_NAME=wordpress
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -152,22 +152,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Blog and website platform"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Blog and website platform'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.wordpress.loadbalancer.server.port=8088'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-wordpress"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-wordpress'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
wordpress-db:
|
||||
image: mariadb:10.11
|
||||
@@ -183,8 +183,8 @@ services:
|
||||
- MYSQL_USER=wordpress
|
||||
- MYSQL_PASSWORD=${WORDPRESS_DB_PASSWORD}
|
||||
labels:
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=WordPress database"
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=WordPress database'
|
||||
|
||||
# Gitea - Self-hosted Git service
|
||||
gitea:
|
||||
@@ -204,7 +204,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3010:3000"
|
||||
- '3010:3000'
|
||||
volumes:
|
||||
- ./gitea/data:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
@@ -218,7 +218,7 @@ services:
|
||||
- GITEA__database__USER=gitea
|
||||
- GITEA__database__PASSWD=${GITEA_DB_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:3000/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -228,22 +228,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Self-hosted Git service"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Self-hosted Git service'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.gitea.loadbalancer.server.port=3010'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-gitea"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-gitea'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
gitea-db:
|
||||
image: postgres:14-alpine
|
||||
@@ -258,8 +258,8 @@ services:
|
||||
- POSTGRES_PASSWORD=${GITEA_DB_PASSWORD}
|
||||
- POSTGRES_DB=gitea
|
||||
labels:
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Gitea database"
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Gitea database'
|
||||
|
||||
|
||||
# Jupyter Lab - Interactive computing notebooks
|
||||
@@ -272,7 +272,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8890:8888"
|
||||
- '8890:8888'
|
||||
volumes:
|
||||
- ./config/jupyter:/home/jovyan/work
|
||||
environment:
|
||||
@@ -292,22 +292,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Jupyter Lab for data science and ML"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-jupyter"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-jupyter'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
volumes:
|
||||
nextcloud-db-data:
|
||||
|
||||
@@ -33,22 +33,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Distributed transcoding server"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-tdarr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-tdarr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Tdarr Node - Transcoding worker
|
||||
# No web UI - controlled by server
|
||||
@@ -75,9 +75,9 @@ services:
|
||||
labels:
|
||||
- homelab.category=media
|
||||
- homelab.description=Tdarr transcoding worker node
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-tdarr"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-tdarr'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Unmanic - Another transcoding option
|
||||
unmanic:
|
||||
@@ -88,7 +88,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8889:8888"
|
||||
- '8889:8888'
|
||||
volumes:
|
||||
- ./unmanic/config:/config
|
||||
- /mnt/media:/library
|
||||
@@ -101,22 +101,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=media"
|
||||
- 'homelab.description=Library optimization and transcoding"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- '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.docker.network=traefik-network"
|
||||
- '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=jasper-unmanic"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
- '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=jasper-unmanic'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
networks:
|
||||
homelab-network:
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "9898:9898"
|
||||
- '9898:9898'
|
||||
volumes:
|
||||
- ./backrest/data:/data
|
||||
- ./backrest/config:/config
|
||||
@@ -27,7 +27,7 @@ services:
|
||||
- BACKREST_CONFIG=/config/config.json
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9898/"]
|
||||
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:9898/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -35,22 +35,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=utilities"
|
||||
- 'homelab.description=Backup management with restic"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=utilities'
|
||||
- 'homelab.description=Backup management with restic'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.backrest.loadbalancer.server.port=9898'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-backrest"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-backrest'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Duplicati - Backup solution
|
||||
duplicati:
|
||||
@@ -61,7 +61,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8200:8200"
|
||||
- '8200:8200'
|
||||
volumes:
|
||||
- ./duplicati/config:/config
|
||||
- /opt/stacks:/source/stacks:ro
|
||||
@@ -72,7 +72,7 @@ services:
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8200/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:8200/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -80,22 +80,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=utilities"
|
||||
- 'homelab.description=Backup software with encryption"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=utilities'
|
||||
- 'homelab.description=Backup software with encryption'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.duplicati.loadbalancer.server.port=8200'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-duplicati"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-duplicati'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Form.io - Form builder
|
||||
# Uncomment and configure if formio/formio image becomes available
|
||||
@@ -107,13 +107,13 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "3002:3001"
|
||||
- '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/"]
|
||||
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3001/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -124,22 +124,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=utilities"
|
||||
- 'homelab.description=Form builder platform"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=utilities'
|
||||
- 'homelab.description=Form builder platform'
|
||||
# Traefik labels
|
||||
- 'traefik.enable=true"
|
||||
- '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"
|
||||
- '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"
|
||||
- 'traefik.http.services.formio.loadbalancer.server.port=3001'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-formio"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-formio'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
formio-mongo:
|
||||
image: mongo:4.4
|
||||
@@ -148,8 +148,8 @@ services:
|
||||
networks:
|
||||
- homelab-network
|
||||
labels:
|
||||
- 'homelab.category=utilities"
|
||||
- 'homelab.description=Form.io database"
|
||||
- 'homelab.category=utilities'
|
||||
- 'homelab.description=Form.io database'
|
||||
|
||||
# Bitwarden (Vaultwarden) - Password manager
|
||||
# Note: SSO disabled for browser extension and mobile app compatibility
|
||||
@@ -162,7 +162,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8091:80"
|
||||
- '8091:80'
|
||||
volumes:
|
||||
- ./vaultwarden/data:/data
|
||||
environment:
|
||||
@@ -178,7 +178,7 @@ services:
|
||||
# - SMTP_USERNAME=${SMTP_USERNAME}
|
||||
# - SMTP_PASSWORD=${SMTP_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:80/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -187,23 +187,23 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# ==========================================
|
||||
# Service metadata
|
||||
- 'homelab.category=utilities"
|
||||
- 'homelab.description=Self-hosted password manager (Bitwarden)"
|
||||
- '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"
|
||||
- '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"
|
||||
# - 'traefik.http.routers.vaultwarden.middlewares=authelia@docker'
|
||||
- 'traefik.http.services.vaultwarden.loadbalancer.server.port=80'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-vaultwarden"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-vaultwarden'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# Authelia Redis - Session storage for Authelia
|
||||
# No web UI - backend service
|
||||
|
||||
@@ -19,12 +19,12 @@ services:
|
||||
- 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
|
||||
- '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:
|
||||
@@ -37,22 +37,22 @@ services:
|
||||
# TRAEFIK CONFIGURATION
|
||||
labels:
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=downloaders"
|
||||
- 'homelab.description=VPN client for secure downloads"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=downloaders'
|
||||
- 'homelab.description=VPN client for secure downloads'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.qbittorrent.loadbalancer.server.port=8081'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-qbittorrent"
|
||||
- "sablier.sessionDuration=1h"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-qbittorrent'
|
||||
- 'sablier.sessionDuration=1h'
|
||||
|
||||
# qBittorrent - Torrent client
|
||||
qbittorrent:
|
||||
@@ -68,7 +68,7 @@ services:
|
||||
memory: 256M
|
||||
container_name: qbittorrent
|
||||
restart: unless-stopped
|
||||
network_mode: "service:gluetun" # Routes through VPN in same compose file
|
||||
network_mode: 'service:gluetun' # Routes through VPN in same compose file
|
||||
volumes:
|
||||
- ./qbittorrent/config:/config
|
||||
- /mnt/downloads:/downloads
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8087:80"
|
||||
- '8087:80'
|
||||
volumes:
|
||||
- ./dokuwiki/config:/config
|
||||
environment:
|
||||
@@ -25,22 +25,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=File-based wiki"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=File-based wiki'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.dokuwiki.loadbalancer.server.port=8087'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-dokuwiki"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-dokuwiki'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
# BookStack - Documentation platform
|
||||
# Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity
|
||||
@@ -52,7 +52,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "6875:80"
|
||||
- '6875:80'
|
||||
volumes:
|
||||
- ./bookstack/config:/config
|
||||
environment:
|
||||
@@ -66,7 +66,7 @@ services:
|
||||
- DB_PASSWORD=${BOOKSTACK_DB_PASSWORD}
|
||||
- APP_KEY=base64:NsYD8+8MAvtBhK8xw9p8pxQDy4x8aOQi/78M3CsseAw=
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -76,22 +76,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=Documentation and wiki platform"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=Documentation and wiki platform'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.bookstack.loadbalancer.server.port=6875'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-bookstack"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-bookstack'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
bookstack-db:
|
||||
image: mariadb:10.11
|
||||
@@ -107,8 +107,8 @@ services:
|
||||
- MYSQL_USER=bookstack
|
||||
- MYSQL_PASSWORD=${BOOKSTACK_DB_PASSWORD}
|
||||
labels:
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=BookStack database"
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=BookStack database'
|
||||
|
||||
# MediaWiki - Wiki platform
|
||||
mediawiki:
|
||||
@@ -119,7 +119,7 @@ services:
|
||||
- homelab-network
|
||||
- traefik-network
|
||||
ports:
|
||||
- "8086:80"
|
||||
- '8086:80'
|
||||
volumes:
|
||||
- ./mediawiki/images:/var/www/html/images
|
||||
- ./mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php
|
||||
@@ -129,7 +129,7 @@ services:
|
||||
- MEDIAWIKI_DB_USER=mediawiki
|
||||
- MEDIAWIKI_DB_PASSWORD=${MEDIAWIKI_DB_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -139,22 +139,22 @@ services:
|
||||
labels:
|
||||
# TRAEFIK CONFIGURATION
|
||||
# Service metadata
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=MediaWiki platform"
|
||||
- 'traefik.enable=true"
|
||||
- 'traefik.docker.network=traefik-network"
|
||||
- 'com.centurylinklabs.watchtower.enable=true'
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=MediaWiki platform'
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.docker.network=traefik-network'
|
||||
# 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"
|
||||
- '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"
|
||||
- 'traefik.http.services.mediawiki.loadbalancer.server.port=8086'
|
||||
# Sablier configuration
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=jasper-mediawiki"
|
||||
- "sablier.start-on-demand=true"
|
||||
- 'sablier.enable=true'
|
||||
- 'sablier.group=jasper-mediawiki'
|
||||
- 'sablier.start-on-demand=true'
|
||||
|
||||
mediawiki-db:
|
||||
image: mariadb:10.11
|
||||
@@ -170,8 +170,8 @@ services:
|
||||
- MYSQL_USER=mediawiki
|
||||
- MYSQL_PASSWORD=${MEDIAWIKI_DB_PASSWORD}
|
||||
labels:
|
||||
- 'homelab.category=productivity"
|
||||
- 'homelab.description=MediaWiki database"
|
||||
- 'homelab.category=productivity'
|
||||
- 'homelab.description=MediaWiki database'
|
||||
|
||||
volumes:
|
||||
bookstack-db-data:
|
||||
|
||||
Reference in New Issue
Block a user