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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
external: true
|
||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user