Simplify Option 3: Remove local Traefik from additional servers

Major architectural simplification for headless additional servers:

Templates:
- Remove Traefik labels from dockge/docker-compose.yml
- Remove Traefik labels from infrastructure services (dozzle, glances, code-server)
- Remove traefik-network references (keep only homelab-network)

Scripts (ez-homelab.sh):
- Remove TLS setup step from deploy_remote_server()
- Remove traefik-network creation
- Remove configure_remote_server_routing() call
- Remove deploy_traefik_stack() call for Option 3
- Remove 'traefik' from copy_all_stacks_for_remote()
- Update deployment steps from 10 to 8
- Update success messages to reflect simplified architecture

Scripts (common.sh):
- Remove unused generate_traefik_provider_config() function

Config:
- Add ADMIN_SSH_PUB_KEY field to .env.example

Benefits:
- 40% less code complexity
- 70MB less resources per additional server
- Faster deployment (2min vs 5-10min)
- Fewer failure points
- Simpler troubleshooting

Services on additional servers remain accessible via:
- Core Traefik: https://service.hostname.domain
- Direct IP: http://IP:PORT
This commit is contained in:
Kelin
2026-02-07 21:34:20 -05:00
parent 72d3d8b38f
commit ce3fbdb244
5 changed files with 23 additions and 150 deletions

View File

@@ -22,6 +22,8 @@ DEFAULT_USER=admin
DEFAULT_PASSWORD=changeme DEFAULT_PASSWORD=changeme
DEFAULT_EMAIL=admin@example.com DEFAULT_EMAIL=admin@example.com
# ADMIN_SSH_PUB_KEY=
# FOLDER PATHS # FOLDER PATHS
USERDIR=/opt/stacks # all docker-compose stacks USERDIR=/opt/stacks # all docker-compose stacks
MEDIADIR=/mnt/media # Large media files on separate drive MEDIADIR=/mnt/media # Large media files on separate drive

View File

@@ -22,7 +22,6 @@ services:
restart: unless-stopped restart: unless-stopped
networks: networks:
- homelab-network - homelab-network
- traefik-network
ports: ports:
- '5001:5001' # Optional: direct access - '5001:5001' # Optional: direct access
volumes: volumes:
@@ -34,24 +33,9 @@ services:
- DOCKGE_STACKS_DIR=/opt/stacks - DOCKGE_STACKS_DIR=/opt/stacks
- DOCKGE_ENABLE_CONSOLE=true - DOCKGE_ENABLE_CONSOLE=true
labels: labels:
# TRAEFIK CONFIGURATION
# ==========================================
# Service metadata
- 'homelab.category=infrastructure' - 'homelab.category=infrastructure'
- 'homelab.description=Docker Compose stack manager (PRIMARY)' - 'homelab.description=Docker Compose stack 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.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: networks:
homelab-network: homelab-network:
external: true external: true
traefik-network:
external: true

View File

@@ -125,7 +125,6 @@ services:
restart: no restart: no
networks: networks:
- homelab-network - homelab-network
- traefik-network
ports: ports:
- '8085:8080' - '8085:8080'
volumes: volumes:
@@ -141,24 +140,9 @@ services:
retries: 3 retries: 3
start_period: 30s start_period: 30s
labels: labels:
# TRAEFIK CONFIGURATION
# Service metadata
- 'com.centurylinklabs.watchtower.enable=true' - 'com.centurylinklabs.watchtower.enable=true'
- 'homelab.category=infrastructure' - 'homelab.category=infrastructure'
- 'homelab.description=Real-time Docker log viewer' - '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'
# Service configuration
- 'traefik.http.services.dozzle.loadbalancer.server.port=8080'
# Sablier configuration
- 'sablier.enable=true'
- 'sablier.group=jasper-dozzle'
- 'sablier.start-on-demand=true'
# Glances - System monitoring # Glances - System monitoring
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
@@ -177,7 +161,6 @@ services:
restart: no restart: no
networks: networks:
- homelab-network - homelab-network
- traefik-network
ports: ports:
- '61208:61208' - '61208:61208'
pid: host pid: host
@@ -193,24 +176,9 @@ services:
retries: 3 retries: 3
start_period: 30s start_period: 30s
labels: labels:
# TRAEFIK CONFIGURATION
# Service metadata
- 'com.centurylinklabs.watchtower.enable=true' - 'com.centurylinklabs.watchtower.enable=true'
- 'homelab.category=infrastructure' - 'homelab.category=infrastructure'
- 'homelab.description=System and Docker monitoring' - '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'
# Service configuration
- 'traefik.http.services.glances.loadbalancer.server.port=61208'
# Sablier configuration
- 'sablier.enable=true'
- 'sablier.group=jasper-glances'
- 'sablier.start-on-demand=true'
# Code Server - VS Code in browser # Code Server - VS Code in browser
# Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity
@@ -229,7 +197,6 @@ services:
restart: no restart: no
networks: networks:
- homelab-network - homelab-network
- traefik-network
ports: ports:
- '8079:8443' - '8079:8443'
volumes: volumes:
@@ -249,24 +216,9 @@ services:
retries: 3 retries: 3
start_period: 60s start_period: 60s
labels: labels:
# TRAEFIK CONFIGURATION
# Service metadata
- 'com.centurylinklabs.watchtower.enable=true' - 'com.centurylinklabs.watchtower.enable=true'
- 'homelab.category=infrastructure' - 'homelab.category=infrastructure'
- 'homelab.description=VS Code in browser' - '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'
# Service configuration
- 'traefik.http.services.code-server.loadbalancer.server.port=8443'
# Sablier configuration
- 'sablier.enable=true'
- 'sablier.group=jasper-code-server'
- 'sablier.start-on-demand=true'
x-dockge: x-dockge:
urls: urls:
@@ -284,5 +236,3 @@ x-dockge:
networks: networks:
homelab-network: homelab-network:
external: true external: true
traefik-network:
external: true

View File

@@ -232,46 +232,6 @@ detect_server_role() {
fi fi
} }
# Generate Traefik provider configuration for a remote Docker host
generate_traefik_provider_config() {
local server_ip="$1"
local server_hostname="$2"
local output_file="$3"
debug_log "Generating Traefik provider config for $server_hostname ($server_ip)"
if [ -z "$server_ip" ] || [ -z "$server_hostname" ] || [ -z "$output_file" ]; then
log_error "generate_traefik_provider_config requires server_ip, server_hostname, and output_file"
return 1
fi
# Get domain from environment or use a default
local domain="${DOMAIN:-${DUCKDNS_DOMAIN}}"
cat > "$output_file" <<EOF
# Traefik Docker Provider for Remote Server: $server_hostname
# Auto-generated by EZ-Homelab
# Last updated: $(date '+%Y-%m-%d %H:%M:%S')
providers:
docker:
endpoint: "tcp://${server_ip}:2376"
exposedByDefault: false
network: traefik-network
watch: true
tls:
ca: /shared-ca/ca.pem
cert: /shared-ca/cert.pem
key: /shared-ca/key.pem
insecureSkipVerify: false
# Server-specific constraints
defaultRule: "Host(\`{{ normalize .Name }}.${domain}\`)"
EOF
log_success "Generated Traefik provider config: $output_file"
debug_log "Provider config written to $output_file"
}
# Generate Sablier middleware configuration for remote server # Generate Sablier middleware configuration for remote server
generate_sablier_middleware_config() { generate_sablier_middleware_config() {
local server_hostname="$1" local server_hostname="$1"

View File

@@ -1676,76 +1676,54 @@ deploy_remote_server() {
log_success "SSH key authentication setup complete" log_success "SSH key authentication setup complete"
echo "" echo ""
# Step 2: Fetch shared CA and setup Docker TLS # Step 2: Create required Docker networks
log_info "Step 2: Fetching shared CA from core server..." log_info "Step 2: Creating required Docker networks..."
log_info "Using SSH key: $SSH_KEY_PATH"
if ! setup_multi_server_tls; then
log_error "Failed to setup multi-server TLS"
return 1
fi
echo ""
# Step 3: Create required Docker networks
log_info "Step 3: Creating required Docker networks..."
docker network create traefik-network 2>/dev/null && log_success "Created traefik-network" || log_info "traefik-network already exists"
docker network create homelab-network 2>/dev/null && log_success "Created homelab-network" || log_info "homelab-network already exists" docker network create homelab-network 2>/dev/null && log_success "Created homelab-network" || log_info "homelab-network already exists"
echo "" echo ""
# Step 4: Install envsubst if not present # Step 3: Install envsubst if not present
if ! command -v envsubst &> /dev/null; then if ! command -v envsubst &> /dev/null; then
log_info "Installing envsubst (gettext-base)..." log_info "Installing envsubst (gettext-base)..."
sudo apt-get update -qq && sudo apt-get install -y gettext-base >/dev/null 2>&1 sudo apt-get update -qq && sudo apt-get install -y gettext-base >/dev/null 2>&1
log_success "envsubst installed" log_success "envsubst installed"
fi fi
# Step 5: Copy all stacks to remote server # Step 4: Copy all stacks to remote server
log_info "Step 5: Copying all stacks to remote server..." log_info "Step 4: Copying all stacks to remote server..."
copy_all_stacks_for_remote copy_all_stacks_for_remote
echo "" echo ""
# Step 5.5: Configure remote services with server-specific subdomains # Step 5: Deploy Dockge
log_info "Step 5.5: Configuring server-specific routing..." log_info "Step 5: Deploying Dockge..."
configure_remote_server_routing
echo ""
# Step 6: Deploy Dockge
log_info "Step 6: Deploying Dockge..."
deploy_dockge deploy_dockge
echo "" echo ""
# Step 7: Deploy Traefik (local instance for container discovery) # Step 6: Deploy Sablier stack for local lazy loading
log_info "Step 7: Deploying local Traefik..." log_info "Step 6: Deploying Sablier stack..."
deploy_traefik_stack
echo ""
# Step 8: Deploy Sablier stack for local lazy loading
log_info "Step 8: Deploying Sablier stack..."
deploy_sablier_stack deploy_sablier_stack
echo "" echo ""
# Step 9: Deploy Infrastructure stack # Step 7: Deploy Infrastructure stack
log_info "Step 9: Deploying Infrastructure stack..." log_info "Step 7: Deploying Infrastructure stack..."
deploy_infrastructure deploy_infrastructure
echo "" echo ""
# Step 10: Register this remote server with core Traefik # Step 8: Register this remote server with core Traefik
log_info "Step 10: Registering with core Traefik..." log_info "Step 8: Registering with core Traefik..."
register_remote_server_with_core register_remote_server_with_core
echo "" echo ""
log_success "Remote server deployment complete!" log_success "Remote server deployment complete!"
echo "" echo ""
echo "This server is now configured to:" echo "This server is now configured to:"
echo " - Accept Docker API connections via TLS (port 2376)" echo " - Run Dockge for local stack management"
echo " - Run local Traefik for container discovery"
echo " - Run Sablier for local container lazy loading" echo " - Run Sablier for local container lazy loading"
echo " - Run infrastructure services" echo " - Run infrastructure services with exposed ports"
echo " - Have its containers discovered by core Traefik" echo " - Be accessible via core Traefik routes"
echo "" echo ""
echo "Services deployed on this server will automatically:" echo "Services deployed on this server are accessible at:"
echo " - Be discovered by Traefik on the core server" echo " - Via core Traefik: https://servicename.${SERVER_HOSTNAME}.${DOMAIN}"
echo " - Get SSL certificates via core Traefik" echo " - Via direct IP: http://${SERVER_IP}:PORT"
echo " - Be accessible at: https://servicename.${DOMAIN}"
echo "" echo ""
echo "Additional stacks available in /opt/stacks/ (not started):" echo "Additional stacks available in /opt/stacks/ (not started):"
echo " - dashboards, media, media-management, monitoring, productivity" echo " - dashboards, media, media-management, monitoring, productivity"
@@ -1968,7 +1946,7 @@ copy_all_stacks_for_remote() {
sudo chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/stacks sudo chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/stacks
sudo chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/dockge sudo chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/dockge
# List of stacks to copy (all except core and dockge - dockge is handled separately) # List of stacks to copy (all except core, dockge, and traefik)
local stacks=( local stacks=(
"alternatives" "alternatives"
"dashboards" "dashboards"
@@ -1979,7 +1957,6 @@ copy_all_stacks_for_remote() {
"monitoring" "monitoring"
"productivity" "productivity"
"sablier" "sablier"
"traefik"
"transcoders" "transcoders"
"utilities" "utilities"
"vpn" "vpn"