Add Docker compose templates and configurations

This commit is contained in:
kelinfoxy
2026-03-17 17:29:50 -04:00
parent b28a11f619
commit 58306f7fe6
67 changed files with 738607 additions and 93 deletions

View File

@@ -0,0 +1,18 @@
# Core Stack Environment Variables
TZ=America/New_York
PUID=1000
PGID=1000
SERVER_IP=192.168.4.4
SERVER_HOSTNAME=jasper
DOMAIN=kelinreij.duckdns.org
DUCKDNS_SUBDOMAINS=kelinreij
DUCKDNS_TOKEN=41ef7faa-fc93-41d2-a32f-340fd2b75b2f
PIHOLE_PASSWORD=Tiberi0u$
AUTHELIA_JWT_SECRET=f6e604660a5b0cc9b6e506374c1de1309e7fb7999fae330701b3ffeb8c874a8f7cb55781186e72c81f46edba4fe6874020d5edc00562bfcbf7b555e5a483e025
AUTHELIA_SESSION_SECRET=27a9a3b300b73de99537488c56133ab062b5b7d6474063db18942314a6b0dc045ee0f42b2f8a526afb12e2a1480e1539087b4a5a67334fe825116739adf27c1b
AUTHELIA_STORAGE_ENCRYPTION_KEY=b9a5374a75524340001bb715dc35b666dbf2288ab2cef5181a4d1ec8ec7c4ed16cab1ab9dfd981341d4b55b86b3d4b61be7f568cae896c38c08e02cd758b1cd4
AUTHELIA_ADMIN_PASSWORD_HASH==19=65536,t=3,p=4+A+otnHSpfW0Xr7uXV3XZ9sy7YxaI

View File

@@ -0,0 +1,107 @@
# Core Infrastructure Services
# 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
labels:
- com.getarcaneapp.arcane.icon=https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/duckdns.svg
traefik:
# Reverse proxy and SSL termination - core routing service, must always run
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
- ./traefik/logs:/logs
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik-network
- homelab-network
labels:
- com.getarcaneapp.arcane.icon=https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/traefik.svg
- 'homelab.category=core'
- 'homelab.description=Reverse proxy and SSL termination'
- 'traefik.enable=true'
- 'traefik.http.routers.traefik.rule=Host(`traefik.kelinreij.duckdns.org`)'
- '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
image: authelia/authelia:latest
container_name: authelia
restart: unless-stopped
environment:
- TZ=${TZ}
ports:
- '9091:9091'
volumes:
- ./authelia/config:/config
- ./authelia/secrets:/secrets
networks:
- traefik-network
- homelab-network
labels:
- com.getarcaneapp.arcane.icon=https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/authelia.svg
- 'homelab.category=core'
- 'homelab.description=Single sign-on authentication'
- 'traefik.enable=true'
- 'traefik.http.routers.authelia.rule=Host(`auth.kelinreij.duckdns.org`)'
- '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'
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.kelinreij.duckdns.org/'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=X-Secret'
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
networks:
traefik-network:
external: true
homelab-network:
external: true
x-dockge:
urls:
- https://auth.kelinreij.duckdns.org
- http://192.168.4.4:9091
- https://traefik.kelinreij.duckdns.org
- http://192.168.4.4:8080
x-arcane:
icon: https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/traefik.svg
urls:
- https://auth.kelinreij.duckdns.org
- http://192.168.4.4:9091
- https://traefik.kelinreij.duckdns.org
- http://192.168.4.4:8080

View 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

View File

@@ -0,0 +1,57 @@
# Traefik Static Configuration
# Copy to /opt/stacks/traefik/traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
api:
dashboard: true
insecure: true # Dashboard accessible via Traefik route with Authelia
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
certificatesResolvers:
letsencrypt:
acme:
email: kelinshomelab@gmail.com # Your email for Let's Encrypt notifications
caServer: https://acme-v02.api.letsencrypt.org/directory # Use staging for testing
storage: /letsencrypt/acme.json
# DNS challenge - For wildcard certificates (*.yourdomain.duckdns.org)
# Works with DuckDNS - requires DUCKDNS_TOKEN in environment
dnsChallenge:
provider: duckdns
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false # Only expose services with traefik.enable=true
network: traefik-network
file:
directory: /dynamic
watch: true
log:
level: DEBUG # DEBUG, INFO, WARN, ERROR
filePath: ./logs/traefik.log
accessLog:
filePath: ./logs/access.log
bufferingSize: 100

View File

@@ -0,0 +1,54 @@
# Traefik Static Configuration
# Copy to /opt/stacks/traefik/traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
api:
dashboard: true
insecure: false # Dashboard accessible via Traefik route with Authelia
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
certificatesResolvers:
letsencrypt:
acme:
email: kelinshomelab@gmail.com # Your email for Let's Encrypt notifications
caServer: https://acme-v02.api.letsencrypt.org/directory # Use staging for testing
storage: /letsencrypt/acme.json
# DNS challenge - For wildcard certificates (*.yourdomain.duckdns.org)
# Works with DuckDNS - requires DUCKDNS_TOKEN in environment
dnsChallenge:
provider: duckdns
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false # Only expose services with traefik.enable=true
network: traefik-network
file:
directory: /dynamic
watch: true
log:
level: DEBUG # DEBUG, INFO, WARN, ERROR
filePath: /var/log/traefik/traefik.log
accessLog:
filePath: /var/log/traefik/access.log
bufferingSize: 100

View File

@@ -0,0 +1,18 @@
http:
routers:
# Individual Services
homeassistant:
rule: "Host(`ha.kelinreij.duckdns.org`)"
entryPoints:
- websecure
service: homeassistant
tls:
certResolver: letsencrypt
services:
# Individual Services
homeassistant:
loadBalancer:
servers:
- url: "http://192.168.4.5:8123"
passHostHeader: true

View File

@@ -0,0 +1,358 @@
# Manual Routes for Remote Server: jarvis
# Auto-generated by EZ-Homelab
# Last updated: 2026-02-11 20:40:04
#
# These routes proxy HTTPS traffic from core Traefik to HTTP services on remote server
http:
routers:
arcane-jarvis:
rule: "Host(`arcane.jarvis.kelinreij.duckdns.org`)"
service: arcane-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
backrest-jarvis:
rule: "Host(`backrest.jarvis.kelinreij.duckdns.org`)"
service: backrest-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
dockge-jarvis:
rule: "Host(`dockge.jarvis.kelinreij.duckdns.org`)"
service: dockge-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
dozzle-jarvis:
rule: "Host(`dozzle.jarvis.kelinreij.duckdns.org`)"
service: dozzle-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
formio-jarvis:
rule: "Host(`formio.jarvis.kelinreij.duckdns.org`)"
service: formio-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
glances-jarvis:
rule: "Host(`glances.jarvis.kelinreij.duckdns.org`)"
service: glances-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
jellyfin-jarvis:
rule: "Host(`jellyfin.kelinreij.duckdns.org`)"
service: jellyfin-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
jellyseerr-jarvis:
rule: "Host(`jellyseerr.kelinreij.duckdns.org`)"
service: jellyseerr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
lazylibrarian-jarvis:
rule: "Host(`lazylibrarian.kelinreij.duckdns.org`)"
service: lazylibrarian-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
lidarr-jarvis:
rule: "Host(`lidarr.kelinreij.duckdns.org`)"
service: lidarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
motioneye-jarvis:
rule: "Host(`motioneye.kelinreij.duckdns.org`)"
service: motioneye-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
mylar3-jarvis:
rule: "Host(`mylar3.kelinreij.duckdns.org`)"
service: mylar3-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
n8n-jarvis:
rule: "Host(`n8n.kelinreij.duckdns.org`)"
service: n8n-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
nextcloud-jarvis:
rule: "Host(`nextcloud.kelinreij.duckdns.org`)"
service: nextcloud-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
prowlarr-jarvis:
rule: "Host(`prowlarr.kelinreij.duckdns.org`)"
service: prowlarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
qbittorrent-jarvis:
rule: "Host(`qbittorrent.kelinreij.duckdns.org`)"
service: qbittorrent-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
radarr-jarvis:
rule: "Host(`radarr.kelinreij.duckdns.org`)"
service: radarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
readarr-jarvis:
rule: "Host(`readarr.kelinreij.duckdns.org`)"
service: readarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
sonarr-jarvis:
rule: "Host(`sonarr.kelinreij.duckdns.org`)"
service: sonarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
tdarr-jarvis:
rule: "Host(`tdarr.kelinreij.duckdns.org`)"
service: tdarr-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
unmanic-jarvis:
rule: "Host(`unmanic.kelinreij.duckdns.org`)"
service: unmanic-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
wordpress-jarvis:
rule: "Host(`wordpress.kelinreij.duckdns.org`)"
service: wordpress-jarvis-service
entrypoints:
- websecure
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
services:
arcane-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:3552"
passHostHeader: true
backrest-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:9898"
passHostHeader: true
dockge-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:5001"
passHostHeader: true
dozzle-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8085"
passHostHeader: true
formio-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:3002"
passHostHeader: true
glances-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:61208"
passHostHeader: true
jellyfin-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8096"
passHostHeader: true
jellyseerr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:5055"
passHostHeader: true
lazylibrarian-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:5299"
passHostHeader: true
lidarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8686"
passHostHeader: true
motioneye-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8765"
passHostHeader: true
mylar3-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8090"
passHostHeader: true
n8n-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:5678"
passHostHeader: true
nextcloud-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8089"
passHostHeader: true
prowlarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:9696"
passHostHeader: true
qbittorrent-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8200"
passHostHeader: true
radarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:7878"
passHostHeader: true
readarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8787"
passHostHeader: true
sonarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8989"
passHostHeader: true
tdarr-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8266"
passHostHeader: true
unmanic-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:9999"
passHostHeader: true
wordpress-jarvis-service:
loadBalancer:
servers:
- url: "http://192.168.4.11:8088"
passHostHeader: true

View File

@@ -0,0 +1,16 @@
# Sablier Middleware for Remote Server: jarvis
# Auto-generated by EZ-Homelab
# Last updated: 2026-02-11 20:40:04
#
# This middleware enables lazy loading for services on jarvis
# Each server has its own Sablier instance managing local containers
http:
middlewares:
sablier-jarvis:
plugin:
sablier:
sablierUrl: "http://192.168.4.11:10000"
sessionDuration: "5m"
dynamic:
theme: "hacker-terminal"

View File

@@ -0,0 +1,131 @@
# 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.yourdomain.duckdns.org/
authResponseHeaders:
- X-Secret
trustForwardHeader: true
sablier-jasper-vaultwarden:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-vaultwarden
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Vaultwarden
theme: ghost
show-details-by-default: true
sablier-jasper-bookstack:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-bookstack
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Bookstack
theme: ghost
show-details-by-default: true
sablier-jasper-calibre-web:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-calibre-web
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Calibre Web
theme: ghost
show-details-by-default: true
sablier-jasper-dozzle:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-dozzle
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: dozzle
theme: ghost
show-details-by-default: true
sablier-jasper-dokuwiki:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-dokuwiki
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: DokuWiki
theme: ghost
show-details-by-default: true
sablier-jasper-assistant:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-assistant
sessionDuration: 30m
ignoreUserAgent: curl
dynamic:
displayName: EZ-Assistant
theme: ghost
show-details-by-default: true
sablier-jasper-gitea:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-gitea
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Gitea
theme: ghost
show-details-by-default: true
sablier-jasper-glances:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-glances
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Glances
theme: ghost
show-details-by-default: true
sablier-jasper-jupyter:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-jupyter
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Jupyter
theme: ghost
show-details-by-default: true
sablier-jasper-mealie:
plugin:
sablier:
sablierUrl: http://sablier-service:10000
group: jasper-mealie
sessionDuration: 5m
ignoreUserAgent: curl
dynamic:
displayName: Mealie
theme: ghost
show-details-by-default: true

View File

@@ -0,0 +1,16 @@
# Wildcard Certificate Configuration
# This creates a router to trigger wildcard certificate generation
http:
routers:
wildcard-cert-request:
rule: "Host(`kelinreij.duckdns.org`) || Host(`www.kelinreij.duckdns.org`)"
entryPoints:
- websecure
service: noop@internal
tls:
certResolver: letsencrypt
domains:
- main: "kelinreij.duckdns.org"
sans:
- "*.kelinreij.duckdns.org"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long