Add multi-server support and update docs

Introduce multi-server architecture documentation and reorganize README content. Top-level README now documents Core vs Remote server roles, links to local docs instead of wiki pages, and highlights Traefik/Sablier multi-server behavior. docker-compose/README.md was rewritten to be a template-style reference with single- and multi-server deployment guidance, Traefik label examples, and sablier usage; dockge README was moved into docker-compose/dockge/. docker-compose/core/README.md was updated to describe core responsibilities, shared CA artifacts, and startup order for multi-server deployments. Several obsolete/duplicated docs and action reports were removed and a new multi-server deployment doc was added to centralize on-demand/remote service guidance. Overall this cleans up legacy docs and documents the multi-server workflow and TLS/shared-CA requirements.
This commit is contained in:
kelinfoxy
2026-02-05 22:30:52 -05:00
parent 84b2cabacc
commit 5cbb106160
27 changed files with 803 additions and 3300 deletions

View File

@@ -17,10 +17,12 @@
**Category:** Core Infrastructure
**Docker Image:** [authelia/authelia](https://hub.docker.com/r/authelia/authelia)
**Default Stack:** `core.yml`
**Default Stack:** `core` (deployed on core server only)
**Web UI:** `https://auth.${DOMAIN}`
**Authentication:** Self-authenticating (login portal)
**Multi-Server Note:** Authelia runs only on the core server and provides centralized SSO authentication for all services across all servers. Remote server services use the `authelia@docker` middleware to authenticate against the core server's Authelia instance.
## What is Authelia?
Authelia is an open-source authentication and authorization server providing single sign-on (SSO) and two-factor authentication (2FA) for your applications via a web portal. It acts as a gatekeeper between Traefik and your services.

View File

@@ -15,10 +15,12 @@
**Category:** Core Infrastructure
**Docker Image:** [linuxserver/duckdns](https://hub.docker.com/r/linuxserver/duckdns)
**Default Stack:** `core.yml`
**Default Stack:** `core` (deployed on core server only)
**Web UI:** No web interface (runs silently)
**Authentication:** Not applicable
**Multi-Server Note:** DuckDNS runs only on the core server where Traefik generates the wildcard SSL certificate. This single certificate is used for all services across all servers in your homelab.
## What is DuckDNS?
DuckDNS is a free dynamic DNS (DDNS) service that provides you with a memorable subdomain under `duckdns.org` and keeps it updated with your current IP address. It's perfect for homelabs where your ISP provides a dynamic IP address that changes periodically.

View File

@@ -15,17 +15,25 @@
## Overview
**Category:** Core Infrastructure
**Docker Image:** [sablierapp/sablier](https://hub.docker.com/r/sablierapp/sablier)
**Default Stack:** `core.yml`
**Web UI:** No web UI (API only)
**Authentication:** None required
**Category:** Resource Management
**Docker Image:** [acouvreur/sablier](https://hub.docker.com/r/acouvreur/sablier)
**Default Stack:** `sablier` (separate stack, deployed on each server)
**Web UI:** `https://sablier.${DOMAIN}` (on core server)
**Authentication:** Protected by Authelia (SSO)
**Purpose:** On-demand container startup and resource management
**Multi-Server Note:** Each server runs its own Sablier instance that only manages local containers. This eliminates the need for remote Docker API connections and creates a more resilient architecture.
## What is Sablier?
Sablier is a lightweight service that enables lazy loading for Docker containers. It automatically starts containers when they're accessed through Traefik and stops them after a period of inactivity, helping to conserve system resources and reduce power consumption.
**In EZ-Homelab's multi-server architecture**, each server runs its own Sablier instance managing only local containers, providing:
- **Decentralized Control**: No single point of failure
- **Simplified Networking**: No remote Docker API connections needed
- **Better Security**: Each Sablier only accesses local Docker socket
- **Independent Operation**: Remote servers function even if core server is down
### Key Features
- **On-Demand Startup:** Containers start automatically when accessed
- **Automatic Shutdown:** Containers stop after configurable inactivity periods
@@ -63,24 +71,43 @@ When a request comes in for a service with Sablier enabled:
## Configuration in AI-Homelab
Sablier is deployed as part of the core infrastructure stack and requires no additional configuration for basic operation. It automatically discovers services with the appropriate labels.
Sablier is deployed as a **separate stack** (`/opt/stacks/sablier/`) on each server and requires no additional configuration for basic operation. It automatically discovers services with the appropriate labels.
### Deployment Location
**Core Server:** `/opt/stacks/sablier/docker-compose.yml`
**Remote Servers:** `/opt/stacks/sablier/docker-compose.yml`
Each Sablier instance:
- Runs independently on its server
- Connects only to local Docker socket (`/var/run/docker.sock`)
- Manages containers on the same server only
- Has its own web dashboard (if enabled)
### Service Integration
Add these labels to any service that should use lazy loading:
**Local Service (same server as Sablier):**
```yaml
services:
myservice:
# ... other configuration ...
labels:
- "sablier.enable=true"
- "sablier.group=core-myservice" # Optional: group related services
- "sablier.group=${SERVER_HOSTNAME}-myservice" # Include server hostname
- "sablier.start-on-demand=true"
- "traefik.enable=true"
- "traefik.http.routers.myservice.rule=Host(`myservice.${DOMAIN}`)"
# ... other Traefik labels ...
```
**Note on Group Naming:** Always prefix group names with `${SERVER_HOSTNAME}` to avoid conflicts between servers:
- Core server: `core-myservice`
- Remote Pi: `pi-myservice`
- Remote NAS: `nas-myservice`
### Advanced Configuration
For services requiring custom timeouts or group management:

View File

@@ -16,10 +16,12 @@
**Category:** Core Infrastructure
**Docker Image:** [traefik](https://hub.docker.com/_/traefik)
**Default Stack:** `core.yml`
**Default Stack:** `core` (multi-provider on core server), `infrastructure` or separate (local-only on remote servers)
**Web UI:** `https://traefik.${DOMAIN}`
**Authentication:** Protected by Authelia (SSO)
**Multi-Server Note:** The core server runs a multi-provider Traefik instance that discovers services across all servers. Remote servers run their own local Traefik instances for container discovery only.
## What is Traefik?
Traefik is a modern HTTP reverse proxy and load balancer designed for microservices and containerized applications. It automatically discovers services and configures routing, making it ideal for Docker environments.
@@ -45,6 +47,7 @@ Traefik is a modern HTTP reverse proxy and load balancer designed for microservi
## How It Works
**Single Server Architecture:**
```
Internet → Your Domain → Router (Port 80/443) → Traefik
├→ Plex (plex.domain.com)
@@ -53,6 +56,18 @@ Internet → Your Domain → Router (Port 80/443) → Traefik
└→ [Other Services]
```
**Multi-Server Architecture:**
```
Internet → Router (Port 80/443) → Core Server Traefik (Multi-Provider)
├→ Local Services (plex.domain.com)
├→ Remote Server 1 via Docker TLS :2376
│ ├→ Remote Traefik (discovery only)
│ └→ Services (pi-service.domain.com)
└→ Remote Server 2 via Docker TLS :2376
├→ Remote Traefik (discovery only)
└→ Services (nas-service.domain.com)
```
### Request Flow
1. **User visits** `https://plex.yourdomain.duckdns.org`
@@ -83,6 +98,20 @@ Traefik automatically:
## Configuration in AI-Homelab
### Multi-Server Deployment
**Core Server (Primary Traefik):**
- Multi-provider configuration discovers services on all servers
- Receives all external traffic (ports 80/443 forwarded)
- Manages SSL certificates for all services
- Routes traffic to local and remote services
**Remote Servers (Secondary Traefik):**
- Local Docker provider only (discovers containers on same server)
- No external ports exposed
- Services use labels for local discovery
- Core Traefik connects via Docker TLS (port 2376)
### Directory Structure
```
@@ -96,6 +125,8 @@ Traefik automatically:
### Static Configuration (`traefik.yml`)
**Core Server Configuration (Multi-Provider):**
```yaml
api:
dashboard: true # Enable web dashboard
@@ -119,20 +150,46 @@ certificatesResolvers:
acme:
email: your-email@example.com
storage: /acme.json
# For testing environments: Use Let's Encrypt staging to avoid rate limits
# caServer: https://acme-staging-v02.api.letsencrypt.org/directory
dnsChallenge:
provider: duckdns
# Note: Explicit resolvers can cause DNS propagation check failures
# Remove resolvers to use system's DNS for better DuckDNS TXT record resolution
providers:
docker:
# Local Docker provider
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-network
# Optional: Additional Docker providers for remote servers
# Uncomment and configure for multi-server setup
# docker:
# endpoint: "tcp://remote-server-ip:2376"
# tls:
# ca: /path/to/ca.pem
# cert: /path/to/cert.pem
# key: /path/to/key.pem
# exposedByDefault: false
file:
directory: /dynamic
watch: true
```
**Remote Server Configuration (Local Only):**
```yaml
api:
dashboard: false # Disable dashboard on remote servers
entryPoints:
websecure:
address: ":443" # Internal only, not exposed
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: /dynamic
watch: true
network: traefik-network
```
### Environment Variables
@@ -144,6 +201,8 @@ ACME_EMAIL=your-email@example.com
### Service Labels Example
**For Local Services (same server as Traefik):**
```yaml
services:
myservice:
@@ -159,6 +218,42 @@ services:
- traefik-network
```
**For Remote Services (different server):**
Don't use Traefik labels. Instead, create an external host file on the core server:
```yaml
# /opt/stacks/core/traefik/dynamic/external-host-remoteserver.yml
http:
routers:
myservice-remote:
rule: "Host(`myservice.${DOMAIN}`)"
entryPoints:
- websecure
service: myservice-remote
tls:
certResolver: letsencrypt
middlewares:
- authelia@docker
services:
myservice-remote:
loadBalancer:
servers:
- url: "http://remote-server-ip:8080"
passHostHeader: true
```
labels:
- "traefik.enable=true"
- "traefik.http.routers.myservice.rule=Host(`myservice.${DOMAIN}`)"
- "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls=true" # Uses wildcard cert automatically
- "traefik.http.routers.myservice.middlewares=authelia@docker"
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
networks:
- traefik-network
```
## Official Resources
- **Website:** https://traefik.io