Files
EZ-Homelab/docs/script-audit-report.md
EZ-Homelab Assistant 90a26a9ac4 Fix homepage Traefik network routing and update configurations
- Add traefik.docker.network=traefik-network label to homepage service
- Prevent Traefik from using wrong IP from homelab-network
- Resolve 504 Gateway Timeout issues after authentication
- Update various docker-compose configurations and templates
- Clean up unused configuration files
2026-01-30 23:29:00 -05:00

10 KiB

EZ-Homelab Script Audit Report

Generated: 30 January 2026

Executive Summary

The ez-homelab.sh script is a comprehensive Bash-based deployment tool for the EZ-Homelab project. It handles system setup, Docker configuration, and multi-stage service deployment. The script supports three main deployment modes with varying complexity. While functional for infrastructure-only deployments (Option 3), the core-only deployment (Option 2) has critical issues with Authelia secret generation and configuration that prevent successful deployment.

Script Architecture

Global Variables & Constants

  • Color codes: RED, GREEN, YELLOW, BLUE, NC for console output formatting
  • Logging functions: log_info(), log_success(), log_warning(), log_error()
  • Deployment flags: DEPLOY_CORE, DEPLOY_INFRASTRUCTURE, DEPLOY_DASHBOARDS, SETUP_STACKS
  • Configuration variables: DOMAIN, SERVER_IP, ADMIN_USER, etc.
  • Path variables: SCRIPT_DIR, REPO_DIR, ACTUAL_USER

Core Functions

1. replace_env_placeholders()

Purpose: Replaces ${VAR} placeholders in files with actual environment variable values Process:

  • Takes file path as argument
  • Uses grep to find all ${VAR} patterns
  • Checks if each variable exists in environment
  • Uses sed for replacement: s|\${VAR}|${!VAR}|g
  • Accumulates missing variables in MISSING_VARS_SUMMARY Issues:
  • Only reports missing variables at end, doesn't fail deployment
  • No validation of replacement success
2. generate_shared_ca()

Purpose: Creates shared Certificate Authority for multi-server TLS Process:

  • Creates /opt/stacks/core/shared-ca/ directory
  • Generates 4096-bit RSA CA key and certificate (365 days validity)
  • Sets ownership to $ACTUAL_USER:$ACTUAL_USER Output: ca.pem, ca-key.pem files
3. setup_multi_server_tls()

Purpose: Configures TLS for remote Docker access using shared CA Process:

  • Prompts for core server IP if not set
  • Tests SSH connectivity (key auth first, then password)
  • Fetches CA certificates from core server via SCP
  • Calls setup_docker_tls() if successful Issues:
  • Complex SSH authentication logic
  • No fallback if CA fetch fails
  • TLS_ISSUES_SUMMARY populated but not always accurate
4. load_env_file()

Purpose: Loads existing configuration from .env file Process:

  • Checks for $REPO_DIR/.env existence
  • Sources the file if found
  • Displays current configuration values
  • Returns 0 if file exists, 1 if not Issues: No validation of loaded values
5. save_env_file()

Purpose: Persists configuration to .env file Process:

  • Creates .env from .env.example if needed
  • Updates values using sed replacements
  • For core deployment: generates Authelia secrets and password hash Critical Issue: Authelia secret generation is here, but may not be called in all deployment paths
6. prompt_for_values()

Purpose: Interactive configuration collection Process:

  • Shows current/default values
  • Allows user to accept defaults or enter custom values
  • Handles sensitive inputs (passwords) with -s flag
  • Sets ADMIN_* variables for core deployment Issues: Complex logic with many conditional branches
7. system_setup()

Purpose: Performs initial system configuration (requires root) Process:

  1. System package updates
  2. Installs prerequisites (curl, wget, git, etc.)
  3. Installs/configures Docker and Docker Compose
  4. Generates shared CA
  5. Configures Docker TLS
  6. Sets up UFW firewall
  7. Configures automatic updates
  8. Creates Docker networks
  9. Sets directory ownership Issues:
  • Requires logout/login for Docker group changes
  • No rollback on failure
8. deploy_dockge()

Purpose: Deploys Dockge stack management interface Process:

  • Copies compose file and .env to /opt/dockge/
  • Replaces placeholders
  • Runs docker compose up -d Output: Dockge service running
9. deploy_core()

Purpose: Deploys core infrastructure stack Process:

  1. Copies compose file and .env to /opt/stacks/core/
  2. Copies Traefik and Authelia config templates
  3. Replaces placeholders in all config files
  4. Generates shared CA
  5. Replaces Authelia-specific secrets and user data
  6. Runs docker compose up -d Critical Issues:
  • Assumes Authelia secrets exist in environment
  • No validation that secrets were generated
  • Complex placeholder replacement logic
10. deploy_infrastructure() / deploy_dashboards()

Purpose: Deploy additional service stacks Process: Similar to deploy_core but simpler

  • Copy files, replace placeholders, deploy Issues: Conditional Authelia middleware removal when core not deployed
11. setup_docker_tls()

Purpose: Configures Docker daemon for TLS Process:

  1. Creates TLS directory
  2. Uses shared CA or generates local CA
  3. Generates server and client certificates
  4. Updates Docker daemon.json
  5. Modifies systemd service for TCP 2376
  6. Restarts Docker service
12. setup_stacks_for_dockge()

Purpose: Prepares all service stacks for Dockge management Process:

  • Iterates through predefined stack list
  • Copies compose files and configs
  • Replaces placeholders
  • Prepares but doesn't deploy stacks

Deployment Flow Analysis

Option 1: Default Setup

Flags: DEPLOY_CORE=true, DEPLOY_INFRASTRUCTURE=true, DEPLOY_DASHBOARDS=true, SETUP_STACKS=true Flow:

  1. System setup (if needed)
  2. Prompt for values
  3. Save env file (generates Authelia secrets)
  4. Deploy Dockge
  5. Deploy core (uses generated secrets)
  6. Deploy infrastructure
  7. Deploy dashboards
  8. Setup stacks for Dockge

Option 2: Core Only

Flags: DEPLOY_CORE=true, DEPLOY_INFRASTRUCTURE=false, DEPLOY_DASHBOARDS=true, SETUP_STACKS=true Flow:

  1. System setup (if needed)
  2. Prompt for values
  3. Save env file (generates Authelia secrets)
  4. Deploy Dockge
  5. Deploy core (uses generated secrets)
  6. Deploy dashboards
  7. Setup stacks for Dockge

Option 3: Infrastructure Only

Flags: DEPLOY_CORE=false, DEPLOY_INFRASTRUCTURE=true, DEPLOY_DASHBOARDS=false, SETUP_STACKS=true Flow:

  1. System setup (if needed)
  2. Prompt for values
  3. Save env file (no Authelia secrets generated)
  4. Setup multi-server TLS
  5. Deploy Dockge
  6. Deploy infrastructure
  7. Setup stacks for Dockge

Critical Issues Identified

1. Authelia Secret Generation Timing (Option 2)

Problem: In Option 2, save_env_file() is called and should generate Authelia secrets, but the deployment may fail if secrets aren't properly set. Root Cause: The save_env_file() function generates secrets only when DEPLOY_CORE=true, but the generation logic may not execute or persist correctly. Impact: Authelia container fails to start due to missing JWT_SECRET, SESSION_SECRET, or STORAGE_ENCRYPTION_KEY

2. Environment Variable Persistence

Problem: After save_env_file(), the script sources the .env file, but there may be a timing issue where variables aren't available for deploy_core(). Evidence: The script does source "$REPO_DIR/.env" in perform_deployment(), but if secrets weren't saved properly, they'll be empty.

3. Placeholder Replacement Order

Problem: replace_env_placeholders() is called during deployment, but if environment variables are missing, replacements fail silently. Impact: Configuration files contain literal ${VAR} strings instead of actual values.

4. Authelia Password Hash Generation

Problem: Password hash generation happens in save_env_file(), but requires Docker to be running and Authelia image to be available. Issues:

  • May fail if Docker isn't ready
  • Uses complex docker run command that could timeout
  • No fallback if hash generation fails

5. Multi-Server TLS Complexity

Problem: setup_multi_server_tls() has complex SSH logic that can fail in multiple ways. Issues:

  • SSH key vs password detection unreliable
  • No retry logic for connection failures
  • Error reporting doesn't clearly indicate resolution steps

6. Directory Creation Race Conditions

Problem: Script creates directories with sudo, then tries to write files as regular user. Potential Issue: Permission conflicts if ownership isn't set correctly.

Recommendations

Immediate Fixes for Option 2

  1. Add Secret Validation: After save_env_file(), validate that all required Authelia secrets exist before proceeding with deployment.

  2. Improve Error Handling: Make replace_env_placeholders() fail deployment if critical variables are missing.

  3. Add Authelia Health Check: After core deployment, verify Authelia container is running and healthy.

Structural Improvements

  1. Separate Secret Generation: Move Authelia secret generation to a dedicated function called before deployment.

  2. Add Pre-deployment Validation: Create a validation function that checks all required environment variables and Docker state before starting deployment.

  3. Simplify TLS Setup: Reduce complexity in multi-server TLS setup with better error handling and user guidance.

  4. Add Rollback Capability: Implement cleanup functions for failed deployments.

Code Quality

  1. Reduce Function Complexity: Break down large functions like deploy_core() into smaller, testable units.

  2. Add Logging: Increase verbosity for debugging deployment issues.

  3. Configuration Management: Consider using a configuration file format (YAML/JSON) instead of .env for complex setups.

Testing Recommendations

  1. Unit Test Functions: Test individual functions like replace_env_placeholders() and generate_shared_ca() in isolation.

  2. Integration Testing: Test each deployment option in a clean environment.

  3. Error Scenario Testing: Test failure modes (missing Docker, network issues, invalid credentials).

Conclusion

The ez-homelab.sh script is a solid foundation for automated homelab deployment, but Option 2 (Core Only) has critical issues with Authelia secret management that prevent reliable deployment. The script needs focused improvements in error handling, validation, and secret generation to achieve the reliability required for critical infrastructure deployment.