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:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user