diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index ca82397..4b429de 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -13,7 +13,7 @@ The **core stack** (`/opt/stacks/core/`) contains essential services that must r - **Sablier**: Lazy loading service for on-demand container startup (saves resources) ### Deployment Model -- **Two-script setup**: `setup-homelab.sh` (system prep, Docker install, secrets generation) → `deploy-homelab.sh` (automated deployment) +- **Unified script setup**: `ez-homelab.sh` (system prep, secrets generation, service deployment) - **Dockge-based management**: All stacks in `/opt/stacks/`, managed via web UI at `dockge.${DOMAIN}` - **Automated workflows**: Scripts create directories, configure networks, deploy stacks, wait for health checks - **Repository location**: `/home/kelin/EZ-Homelab/` (templates in `docker-compose/`, docs in `docs/`) @@ -113,21 +113,12 @@ Proxy non-Docker services (Raspberry Pi, NAS) via Traefik file provider: ### First-Time Deployment ```bash -cd ~/AI-Homelab -sudo ./scripts/setup-homelab.sh # System prep, Docker install, Authelia secrets -# Reboot if NVIDIA drivers installed -sudo ./scripts/deploy-homelab.sh # Deploy core+infrastructure stacks, open Dockge +cd ~/EZ-Homelab +./ez-homelab.sh # Unified setup and deployment ``` ### Managing Services via Scripts -- **setup-homelab.sh**: Idempotent system preparation (skips completed steps, runs on bare Debian) - - Steps: Update system → Install Docker → Configure firewall → Generate Authelia secrets → Create directories/networks → NVIDIA driver detection - - Auto-generates: JWT secret (64 hex), session secret (64 hex), encryption key (64 hex), admin password hash - - Creates `homelab-network` and `traefik-network` Docker networks -- **deploy-homelab.sh**: Automated stack deployment (requires `.env` configured first) - - Steps: Validate prerequisites → Create directories → Deploy core → Deploy infrastructure → Deploy dashboards → Prepare additional stacks → Wait for Dockge - - Copies `.env` to `/opt/stacks/core/.env` and `/opt/stacks/infrastructure/.env` - - Waits for service health checks before proceeding +- **ez-homelab.sh**: Unified setup and deployment script (system prep, secrets generation, service deployment) ### Testing Changes ```bash @@ -279,7 +270,7 @@ x-dockge: - **Dynamic reloading**: Changes apply without container restarts ### Authelia Password Generation -Secrets auto-generated by `setup-homelab.sh`: +Secrets auto-generated by `ez-homelab.sh`: - JWT secret: `openssl rand -hex 64` - Session secret: `openssl rand -hex 64` - Encryption key: `openssl rand -hex 64` diff --git a/AGENT_INSTRUCTIONS.md b/AGENT_INSTRUCTIONS.md index 91bff04..a9e7405 100644 --- a/AGENT_INSTRUCTIONS.md +++ b/AGENT_INSTRUCTIONS.md @@ -30,8 +30,9 @@ You are an AI agent specialized in managing Docker-based homelab infrastructure │ ├── proxying-external-hosts.md │ └── troubleshooting/ ├── scripts/ # Automation scripts -│ ├── setup-homelab.sh # First-run setup -│ └── deploy-homelab.sh # Automated deployment +│ ├── ez-homelab.sh # Unified setup and deployment +│ ├── reset-test-environment.sh # Safe test environment cleanup +│ └── reset-ondemand-services.sh # Reload services for Sablier lazy loading ├── .env.example # Environment template ├── .env # User-created environment file (not in git) ├── AGENT_INSTRUCTIONS.md # This file @@ -263,7 +264,7 @@ labels: ### Development Workflow 1. **Repository Maintenance** - - Test deployment scripts: `./scripts/setup-homelab.sh`, `./scripts/deploy-homelab.sh` + - Test deployment script: `./scripts/ez-homelab.sh` - Verify compose file syntax across all stacks - Validate `.env.example` completeness - Check documentation accuracy @@ -529,14 +530,14 @@ docker compose -f docker-compose/core.yml config grep -v '^#' .env | grep -v '^$' # Test script syntax -bash -n scripts/deploy-homelab.sh +bash -n scripts/ez-homelab.sh # Verify file permissions ls -la ~/EZ-Homelab/ ``` ### Deployment Checklist -- [ ] Fresh system: Test `setup-homelab.sh` +- [ ] Fresh system: Test `ez-homelab.sh` - [ ] Core stack: Deploy and verify DuckDNS, Traefik, Authelia, Gluetun - [ ] Infrastructure: Deploy Dockge and verify web UI access - [ ] Additional stacks: Test individual stack deployment diff --git a/docs/ai-vscode-setup.md b/docs/ai-vscode-setup.md index e894596..ad9e8d3 100644 --- a/docs/ai-vscode-setup.md +++ b/docs/ai-vscode-setup.md @@ -33,7 +33,7 @@ With VS Code connected to your server, you can now use GitHub Copilot to guide y ### Initial Server Setup - **Clone repository**: Ask Copilot "Help me clone the AI-Homelab repository" - **Configure environment**: "Guide me through setting up the .env file" -- **Run setup scripts**: "Walk me through running the setup-homelab.sh script" +- **Run setup scripts**: "Walk me through running the ez-homelab.sh script" - **Deploy services**: "Help me run the deployment script" ### AI-Assisted Configuration diff --git a/docs/automated-setup.md b/docs/automated-setup.md index d4c3d00..b2b4e06 100644 --- a/docs/automated-setup.md +++ b/docs/automated-setup.md @@ -35,39 +35,18 @@ For most users, the automated setup script handles everything from system prepar **Note:** The `.env` file stays in the repository folder (`~/EZ-Homelab/.env`). The deploy script copies it to stack directories automatically. Authelia secrets (JWT, session, encryption key) are auto-generated by the setup script - leave them with default values for now. -5. **Run the setup script:** +5. **Run the unified setup script:** ```bash - sudo ./scripts/setup-homelab.sh + ./scripts/ez-homelab.sh ``` - The script will: - - Update system packages - - Install Docker Engine + Compose V2 (if needed) - - Configure user groups (docker, sudo) - - Set up firewall (UFW) - - Enable SSH server - - **Generate Authelia secrets** (JWT, session, encryption key) - - **Prompt for admin username, password, and email** - - **Generate argon2id password hash** (30-60 seconds) - - Create `/opt/stacks/` directory structure - - Set up Docker networks (homelab, traefik, dockerproxy, media) - - Detect NVIDIA GPU and offer driver installation - - **Important:** If NVIDIA drivers were installed, reboot your system now before continuing. - -6. **Deploy homelab**: - ```bash - sudo ./scripts/deploy-homelab.sh - ``` - - **The deploy script automatically:** - - Creates Docker networks - - Configures Traefik with your email and domain - - **Obtains wildcard SSL certificate** (*.yourdomain.duckdns.org) via DNS challenge - - Deploys core stack (DuckDNS, Traefik, Authelia, Gluetun) - - Deploys infrastructure stack (Dockge, Pi-hole, monitoring) - - Deploys dashboards stack (Homepage, Homarr) - - Opens Dockge in your browser + The script will guide you through: + - System preparation (if needed) + - Domain and credential configuration + - Service stack selection + - Authelia secrets generation + - SSL certificate setup + - Service deployment **Note:** Certificate generation may take 2-5 minutes. All services will use the wildcard certificate automatically. @@ -78,11 +57,11 @@ For most users, the automated setup script handles everything from system prepar **That's it!** Your homelab is ready. **Access Dockge at `https://dockge.yourdomain.duckdns.org`** -## What the Setup Script Does +## What the Unified Setup Script Does -The `setup-homelab.sh` script is a comprehensive first-run configuration tool: +The `ez-homelab.sh` script is a comprehensive guided setup and deployment tool: -**System Preparation:** +**System Preparation (when needed):** - ✅ Pre-flight checks (internet connectivity, disk space 50GB+) - ✅ Updates system packages - ✅ Installs required packages (git, curl, etc.) @@ -91,22 +70,25 @@ The `setup-homelab.sh` script is a comprehensive first-run configuration tool: - ✅ Sets up firewall (UFW with SSH, HTTP, HTTPS) - ✅ Enables SSH server -**Authelia Configuration (Interactive):** +**Interactive Configuration:** +- ✅ Guides through domain setup (DuckDNS) +- ✅ Prompts for admin username, email, and password - ✅ Generates three cryptographic secrets (JWT, session, encryption) -- ✅ Prompts for admin username (default: admin) -- ✅ Prompts for secure password with confirmation -- ✅ Prompts for admin email address - ✅ Generates argon2id password hash using Docker (30-60s process) -- ✅ Validates Docker is available before password operations -- ✅ Saves credentials securely for deployment script +- ✅ Allows service stack selection +- ✅ Validates Docker is available before operations -**Infrastructure Setup:** +**Infrastructure Setup & Deployment:** - ✅ Creates directory structure (`/opt/stacks/`) - ✅ Sets up Docker networks (homelab, traefik, dockerproxy, media) +- ✅ Deploys selected service stacks +- ✅ Obtains wildcard SSL certificate (*.yourdomain.duckdns.org) - ✅ Detects NVIDIA GPU and offers driver installation +- ✅ Opens Dockge when ready **Safety Features:** -- Skips completed steps (safe to re-run) +- Interactive guidance with clear prompts - Timeout handling (60s for Docker operations) - Comprehensive error messages with troubleshooting hints -- Exit on critical failures with clear next steps \ No newline at end of file +- Safe to re-run (idempotent operations) +- Confirmation prompts for destructive actions \ No newline at end of file diff --git a/docs/env-configuration.md b/docs/env-configuration.md index 3944849..96ec694 100644 --- a/docs/env-configuration.md +++ b/docs/env-configuration.md @@ -110,9 +110,9 @@ Set your timezone. Common options: ### 4. Authelia Secrets -**⚠️ IMPORTANT:** These are auto-generated by the setup script. Do NOT set them manually. +**⚠️ IMPORTANT:** These are auto-generated by the unified setup script. Do NOT set them manually. -The `setup-homelab.sh` script will generate secure random secrets for: +The `ez-homelab.sh` script will generate secure random secrets for: - JWT Secret (64 hex characters) - Session Secret (64 hex characters) - Storage Encryption Key (64 hex characters) diff --git a/docs/getting-started.md b/docs/getting-started.md index adaa478..1d4868c 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -6,9 +6,7 @@ Welcome to your AI-powered homelab! This guide will walk you through setting up - [ ] Clone this repository to your home folder - [ ] Configure `.env` file with your domain and tokens ([see prerequisites](env-configuration.md)) - [ ] Forward ports 80 and 443 from your router to your server -- [ ] Run setup script (generates Authelia secrets and admin user) ([setup-homelab.sh](../scripts/setup-homelab.sh)) -- [ ] Log out and back in for Docker group permissions -- [ ] Run deployment script (deploys all core, infrastructure & dashboard services) ([deploy-homelab.sh](../scripts/deploy-homelab.sh)) +- [ ] Run unified setup script (generates Authelia secrets and admin user, deploys services) ([ez-homelab.sh](../scripts/ez-homelab.sh)) - [ ] Access Dockge web UI (`https://dockge.${DOMAIN}`) - [ ] Set up 2FA with Authelia ([Authelia setup guide](service-docs/authelia.md)) - [ ] (optional) Deploy additional stacks as needed via Dockge ([services overview](services-overview.md)) diff --git a/docs/manual-setup.md b/docs/manual-setup.md index 82d3325..9a75d98 100644 --- a/docs/manual-setup.md +++ b/docs/manual-setup.md @@ -205,12 +205,12 @@ docker network create network-name ## Switching to Automated -If manual setup works, you can switch to the automated scripts for future updates: +If manual setup works, you can switch to the unified automated script for future updates: ```bash -# Just run the deploy script -cd ~/AI-Homelab -sudo ./scripts/deploy-homelab.sh +# Just run the unified setup script +cd ~/EZ-Homelab +./scripts/ez-homelab.sh ``` -The deploy script is idempotent - it won't break existing configurations. +The unified script is idempotent - it won't break existing configurations. diff --git a/docs/quick-reference.md b/docs/quick-reference.md index 770bc29..fd817d8 100644 --- a/docs/quick-reference.md +++ b/docs/quick-reference.md @@ -26,8 +26,7 @@ Your homelab uses separate stacks for organization: For detailed information about the deployment scripts, their features, and usage, see [scripts/README.md](../scripts/README.md). **Quick summary:** -- `setup-homelab.sh` - First-run system setup and Authelia configuration -- `deploy-homelab.sh` - Deploy all core services and prepare additional stacks +- `ez-homelab.sh` - Unified setup and deployment script (system prep, secrets generation, service deployment) - `reset-test-environment.sh` - Testing/development only - removes all deployed services - `reset-ondemand-services.sh` - Reload services for Sablier lazy loading @@ -530,15 +529,10 @@ deploy: ### Minimal setup ```bash # Clone and configure -git clone https://github.com/kelinfoxy/AI-Homelab.git -cd AI-Homelab -sudo ./scripts/setup-homelab.sh -cp .env.example .env -nano .env - -# Deploy core only -mkdir -p /opt/stacks/core -cp docker-compose/core/docker-compose.yml /opt/stacks/core/docker-compose.yml +git clone https://github.com/kelinfoxy/EZ-Homelab.git +cd EZ-Homelab +./scripts/ez-homelab.sh +``` cp -r config-templates/traefik /opt/stacks/core/ cp -r config-templates/authelia /opt/stacks/core/ cp .env /opt/stacks/core/ diff --git a/docs/troubleshooting/COMMON-ISSUES.md b/docs/troubleshooting/COMMON-ISSUES.md index 0ee464d..b8fd032 100644 --- a/docs/troubleshooting/COMMON-ISSUES.md +++ b/docs/troubleshooting/COMMON-ISSUES.md @@ -95,8 +95,8 @@ docker compose up -d **Solution:** ```bash -# Re-run deployment script (safe - won't affect running services) -sudo ./scripts/deploy-homelab.sh +# Re-run unified setup script (safe - won't affect running services) +./scripts/ez-homelab.sh # Or manually fix: cd /opt/stacks/dashboards/homepage @@ -181,8 +181,8 @@ sudo systemctl stop systemd-resolved # Check what exists ls -la /opt/stacks/ -# Re-run deployment to copy stacks -sudo ./scripts/deploy-homelab.sh +# Re-run unified setup script to copy stacks +./scripts/ez-homelab.sh ``` ## Performance Issues @@ -233,9 +233,8 @@ sudo docker logs authelia # Use the safe reset script sudo ./scripts/reset-test-environment.sh -# Then re-run setup and deploy -sudo ./scripts/setup-homelab.sh -sudo ./scripts/deploy-homelab.sh +# Then re-run unified setup script +./scripts/ez-homelab.sh ``` ### Partial Reset (Single Stack) diff --git a/scripts/README.md b/scripts/README.md index c5b3b30..5146d53 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -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 diff --git a/scripts/deploy-homelab.sh b/scripts/deploy-homelab.sh deleted file mode 100755 index 8a3d287..0000000 --- a/scripts/deploy-homelab.sh +++ /dev/null @@ -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 "" diff --git a/scripts/ez-homelab.sh b/scripts/ez-homelab.sh index f056a2b..232e62b 100755 --- a/scripts/ez-homelab.sh +++ b/scripts/ez-homelab.sh @@ -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 diff --git a/scripts/reset-test-environment.sh b/scripts/reset-test-environment.sh index d3fc3e6..2e85f61 100755 --- a/scripts/reset-test-environment.sh +++ b/scripts/reset-test-environment.sh @@ -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" diff --git a/scripts/setup-homelab.sh b/scripts/setup-homelab.sh deleted file mode 100755 index 6dd7621..0000000 --- a/scripts/setup-homelab.sh +++ /dev/null @@ -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." diff --git a/working-config-from-jasper.md b/working-config-from-jasper.md deleted file mode 100644 index 49b05e5..0000000 --- a/working-config-from-jasper.md +++ /dev/null @@ -1,901 +0,0 @@ -This file contains the current configuration for Traefik & Sablier on the server jarvis (192.168.4.4) -This configuration was working in a previous test round. - -external-host-jarvis.yml -```yaml -http: - routers: - backrest-jarvis: - rule: "Host(`backrest.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: backrest-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-backrest@file - - authelia@docker - - bookstack-jarvis: - rule: "Host(`bookstack.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: bookstack-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-bookstack@file - - authelia@docker - - bitwarden-jarvis: - rule: "Host(`bitwarden.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: bitwarden-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-bitwarden@file - - authelia@docker - - calibre-web-jarvis: - rule: "Host(`calibre.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: calibre-web-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-calibre-web@file - - authelia@docker - - code-jarvis: - rule: "Host(`code.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: code-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-code-server@file - - authelia@docker - - dockge-jarvis: - rule: "Host(`jarvis.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: dockge-jarvis - tls: - certResolver: letsencrypt - middlewares: - - authelia@docker - - dockhand-jarvis: - rule: "Host(`dockhand.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: dockhand-jarvis - tls: - certResolver: letsencrypt - middlewares: - - authelia@docker - - dokuwiki-jarvis: - rule: "Host(`wiki.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: dokuwiki-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-dokuwiki@file - - authelia@docker - - dozzle-jarvis: - rule: "Host(`dozzle.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: dozzle-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-dozzle@file - - authelia@docker - - duplicati-jarvis: - rule: "Host(`duplicati.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: duplicati-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-duplicati@file - - authelia@docker - - formio-jarvis: - rule: "Host(`formio.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: formio-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-formio@file - - authelia@docker - - gitea-jarvis: - rule: "Host(`gitea.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: gitea-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-gitea@file - - authelia@docker - - glances-jarvis: - rule: "Host(`glances.jarvis.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: glances-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-glances@file - - authelia@docker - - homepage-jarvis: - rule: "Host(`homepage.jarvis.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: homepage-jarvis - tls: - certResolver: letsencrypt - middlewares: - - authelia@docker - - homarr-jarvis: - rule: "Host(`homarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: homarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - authelia@docker - - sablier-jarvis-homarr@file - - jellyfin-jarvis: - rule: "Host(`jellyfin.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: jellyfin-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-jellyfin@file - # No authelia middleware for media apps - - kopia-jarvis: - rule: "Host(`kopia.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: kopia-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-kopia@file - - authelia@docker - - mealie-jarvis: - rule: "Host(`mealie.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: mealie-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-mealie@file - - authelia@docker - - motioneye-jarvis: - rule: "Host(`motioneye.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: motioneye-jarvis - tls: - certResolver: letsencrypt - middlewares: - - authelia@docker - - mediawiki-jarvis: - rule: "Host(`mediawiki.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: mediawiki-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-mediawiki@file - - authelia@docker - - nextcloud-jarvis: - rule: "Host(`nextcloud.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: nextcloud-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-nextcloud@file - - authelia@docker - - openkm-jarvis: - rule: "Host(`openkm.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: openkm-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-openkm@file - - authelia@docker - - openwebui-jarvis: - rule: "Host(`openwebui.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: openwebui-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-openwebui@file - - authelia@docker - - qbittorrent-jarvis: - rule: "Host(`torrents.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: qbittorrent-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - tdarr-jarvis: - rule: "Host(`tdarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: tdarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - unmanic-jarvis: - rule: "Host(`unmanic.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: unmanic-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-unmanic@file - - authelia@docker - - wordpress-jarvis: - rule: "Host(`knot-u.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: wordpress-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-wordpress@file - - authelia@file - -# Arr Services (no SSO for media apps) - - jellyseerr-jarvis: - rule: "Host(`jellyseerr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: jellyseerr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - prowlarr-jarvis: - rule: "Host(`prowlarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: prowlarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - radarr-jarvis: - rule: "Host(`radarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: radarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - sonarr-jarvis: - rule: "Host(`sonarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: sonarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - lidarr-jarvis: - rule: "Host(`lidarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: lidarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - readarr-jarvis: - rule: "Host(`readarr.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: readarr-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - mylar3-jarvis: - rule: "Host(`mylar3.kelinreij.duckdns.org`)" - entryPoints: - - websecure - service: mylar3-jarvis - tls: - certResolver: letsencrypt - middlewares: - - sablier-jarvis-arr@file - - authelia@docker - - services: - backrest-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:9898" - passHostHeader: true - - bitwarden-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8000" - passHostHeader: true - - bookstack-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:6875" - passHostHeader: true - - calibre-web-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8083" - passHostHeader: true - - code-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8079" - passHostHeader: true - - dockge-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:5001" - passHostHeader: true - - dockhand-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:3003" - passHostHeader: true - - dokuwiki-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8087" - passHostHeader: true - - dozzle-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8085" - passHostHeader: true - - duplicati-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8200" - passHostHeader: true - - formio-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:3002" - passHostHeader: true - - gitea-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:3010" - passHostHeader: true - - glances-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:61208" - passHostHeader: true - - homarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:7575" - passHostHeader: true - - homepage-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:3000" - passHostHeader: true - - jellyfin-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8096" - passHostHeader: true - - kopia-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:51515" - passHostHeader: true - - mealie-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:9000" - passHostHeader: true - - mediawiki-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8084" - passHostHeader: true - - motioneye-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8081" - passHostHeader: true - - nextcloud-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8089" - passHostHeader: true - - openkm-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:18080" - passHostHeader: true - - openwebui-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:3004" - passHostHeader: true - - qbittorrent-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8080" - passHostHeader: true - - tdarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8265" - passHostHeader: true - - unmanic-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8888" - passHostHeader: true - - wordpress-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8088" - passHostHeader: true - - # Arr Services - - jellyseerr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:5055" - passHostHeader: true - - prowlarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:9696" - passHostHeader: true - - radarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:7878" - passHostHeader: true - - sonarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8989" - passHostHeader: true - - lidarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8686" - passHostHeader: true - - readarr-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8787" - passHostHeader: true - - mylar3-jarvis: - loadBalancer: - servers: - - url: "http://192.168.4.11:8090" - passHostHeader: true - -``` - -sablier.yml -```yaml -http: - middlewares: - sablier-jarvis-arr: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-arr - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Arr Apps - theme: ghost - show-details-by-default: true - - sablier-jarvis-backrest: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-backrest - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Backrest - theme: ghost - show-details-by-default: true - - sablier-jarvis-bookstack: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-bookstack - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Bookstack - theme: ghost - show-details-by-default: true - - sablier-jarvis-jellyfin: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-jellyfin - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Jellyfin - theme: ghost - show-details-by-default: true - - sablier-jarvis-calibre-web: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-calibre-web - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Calibre Web - theme: ghost - show-details-by-default: true - - sablier-jarvis-code-server: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-code-server - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Code Server - theme: ghost - show-details-by-default: true - - sablier-jarvis-bitwarden: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-bitwarden - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: bitwarden - theme: ghost - show-details-by-default: true - - sablier-jarvis-wordpress: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-wordpress - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: wordpress - theme: ghost - show-details-by-default: true - - sablier-jarvis-nextcloud: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-nextcloud - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: NextCloud - theme: ghost - show-details-by-default: true - - sablier-jarvis-mediawiki: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-mediawiki - sessionDuration: 2m - ignoreUserAgent: curl - dynamic: - displayName: mediawiki - theme: ghost - show-details-by-default: true - - sablier-jarvis-mealie: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-mealie - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Mealie - theme: ghost - show-details-by-default: true - - sablier-jarvis-gitea: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-gitea - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Gitea - theme: ghost - show-details-by-default: true - - sablier-jarvis-formio: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-formio - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: FormIO - theme: ghost - show-details-by-default: true - - sablier-jarvis-dozzle: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-dozzle - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: dozzle - theme: ghost - show-details-by-default: true - - sablier-jarvis-duplicati: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-duplicati - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Duplicati - theme: ghost - show-details-by-default: true - - sablier-jarvis-glances: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-glances - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Glances - theme: ghost - show-details-by-default: true - - sablier-jarvis-homarr: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-homarr - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Homarr - theme: ghost - show-details-by-default: true - - sablier-jarvis-komodo: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-komodo - sessionDuration: 2m - ignoreUserAgent: curl - dynamic: - displayName: Komodo - theme: ghost - show-details-by-default: true - - sablier-jarvis-kopia: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-kopia - sessionDuration: 2m - ignoreUserAgent: curl - dynamic: - displayName: Kopia - theme: ghost - show-details-by-default: true - - sablier-jarvis-openkm: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-openkm - sessionDuration: 2m - ignoreUserAgent: curl - dynamic: - displayName: OpenKM - theme: ghost - show-details-by-default: true - - sablier-jarvis-openwebui: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: openwebui-jarvis - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: OpenWebUI - theme: ghost - show-details-by-default: true - - sablier-jarvis-pulse: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-pulse - sessionDuration: 2m - ignoreUserAgent: curl - dynamic: - displayName: Pulse - theme: ghost - show-details-by-default: true - - sablier-jarvis-tdarr: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-tdarr - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Tdarr - theme: ghost - show-details-by-default: true - - sablier-jarvis-unmanic: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-unmanic - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: Unmanic - theme: ghost - show-details-by-default: true - - sablier-jarvis-dokuwiki: - plugin: - sablier: - sablierUrl: http://sablier-service:10000 - group: jarvis-dokuwiki - sessionDuration: 30m - ignoreUserAgent: curl - dynamic: - displayName: DokuWiki - theme: ghost - show-details-by-default: true - - authelia: - forwardauth: - address: http://authelia:9091/api/verify?rd=https://auth.kelinreij.duckdns.org/ - authResponseHeaders: - - X-Secret - trustForwardHeader: true - - -``` \ No newline at end of file