Documentation updates

This commit is contained in:
kelinfoxy
2026-01-24 21:40:51 -05:00
parent a1c9a0958b
commit a59862c988
15 changed files with 93 additions and 2026 deletions

View File

@@ -1,20 +1,18 @@
# AI-Homelab Setup Scripts
# EZ-Homelab Setup Scripts
This directory contains scripts for automated AI-Homelab deployment and management:
This directory contains scripts for automated EZ-Homelab deployment and management:
1. **setup-homelab.sh** - System preparation
2. **deploy-homelab.sh** - Core infrastructure deployment
3. **reset-test-environment.sh** - Safe test environment cleanup
4. **reset-ondemand-services.sh** - Reload services for Sablier lazy loading
1. **ez-homelab.sh** - Unified setup and deployment script
2. **reset-test-environment.sh** - Safe test environment cleanup
3. **reset-ondemand-services.sh** - Reload services for Sablier lazy loading
## setup-homelab.sh
## ez-homelab.sh
Automated first-run setup script for preparing a fresh Debian installation for AI-Homelab deployment.
> You can skip this if you have the following completed already.
Or run it to verify.
Unified guided setup and deployment script that handles both system preparation and service deployment in a single interactive session.
### What It Does
**System Preparation (when needed):**
1. **System Update** - Updates all system packages
2. **Install Dependencies** - Installs required packages (curl, git, etc.)
3. **Install Docker** - Adds Docker repository and installs Docker Engine with Compose V2
@@ -24,23 +22,40 @@ Or run it to verify.
7. **Create Directories** - Sets up `/opt/stacks`, `/opt/dockge`, `/mnt/media`, `/mnt/downloads`
8. **Create Docker Networks** - Creates homelab-network, traefik-network, and media-network
**Configuration & Deployment:**
1. **Interactive Setup** - Guides you through domain, admin credentials, and service selection
2. **Authelia Secrets Generation** - Generates JWT, session, and encryption keys
3. **Admin User Creation** - Prompts for admin username, email, and password
4. **Service Deployment** - Deploys selected stacks based on your choices
5. **SSL Certificate Setup** - Obtains wildcard certificate via DNS challenge
6. **Dockge Access** - Opens Dockge web UI when ready
### Usage
```bash
cd ~/AI-Homelab
cd ~/EZ-Homelab
# Make the script executable (if needed)
chmod +x scripts/setup-homelab.sh
chmod +x scripts/ez-homelab.sh
# Run with sudo
sudo ./scripts/setup-homelab.sh
# Run the script (will use sudo when needed)
./scripts/ez-homelab.sh
```
### Interactive Options
The script will prompt you to:
- Enter your domain (e.g., yourdomain.duckdns.org)
- Provide DuckDNS token
- Set admin credentials for Authelia
- Choose which service stacks to deploy
- Configure additional settings as needed
### After Running
1. Log out and log back in for group changes to take effect
2. Edit `.env` file with your configuration
3. Run `deploy-homelab.sh` to deploy core infrastructure and Dockge
1. Access Dockge at `https://dockge.yourdomain.duckdns.org`
2. Log in with your configured Authelia credentials
3. Deploy additional stacks through Dockge's web UI
### NVIDIA GPU Support
@@ -61,14 +76,16 @@ This manual approach avoids driver conflicts that often occur with automated ins
### Requirements
- Fresh Debian installation (Debian 11 or 12)
- Fresh Debian/Ubuntu installation (or existing system)
- Root access (via sudo)
- Internet connection
- Ports 80 and 443 forwarded to your server
### Tested On
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
- Ubuntu 20.04/22.04
### Notes
@@ -80,117 +97,6 @@ This manual approach avoids driver conflicts that often occur with automated ins
---
## deploy-homelab.sh
Automated deployment script that deploys the core infrastructure and Dockge. Run this after editing your `.env` file.
### What It Does
1. **Validate Prerequisites** - Checks for Docker, .env file, and proper configuration
2. **Create Directories** - Sets up `/opt/stacks/core` and `/opt/stacks/infrastructure`
3. **Create Docker Networks** - Ensures homelab-network, traefik-network, and media-network exist
4. **Deploy Core Stack** - Deploys DuckDNS, Traefik, and Authelia
5. **Deploy Infrastructure Stack** - Deploys Dockge, Portainer, Pi-hole, and monitoring tools
6. **Wait for Dockge** - Waits for Dockge web UI to become accessible
7. **Open Browser** - Automatically opens Dockge in your default browser
### Usage
```bash
# From the AI-Homelab directory
cd AI-Homelab
# Ensure .env is configured
cp .env.example .env
nano .env # Edit with your values
# Make the script executable (if needed)
chmod +x scripts/deploy-homelab.sh
# Run WITHOUT sudo (run as your regular user)
./scripts/deploy-homelab.sh
```
### After Running
The script will automatically open `https://dockge.yourdomain.duckdns.org` in your browser when Dockge is ready.
1. Log in to Dockge using your Authelia credentials (configured in `/opt/stacks/core/authelia/users_database.yml`)
2. Deploy additional stacks through Dockge's web UI:
- `dashboards.yml` - Homepage and Homarr
- `media.yml` - Plex, Jellyfin, Sonarr, Radarr, etc.
- `media-extended.yml` - Readarr, Lidarr, etc.
- `homeassistant.yml` - Home Assistant and accessories
- `productivity.yml` - Nextcloud, Gitea, wikis
- `monitoring.yml` - Grafana, Prometheus
- `utilities.yml` - Backups, password manager
### Requirements
- Docker and Docker Compose installed
- `.env` file configured with your domain and credentials
- User must be in docker group (handled by setup-homelab.sh)
### Browser Detection
The script will attempt to open Dockge using:
- `xdg-open` (default on most Linux desktops)
- `gnome-open` (GNOME desktop)
- `firefox` or `google-chrome` (direct browser launch)
If no browser is detected, it will display the URL for manual access.
### Manual Deployment Alternative
If you prefer to deploy manually instead of using the script:
```bash
# Deploy core stack
mkdir -p /opt/stacks/core
cp docker-compose/core.yml /opt/stacks/core/docker-compose.yml
cp -r config-templates/traefik /opt/stacks/core/
cp -r config-templates/authelia /opt/stacks/core/
cp .env /opt/stacks/core/
cd /opt/stacks/core && docker compose up -d
# Deploy infrastructure stack
mkdir -p /opt/stacks/infrastructure
cp docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml
cp .env /opt/stacks/infrastructure/
cd /opt/stacks/infrastructure && docker compose up -d
# Manually open: https://dockge.yourdomain.duckdns.org
```
### Troubleshooting
**Script says "Docker daemon is not running":**
- Run: `sudo systemctl start docker`
- Or log out and back in if you just added yourself to docker group
**Script says ".env file not found":**
- Run: `cp .env.example .env` and edit with your values
**Dockge doesn't open automatically:**
- The script will display the URL to open manually
- Wait a minute for services to fully start
- Check logs: `docker compose -f /opt/stacks/infrastructure/docker-compose.yml logs dockge`
**Traefik SSL certificate errors:**
- Initial certificate generation can take a few minutes
- Check DuckDNS token is correct in .env
- Verify your domain is accessible from the internet
### Notes
- Run as regular user (NOT with sudo)
- Validates .env configuration before deployment
- Waits up to 60 seconds for Dockge to become ready
- Automatically copies .env to stack directories
- Safe to run multiple times (idempotent)
---
## reset-test-environment.sh
Safe cleanup script for testing environments. Completely removes all deployed services, data, and configurations while preserving the underlying system setup. Intended for development and testing scenarios only.
@@ -231,8 +137,7 @@ sudo ./scripts/reset-test-environment.sh
The system will be returned to a clean state ready for re-deployment:
1. Ensure `.env` file is properly configured
2. Run: `sudo ./scripts/setup-homelab.sh` (if needed)
3. Run: `./scripts/deploy-homelab.sh`
2. Run: `./scripts/ez-homelab.sh`
### Requirements

View File

@@ -1,465 +0,0 @@
#!/bin/bash
# EZ-Homelab Deployment Script
# This script deploys homelab services with flexible options
# Run after: 1) setup-homelab.sh and 2) editing .env file
# Run as: ./deploy-homelab.sh
set -e # Exit on error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Log functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [ "$EUID" -eq 0 ]; then
log_error "Please do NOT run this script as root or with sudo"
log_info "Run as: ./deploy-homelab.sh"
exit 1
fi
# Get script directory (EZ-Homelab/scripts)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
REPO_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
log_info "EZ-Homelab Deployment Script"
echo ""
# Check if .env file exists
if [ ! -f "$REPO_DIR/.env" ]; then
log_error ".env file not found!"
log_info "Please create and configure your .env file first:"
echo " cd $REPO_DIR"
echo " cp .env.example .env"
echo " nano .env"
exit 1
fi
# Check if Docker is installed and running
if ! command -v docker &> /dev/null; then
log_error "Docker is not installed. Please run setup-homelab.sh first."
exit 1
fi
if ! docker info &> /dev/null; then
log_error "Docker daemon is not running or you don't have permission."
log_info "Try: sudo systemctl start docker"
log_info "Or log out and log back in for group changes to take effect"
exit 1
fi
log_success "Docker is available and running"
echo ""
# Load environment variables for domain check
source "$REPO_DIR/.env"
if [ -z "$DOMAIN" ]; then
log_error "DOMAIN is not set in .env file"
log_info "Please edit .env and set your DuckDNS domain"
exit 1
fi
log_info "Using domain: $DOMAIN"
echo ""
# Deployment options menu
echo "=========================================="
echo " EZ-HOMELAB DEPLOYMENT OPTIONS"
echo "=========================================="
echo ""
echo "Choose your deployment scenario:"
echo ""
echo "1) Full deployment (recommended for new servers)"
echo " - Deploy core infrastructure (Traefik, Authelia, etc.)"
echo " - Deploy infrastructure stack (Dockge, Pi-hole, etc.)"
echo " - Deploy dashboards (Homepage, Homarr)"
echo " - Setup all remaining stacks for Dockge"
echo ""
echo "2) Skip core stack (for existing homelab servers)"
echo " - Skip core infrastructure deployment"
echo " - Deploy infrastructure stack (Dockge, Pi-hole, etc.)"
echo " - Deploy dashboards (Homepage, Homarr)"
echo " - Setup all remaining stacks for Dockge"
echo ""
echo "3) Setup stacks only (no deployment)"
echo " - Setup all stacks in Dockge without deploying any"
echo " - Useful for preparing stacks for manual deployment"
echo ""
read -p "Enter your choice (1-3): " DEPLOY_CHOICE
case $DEPLOY_CHOICE in
1)
DEPLOY_CORE=true
DEPLOY_INFRASTRUCTURE=true
DEPLOY_DASHBOARDS=true
SETUP_STACKS=true
log_info "Selected: Full deployment"
;;
2)
DEPLOY_CORE=false
DEPLOY_INFRASTRUCTURE=true
DEPLOY_DASHBOARDS=true
SETUP_STACKS=true
log_info "Selected: Skip core stack"
;;
3)
DEPLOY_CORE=false
DEPLOY_INFRASTRUCTURE=false
DEPLOY_DASHBOARDS=false
SETUP_STACKS=true
log_info "Selected: Setup stacks only"
;;
*)
log_error "Invalid choice. Please run the script again."
exit 1
;;
esac
echo ""
# Function to replace environment variables in config files
replace_env_vars() {
local config_dir="$1"
local env_file="$2"
log_info "Processing environment variables in $config_dir..."
# Find all files in the config directory
find "$config_dir" -type f \( -name "*.yml" -o -name "*.yaml" -o -name "*.conf" -o -name "*.json" \) | while read -r file; do
# Extract all ${VAR_NAME} patterns from the file
vars_found=$(grep -o '\${[^}]*}' "$file" | sed 's/\${//' | sed 's/}//' | sort | uniq)
if [ -n "$vars_found" ]; then
log_info "Processing file: $(basename "$file")"
for var in $vars_found; do
# Check if variable exists in .env file
if grep -q "^${var}=" "$env_file" 2>/dev/null; then
# Get the value from .env file
value=$(grep "^${var}=" "$env_file" | cut -d'=' -f2- | sed 's/^"//' | sed 's/"$//')
# Escape special characters for sed
escaped_value=$(printf '%s\n' "$value" | sed 's/[[\.*^$()+?{|]/\\&/g')
# Replace in file
sed -i "s|\${${var}}|${escaped_value}|g" "$file"
log_info " ✓ Replaced \${$var}"
else
log_warning " ⚠ Variable \${$var} not found in .env file - leaving as-is"
fi
done
fi
done
}
# Function to setup stacks without deploying them
setup_stacks_for_dockge() {
log_info "Setting up all stacks for Dockge..."
# List of stacks to setup
STACKS=("vpn" "media" "media-management" "monitoring" "productivity" "utilities" "alternatives" "homeassistant" "nextcloud")
for stack in "${STACKS[@]}"; do
STACK_DIR="/opt/stacks/$stack"
REPO_STACK_DIR="$REPO_DIR/docker-compose/$stack"
if [ -d "$REPO_STACK_DIR" ]; then
log_info "Setting up $stack stack..."
# Create stack directory
mkdir -p "$STACK_DIR"
# Copy docker-compose.yml
if [ -f "$REPO_STACK_DIR/docker-compose.yml" ]; then
cp "$REPO_STACK_DIR/docker-compose.yml" "$STACK_DIR/"
cp "$REPO_DIR/.env" "$STACK_DIR/.env"
# Copy any additional config directories
for config_dir in "$REPO_STACK_DIR"/*/; do
if [ -d "$config_dir" ] && [ "$(basename "$config_dir")" != "." ]; then
cp -r "$config_dir" "$STACK_DIR/"
fi
done
# Replace environment variables in the stack configuration
replace_env_vars "$STACK_DIR" "$STACK_DIR/.env"
log_success "$stack stack prepared for Dockge"
else
log_warning "$stack stack docker-compose.yml not found, skipping..."
fi
else
log_warning "$stack stack directory not found in repo, skipping..."
fi
done
log_success "All stacks prepared for Dockge deployment"
echo ""
}
# Step 1: Create required directories
log_info "Step 1: Creating required directories..."
mkdir -p /opt/stacks/core
mkdir -p /opt/stacks/infrastructure
mkdir -p /opt/dockge/data
log_success "Directories created"
echo ""
# Step 2: Create Docker networks (if they don't exist)
log_info "Step 2: Creating Docker networks..."
docker network create homelab-network 2>/dev/null && log_success "Created homelab-network" || log_info "homelab-network already exists"
docker network create traefik-network 2>/dev/null && log_success "Created traefik-network" || log_info "traefik-network already exists"
docker network create media-network 2>/dev/null && log_success "Created media-network" || log_info "media-network already exists"
echo ""
# Step 3: Deploy core infrastructure (DuckDNS, Traefik, Authelia, Gluetun)
if [ "$DEPLOY_CORE" = true ]; then
log_info "Step 3: Deploying core infrastructure stack..."
log_info " - DuckDNS (Dynamic DNS)"
log_info " - Traefik (Reverse Proxy with SSL)"
log_info " - Authelia (Single Sign-On)"
log_info " - Gluetun (VPN Client)"
echo ""
# Copy core stack files with overwrite checks
if [ -f "/opt/stacks/core/docker-compose.yml" ]; then
log_warning "docker-compose.yml already exists in /opt/stacks/core/"
log_info "Creating backup: docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)"
cp /opt/stacks/core/docker-compose.yml /opt/stacks/core/docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)
fi
cp "$REPO_DIR/docker-compose/core/docker-compose.yml" /opt/stacks/core/docker-compose.yml
if [ -d "/opt/stacks/core/traefik" ]; then
log_warning "Traefik configuration already exists in /opt/stacks/core/"
log_info "Creating backup: traefik.backup.$(date +%Y%m%d_%H%M%S)"
mv /opt/stacks/core/traefik /opt/stacks/core/traefik.backup.$(date +%Y%m%d_%H%M%S)
fi
cp -r "$REPO_DIR/config-templates/traefik" /opt/stacks/core/
# Detect server hostname and update configuration
log_info "Detecting server hostname..."
DETECTED_HOSTNAME=$(hostname)
if [ -n "$DETECTED_HOSTNAME" ] && [ "$DETECTED_HOSTNAME" != "debian" ]; then
log_info "Detected hostname: $DETECTED_HOSTNAME"
# Update SERVER_HOSTNAME in the copied .env file
sed -i "s/SERVER_HOSTNAME=.*/SERVER_HOSTNAME=$DETECTED_HOSTNAME/" /opt/stacks/core/.env
# Update SERVER_HOSTNAME in the source .env file for future deployments
sed -i "s/SERVER_HOSTNAME=.*/SERVER_HOSTNAME=$DETECTED_HOSTNAME/" "$REPO_DIR/.env"
# Update sablier.yml with detected hostname
sed -i "s/debian-/$DETECTED_HOSTNAME-/g" /opt/stacks/core/traefik/dynamic/sablier.yml
log_success "Updated configuration with detected hostname: $DETECTED_HOSTNAME"
else
log_info "Using default hostname 'debian' (hostname detection failed or returned default)"
fi
echo ""
if [ -d "/opt/stacks/core/authelia" ]; then
log_warning "Authelia configuration already exists in /opt/stacks/core/"
log_info "Creating backup: authelia.backup.$(date +%Y%m%d_%H%M%S)"
mv /opt/stacks/core/authelia /opt/stacks/core/authelia.backup.$(date +%Y%m%d_%H%M%S)
fi
cp -r "$REPO_DIR/config-templates/authelia" /opt/stacks/core/
# Replace domain placeholders in Authelia config (legacy hardcoded replacement)
sed -i "s/your-domain.duckdns.org/${DOMAIN}/g" /opt/stacks/core/authelia/configuration.yml
if [ -f "/opt/stacks/core/.env" ]; then
log_warning ".env already exists in /opt/stacks/core/"
log_info "Creating backup: .env.backup.$(date +%Y%m%d_%H%M%S)"
cp /opt/stacks/core/.env /opt/stacks/core/.env.backup.$(date +%Y%m%d_%H%M%S)
fi
cp "$REPO_DIR/.env" /opt/stacks/core/.env
# Automatically replace all environment variables in config files
replace_env_vars "/opt/stacks/core" "/opt/stacks/core/.env"
# Legacy hardcoded replacements (keeping for backward compatibility)
# These will be overridden by the automatic replacement above if variables exist
sed -i "s/admin/${AUTHELIA_ADMIN_USER}/g" /opt/stacks/core/authelia/users_database.yml
sed -i "s/admin@example.com/${AUTHELIA_ADMIN_EMAIL}/g" /opt/stacks/core/authelia/users_database.yml
sed -i "s|\$argon2id\$v=19\$m=65536,t=3,p=4\$CHANGEME|${AUTHELIA_ADMIN_PASSWORD}|g" /opt/stacks/core/authelia/users_database.yml
# Deploy core stack
cd /opt/stacks/core
docker compose up -d
log_success "Core infrastructure deployed"
echo ""
# Wait for Traefik to be ready
log_info "Waiting for Traefik to initialize..."
sleep 10
# Check if Traefik is healthy
if docker ps | grep -q "traefik.*Up"; then
log_success "Traefik is running"
else
log_warning "Traefik container check inconclusive, continuing..."
fi
echo ""
else
log_info "Skipping core infrastructure deployment"
echo ""
fi
# Step 4: Deploy infrastructure stack (Dockge and monitoring tools)
if [ "$DEPLOY_INFRASTRUCTURE" = true ]; then
log_info "Step 4: Deploying infrastructure stack..."
log_info " - Dockge (Docker Compose Manager)"
log_info " - Pi-hole (DNS Ad Blocker)"
log_info " - Watchtower (Container Updates)"
log_info " - Dozzle (Log Viewer)"
log_info " - Glances (System Monitor)"
log_info " - Docker Proxy (Security)"
echo ""
# Copy infrastructure stack
cp "$REPO_DIR/docker-compose/infrastructure/docker-compose.yml" /opt/stacks/infrastructure/docker-compose.yml
cp "$REPO_DIR/.env" /opt/stacks/infrastructure/.env
# Deploy infrastructure stack
cd /opt/stacks/infrastructure
docker compose up -d
log_success "Infrastructure stack deployed"
echo ""
else
log_info "Skipping infrastructure stack deployment"
echo ""
fi
# Step 5: Deploy dashboard stack
if [ "$DEPLOY_DASHBOARDS" = true ]; then
log_info "Step 5: Deploying dashboard stack..."
log_info " - Homepage (Application Dashboard)"
log_info " - Homarr (Modern Dashboard)"
echo ""
# Create dashboards directory
mkdir -p /opt/stacks/dashboards
# Copy dashboards compose file
cp "$REPO_DIR/docker-compose/dashboards/docker-compose.yml" /opt/stacks/dashboards/docker-compose.yml
cp "$REPO_DIR/.env" /opt/stacks/dashboards/.env
# Copy homepage config
if [ -d "$REPO_DIR/docker-compose/dashboards/homepage" ]; then
cp -r "$REPO_DIR/docker-compose/dashboards/homepage" /opt/stacks/dashboards/
fi
# Deploy dashboards stack
cd /opt/stacks/dashboards
docker compose up -d
log_success "Dashboard stack deployed"
echo ""
else
log_info "Skipping dashboard stack deployment"
echo ""
fi
# Step 6: Deploy Dokuwiki
log_info "Step 6: Deploying Dokuwiki wiki platform..."
log_info " - DokuWiki (File-based wiki with pre-configured content)"
echo ""
# Create Dokuwiki directory
mkdir -p /opt/stacks/dokuwiki/config
# Copy Dokuwiki compose file
cp "$REPO_DIR/config-templates/dokuwiki/docker-compose.yml" /opt/stacks/dokuwiki/docker-compose.yml
# Copy pre-configured Dokuwiki config, content, and keys
if [ -d "$REPO_DIR/config-templates/dokuwiki/conf" ]; then
cp -r "$REPO_DIR/config-templates/dokuwiki/conf" /opt/stacks/dokuwiki/config/
else
log_warning "Dokuwiki conf directory not found, skipping..."
fi
if [ -d "$REPO_DIR/config-templates/dokuwiki/data" ]; then
cp -r "$REPO_DIR/config-templates/dokuwiki/data" /opt/stacks/dokuwiki/config/
else
log_warning "Dokuwiki data directory not found, skipping..."
fi
if [ -d "$REPO_DIR/config-templates/dokuwiki/keys" ]; then
cp -r "$REPO_DIR/config-templates/dokuwiki/keys" /opt/stacks/dokuwiki/config/
else
log_warning "Dokuwiki keys directory not found, skipping..."
fi
# Set proper ownership for Dokuwiki config
sudo chown -R 1000:1000 /opt/stacks/dokuwiki/config
# Deploy Dokuwiki
cd /opt/stacks/dokuwiki
docker compose up -d
log_success "Dokuwiki deployed with pre-configured content"
echo ""
# Step 7: Setup stacks for Dockge (if requested)
if [ "$SETUP_STACKS" = true ]; then
setup_stacks_for_dockge
fi
# Deployment completed
echo ""
echo "=========================================="
log_success "Deployment completed successfully!"
echo "=========================================="
echo ""
log_info "Access your services:"
echo ""
echo " 🚀 Dockge: $DOCKGE_URL"
echo " 📊 Homepage: https://home.${DOMAIN}"
echo " 🎯 Homarr: https://homarr.${DOMAIN}"
echo " 📖 Wiki: https://wiki.${DOMAIN}"
echo " 🔒 Authelia: https://auth.${DOMAIN}"
echo " 🔀 Traefik: https://traefik.${DOMAIN}"
echo ""
log_info "Next steps:"
echo ""
echo " 1. Log in to Dockge using your Authelia credentials"
echo " (configured in /opt/stacks/core/authelia/users_database.yml)"
echo ""
echo " 2. Access your dashboards:"
echo " - Homepage: https://home.${DOMAIN} (AI-configurable dashboard)"
echo " - Homarr: https://homarr.${DOMAIN} (Modern dashboard)"
echo ""
echo " 3. Access your pre-deployed Dokuwiki at https://wiki.${DOMAIN}"
echo " (admin/admin credentials)"
echo ""
echo " 4. Deploy additional stacks through Dockge's web UI:"
echo " - media.yml (Plex, Jellyfin, Sonarr, Radarr, etc.)"
echo " - media-extended.yml (Readarr, Lidarr, etc.)"
echo " - homeassistant.yml (Home Assistant and accessories)"
echo " - productivity.yml (Nextcloud, Gitea, additional wikis)"
echo " - monitoring.yml (Grafana, Prometheus, etc.)"
echo " - utilities.yml (Backups, code editors, etc.)"
echo ""
echo " 5. Configure services via the AI assistant in VS Code"
echo ""
echo "=========================================="
echo ""
log_info "For documentation, see: $REPO_DIR/docs/"
log_info "For troubleshooting, see: $REPO_DIR/docs/quick-reference.md"
echo ""

View File

@@ -649,9 +649,7 @@ main() {
echo " 🚀 Dockge: https://dockge.${DOMAIN}"
[ "$DEPLOY_CORE" = true ] && echo " 🔒 Authelia: https://auth.${DOMAIN}"
[ "$DEPLOY_CORE" = true ] && echo " 🔀 Traefik: https://traefik.${DOMAIN}"
echo " 📊 Homepage: https://home.${DOMAIN}"
echo " 🎯 Homarr: https://homarr.${DOMAIN}"
echo " 📖 Wiki: https://wiki.${DOMAIN}"
echo " 📊 Homepage: https://homepage.${DOMAIN}"
echo ""
fi

View File

@@ -163,8 +163,7 @@ log_info "System is ready for next round of testing"
echo ""
log_info "Next steps:"
echo " 1. Ensure .env file is properly configured"
echo " 2. Run: sudo ./setup-homelab.sh"
echo " 3. Run: sudo ./deploy-homelab.sh"
echo " 2. Run: ./ez-homelab.sh"
echo ""
log_info "Note: Docker and system packages are NOT removed"
log_info "User groups and firewall settings are preserved"

View File

@@ -1,434 +0,0 @@
#!/bin/bash
# AI-Homelab First-Run Setup Script
# This script prepares a fresh Debian installation for homelab deployment
# Run as: sudo ./setup-homelab.sh
set -e # Exit on error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Log functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [ "$EUID" -ne 0 ]; then
log_error "Please run as root (use: sudo ./setup-homelab.sh)"
exit 1
fi
# Get the actual user who invoked sudo
ACTUAL_USER=${SUDO_USER:-$USER}
# Get script directory and repo directory
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
REPO_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
# Step 1: System Update
log_info "Step 1/10: Updating system packages..."
apt-get update && apt-get upgrade -y
log_success "System updated successfully"
echo ""
# Step 2: Install Required Packages
log_info "Step 2/10: Installing required packages..."
# Update package list first to avoid issues
apt-get update
# Install packages with error handling
if ! apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
git \
openssh-server \
sudo \
pciutils \
net-tools \
ufw; then
log_warning "Some packages may have failed to install. Attempting software-properties-common separately..."
apt-get install -y software-properties-common || log_warning "software-properties-common installation failed - may need manual intervention"
else
# Try to install software-properties-common separately as it sometimes causes issues
apt-get install -y software-properties-common || log_warning "software-properties-common installation failed - continuing anyway"
fi
log_success "Required packages installed"
echo ""
# Step 3: Install Docker
log_info "Step 3/10: Installing Docker..."
if command -v docker &> /dev/null && docker --version &> /dev/null; then
log_success "Docker is already installed ($(docker --version))"
# Check if Docker service is running
if ! systemctl is-active --quiet docker; then
log_warning "Docker service is not running, starting it..."
systemctl start docker
systemctl enable docker
log_success "Docker service started and enabled"
else
log_info "Docker service is already running"
fi
else
# Add Docker's official GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update and install Docker
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Start and enable Docker service
systemctl start docker
systemctl enable docker
log_success "Docker installed and service started ($(docker --version))"
fi
echo ""
# Step 4: Configure User Groups
log_info "Step 4/10: Configuring user groups..."
# Add user to sudo group if not already
if groups "$ACTUAL_USER" | grep -q '\bsudo\b'; then
log_warning "User $ACTUAL_USER is already in sudo group"
else
usermod -aG sudo "$ACTUAL_USER"
log_success "User $ACTUAL_USER added to sudo group"
fi
# Add user to docker group
if groups "$ACTUAL_USER" | grep -q '\bdocker\b'; then
log_warning "User $ACTUAL_USER is already in docker group"
else
usermod -aG docker "$ACTUAL_USER"
log_success "User $ACTUAL_USER added to docker group"
fi
echo ""
# Step 5: Configure Firewall
log_info "Step 5/10: Configuring firewall..."
# Enable UFW if not already enabled
if ufw status | grep -q "Status: active"; then
log_warning "Firewall is already active"
else
ufw --force enable
log_success "Firewall enabled"
fi
# Allow SSH if not already allowed
if ufw status | grep -q "22/tcp"; then
log_warning "SSH port 22 is already allowed"
else
ufw allow ssh
log_success "SSH port allowed in firewall"
fi
# Allow HTTP/HTTPS for web services
ufw allow 80/tcp
ufw allow 443/tcp
log_success "HTTP/HTTPS ports allowed in firewall"
echo ""
# Step 6: Configure SSH
log_info "Step 6/10: Configuring SSH server..."
systemctl enable ssh
systemctl start ssh
# Check if SSH is running
if systemctl is-active --quiet ssh; then
SSH_PORT=$(grep "^Port" /etc/ssh/sshd_config | awk '{print $2}')
SSH_PORT=${SSH_PORT:-22}
log_success "SSH server is running on port $SSH_PORT"
else
log_warning "SSH server failed to start, check configuration"
fi
echo ""
# Step 7: Detect and Install NVIDIA Drivers (if applicable)
log_info "Step 7/10: Checking for NVIDIA GPU..."
# Detect NVIDIA GPU
if lspci | grep -i nvidia > /dev/null; then
log_info "NVIDIA GPU detected:"
lspci | grep -i nvidia
echo ""
# Check if NVIDIA drivers are already installed
if nvidia-smi &> /dev/null; then
log_warning "NVIDIA drivers are already installed"
NVIDIA_INSTALLED=true
else
log_info "Installing NVIDIA drivers..."
# Install kernel headers first (required for NVIDIA driver)
apt-get install -y linux-headers-amd64
# Install NVIDIA driver (non-interactive)
if apt-get install -y nvidia-driver; then
log_success "NVIDIA drivers installed"
NVIDIA_INSTALLED=false
else
log_warning "NVIDIA driver installation failed. You may need to install manually after reboot."
log_info "Try: sudo apt update && sudo apt install nvidia-driver"
NVIDIA_INSTALLED=false # Still set to false to trigger reboot reminder
fi
fi
# Check if NVIDIA Container Toolkit is installed
if command -v nvidia-container-runtime &> /dev/null; then
log_warning "NVIDIA Container Toolkit is already installed"
else
log_info "Installing NVIDIA Container Toolkit..."
# Install NVIDIA Container Toolkit
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
apt-get update
apt-get install -y nvidia-container-toolkit
# Configure Docker to use NVIDIA runtime
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker
log_success "NVIDIA Container Toolkit installed and configured"
fi
if [ "$NVIDIA_INSTALLED" = false ]; then
log_warning "NVIDIA drivers were installed. A reboot may be required for changes to take effect."
fi
echo ""
else
log_info "No NVIDIA GPU detected, skipping driver installation"
echo ""
fi
# Step 8: Create Directory Structure
log_info "Step 8/10: Creating directory structure..."
mkdir -p /opt/stacks
mkdir -p /opt/dockge/data
mkdir -p /mnt/media/{movies,tv,music,books,photos}
mkdir -p /mnt/downloads/{complete,incomplete}
mkdir -p /mnt/backups
mkdir -p /mnt/surveillance
mkdir -p /mnt/git
# Set ownership with error handling
log_info "Setting directory ownership to user: $ACTUAL_USER..."
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/stacks 2>/dev/null; then
log_warning "Failed to set ownership for /opt/stacks - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /opt/stacks"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/dockge 2>/dev/null; then
log_warning "Failed to set ownership for /opt/dockge - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /opt/dockge"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/media 2>/dev/null; then
log_warning "Failed to set ownership for /mnt/media - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /mnt/media"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/downloads 2>/dev/null; then
log_warning "Failed to set ownership for /mnt/downloads - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /mnt/downloads"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/backups 2>/dev/null; then
log_warning "Failed to set ownership for /mnt/backups - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /mnt/backups"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/surveillance 2>/dev/null; then
log_warning "Failed to set ownership for /mnt/surveillance - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /mnt/surveillance"
fi
if ! chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/git 2>/dev/null; then
log_warning "Failed to set ownership for /mnt/git - you may need to run: sudo chown -R $ACTUAL_USER:$ACTUAL_USER /mnt/git"
fi
log_success "Directory structure created"
echo ""
# Step 9: Create Docker Networks
log_info "Step 9/10: Creating Docker networks..."
su - "$ACTUAL_USER" -c "docker network create homelab-network 2>/dev/null || true"
su - "$ACTUAL_USER" -c "docker network create traefik-network 2>/dev/null || true"
su - "$ACTUAL_USER" -c "docker network create media-network 2>/dev/null || true"
su - "$ACTUAL_USER" -c "docker network create dockerproxy-network 2>/dev/null || true"
log_success "Docker networks created"
echo ""
# Step 10: Generate Authelia Secrets
log_info "Step 10/10: Generating Authelia secrets..."
# Check if .env file exists, create from example if needed
if [ ! -f "$REPO_DIR/.env" ]; then
if [ -f "$REPO_DIR/.env.example" ]; then
cp "$REPO_DIR/.env.example" "$REPO_DIR/.env"
log_info ".env file created from .env.example"
else
log_error ".env and .env.example files not found in $REPO_DIR"
exit 1
fi
fi
# Generate cryptographic secrets
log_info "Generating Authelia JWT secret..."
AUTHELIA_JWT_SECRET=$(openssl rand -hex 64)
log_info "Generating Authelia session secret..."
AUTHELIA_SESSION_SECRET=$(openssl rand -hex 64)
log_info "Generating Authelia storage encryption key..."
AUTHELIA_STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 64)
# Check for existing default credentials in .env
source "$REPO_DIR/.env"
USE_DEFAULTS=false
if [ -n "$DEFAULT_USER" ] && [ -n "$DEFAULT_PASSWORD" ] && [ -n "$DEFAULT_EMAIL" ]; then
echo ""
echo "Found existing default credentials in .env:"
echo " User: $DEFAULT_USER"
echo " Email: $DEFAULT_EMAIL"
echo " Password: [hidden]"
echo ""
read -p "Use these for Authelia admin? (Y/n): " USE_DEFAULT
USE_DEFAULT=${USE_DEFAULT:-y}
if [[ "$USE_DEFAULT" =~ ^[Yy]$ ]]; then
USE_DEFAULTS=true
ADMIN_USER=$DEFAULT_USER
ADMIN_EMAIL=$DEFAULT_EMAIL
ADMIN_PASSWORD=$DEFAULT_PASSWORD
fi
fi
if [ "$USE_DEFAULTS" = false ]; then
# Prompt for admin credentials
log_info "Configuring Authelia admin user..."
echo ""
echo "Authelia Admin Configuration:"
echo "=============================="
read -p "Admin username (default: admin): " ADMIN_USER
ADMIN_USER=${ADMIN_USER:-admin}
read -p "Admin email: " ADMIN_EMAIL
while [ -z "$ADMIN_EMAIL" ]; do
log_error "Email is required"
read -p "Admin email: " ADMIN_EMAIL
done
# Prompt for password with confirmation
while true; do
read -s -p "Admin password: " ADMIN_PASSWORD
echo ""
read -s -p "Confirm password: " ADMIN_PASSWORD_CONFIRM
echo ""
if [ "$ADMIN_PASSWORD" = "$ADMIN_PASSWORD_CONFIRM" ]; then
break
else
log_error "Passwords do not match. Please try again."
fi
done
fi
# Generate password hash using Authelia Docker image
log_info "Generating password hash (this may take 30-60 seconds)..."
# Check if Docker is running
if ! docker info > /dev/null 2>&1; then
log_error "Docker is not running. Please check Docker installation."
exit 1
fi
# Pull the Authelia image first
log_info "Pulling Authelia image..."
if ! docker pull authelia/authelia:latest > /dev/null 2>&1; then
log_error "Failed to pull Authelia image. Please check internet connectivity."
exit 1
fi
# Generate the hash
ADMIN_PASSWORD_HASH=$(docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password "$ADMIN_PASSWORD" 2>&1 | grep -o '"[^"]*"' | tr -d '"')
if [ -z "$ADMIN_PASSWORD_HASH" ]; then
log_error "Failed to generate password hash. Please check Docker connectivity."
log_info "Debug: Trying manual hash generation..."
# Fallback: generate a basic hash using openssl (not recommended for production)
ADMIN_PASSWORD_HASH=$(echo -n "$ADMIN_PASSWORD" | openssl dgst -sha256 | cut -d' ' -f2)
if [ -n "$ADMIN_PASSWORD_HASH" ]; then
log_warning "Using fallback hash method. Please regenerate with proper Authelia hash later."
else
exit 1
fi
fi
# Update .env file with generated values
log_info "Updating .env file with generated secrets..."
# Use sed to replace the placeholder values
sed -i "s/AUTHELIA_JWT_SECRET=.*/AUTHELIA_JWT_SECRET=$AUTHELIA_JWT_SECRET/" "$REPO_DIR/.env"
sed -i "s/AUTHELIA_SESSION_SECRET=.*/AUTHELIA_SESSION_SECRET=$AUTHELIA_SESSION_SECRET/" "$REPO_DIR/.env"
sed -i "s/AUTHELIA_STORAGE_ENCRYPTION_KEY=.*/AUTHELIA_STORAGE_ENCRYPTION_KEY=$AUTHELIA_STORAGE_ENCRYPTION_KEY/" "$REPO_DIR/.env"
# Uncomment and set admin credentials
sed -i "s/# AUTHELIA_ADMIN_USER=.*/AUTHELIA_ADMIN_USER=$ADMIN_USER/" "$REPO_DIR/.env"
sed -i "s/# AUTHELIA_ADMIN_EMAIL=.*/AUTHELIA_ADMIN_EMAIL=$ADMIN_EMAIL/" "$REPO_DIR/.env"
sed -i "s/# AUTHELIA_ADMIN_PASSWORD=.*/AUTHELIA_ADMIN_PASSWORD=$ADMIN_PASSWORD_HASH/" "$REPO_DIR/.env"
log_success "Authelia secrets and admin credentials generated"
echo ""
# Final Summary
echo ""
echo "=========================================="
log_success "AI-Homelab setup completed successfully!"
echo "=========================================="
echo ""
log_info "Next steps:"
echo ""
echo " 1. Log out and log back in for group changes to take effect"
echo " (or run: newgrp docker)"
echo ""
echo " 2. Navigate to your EZ-Homelab repository:"
echo " cd ~/EZ-Homelab"
echo ""
echo " 3. Edit the .env file with your configuration:"
echo " cp .env.example .env"
echo " nano .env"
echo ""
echo " 4. Run the deployment script:"
echo " ./scripts/deploy-homelab.sh"
echo ""
echo " 5. Access Dockge at: https://dockge.yourdomain.duckdns.org"
echo " (Use your configured domain and Authelia credentials)"
echo ""
echo "=========================================="
if lspci | grep -i nvidia > /dev/null && [ "$NVIDIA_INSTALLED" = false ]; then
echo ""
log_warning "REMINDER: Reboot required for NVIDIA driver changes"
echo " Run: sudo reboot"
echo "=========================================="
fi
echo ""
log_info "Setup complete! Please log out and log back in."