From 32974a582053cb126e0b3e706b8b137b00c052e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 12 Jan 2026 03:47:53 +0000 Subject: [PATCH] Add Bitwarden, setup script, remove redundant files, update disk requirements, and add LinuxServer preference - Add Vaultwarden (Bitwarden) password manager to utilities.yml - Self-hosted password manager with web UI - SMTP configuration for email notifications - Admin token for management - Access at bitwarden.${DOMAIN} - Protected by Authelia SSO - Create automated first-run setup script (scripts/setup-homelab.sh) - Installs Docker Engine and Compose V2 - Configures user groups (sudo, docker) - Enables SSH for remote management - Detects NVIDIA GPU and provides manual driver installation instructions - Creates directory structure and Docker networks - Comprehensive instructions for post-setup deployment - Remove redundant compose files (now in core.yml) - Deleted authelia.yml, duckdns.yml, gluetun.yml, traefik.yml - All services consolidated into unified core.yml stack - Eliminates confusion and duplication - Update disk space requirements across documentation - Changed from "100GB+ system, 1TB+ media" to: - "120GB+ system drive (NVMe or SSD highly recommended)" - "2TB+ for media & additional disks for services like Nextcloud" - Updated in README.md and getting-started.md - Add preference for LinuxServer.io images - Updated copilot-instructions.md - LinuxServer images support PUID/PGID for proper file permissions - Preference noted in consistency guidelines - Update core stack documentation - Emphasize unified core.yml deployment - Add both deployment methods (cd to directory vs full path) - Update getting-started.md with correct deployment steps - Note removal of separate stack files - Add Bitwarden environment variables to .env.example - BITWARDEN_ADMIN_TOKEN, SIGNUPS_ALLOWED, INVITATIONS_ALLOWED - SMTP configuration for email notifications - Generation instructions included - Update services-reference.md - Add Vaultwarden to utilities section (now 7 services) - Update service count and access URLs All documentation now consistent with unified core stack approach and includes all requested features. Co-authored-by: kelinfoxy <67766943+kelinfoxy@users.noreply.github.com> --- .env.example | 11 ++ .github/copilot-instructions.md | 10 +- README.md | 39 +++--- docker-compose/authelia.yml | 39 ------ docker-compose/duckdns.yml | 21 --- docker-compose/gluetun.yml | 81 ------------ docker-compose/traefik.yml | 43 ------ docker-compose/utilities.yml | 32 +++++ docs/getting-started.md | 33 +---- docs/services-reference.md | 3 +- scripts/README.md | 74 +++++++++++ scripts/setup-homelab.sh | 227 ++++++++++++++++++++++++++++++++ 12 files changed, 380 insertions(+), 233 deletions(-) delete mode 100644 docker-compose/authelia.yml delete mode 100644 docker-compose/duckdns.yml delete mode 100644 docker-compose/gluetun.yml delete mode 100644 docker-compose/traefik.yml create mode 100644 scripts/README.md create mode 100755 scripts/setup-homelab.sh diff --git a/.env.example b/.env.example index 2ed0d44..244b41e 100644 --- a/.env.example +++ b/.env.example @@ -174,6 +174,17 @@ JUPYTER_TOKEN=changeme # Pi-hole PIHOLE_PASSWORD=changeme +# Bitwarden (Vaultwarden) Password Manager +# Admin token: openssl rand -base64 48 +BITWARDEN_ADMIN_TOKEN=changeme-bitwarden-admin-token +BITWARDEN_SIGNUPS_ALLOWED=true # Set to false after creating accounts +BITWARDEN_INVITATIONS_ALLOWED=true +SMTP_HOST=smtp.gmail.com +SMTP_FROM=bitwarden@yourdomain.com +SMTP_PORT=587 +SMTP_SECURITY=starttls +# SMTP_USERNAME and SMTP_PASSWORD defined above + # Watchtower Notifications (optional) # WATCHTOWER_NOTIFICATION_URL= diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index baed45e..39f0fd6 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -26,6 +26,7 @@ You are an AI assistant specialized in managing Docker-based homelab infrastruct - Use the same network naming patterns - Maintain uniform volume mount structures - Apply consistent environment variable patterns +- **Prefer LinuxServer.io images** when available (they support PUID/PGID for proper file permissions) ### 4. Stack-Aware Changes - Before making changes, consider the impact on the entire server stack @@ -280,7 +281,7 @@ environment: ## Core Infrastructure Stack -The `core` stack contains the four essential services that must be deployed **FIRST**: +The `core` stack (located at `/opt/stacks/core/docker-compose.yml`) contains the four essential services that must be deployed **FIRST**: 1. **DuckDNS** - Dynamic DNS updater for Let's Encrypt 2. **Traefik** - Reverse proxy with automatic SSL certificates @@ -292,15 +293,22 @@ The `core` stack contains the four essential services that must be deployed **FI - Simplifies initial deployment (one command) - Easier to manage core infrastructure together - Reduces network configuration complexity +- All core services in `/opt/stacks/core/` directory **Deployment:** ```bash +# From within the directory cd /opt/stacks/core/ docker compose up -d + +# Or from anywhere with full path +docker compose -f /opt/stacks/core/docker-compose.yml up -d ``` All other stacks depend on the core stack being deployed first. +**Note:** The separate `authelia.yml`, `duckdns.yml`, `gluetun.yml`, and `traefik.yml` files have been removed to eliminate redundancy. All these services are now in the unified `core.yml` stack. + ## Toggling SSO (Authelia) On/Off You can easily enable or disable SSO protection for any service by modifying its Traefik labels. diff --git a/README.md b/README.md index b0f9f4a..aa1785c 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ The infrastructure uses Traefik for reverse proxy with automatic SSL, Authelia f - VS Code with GitHub Copilot extension (for AI assistance) - A domain from DuckDNS (free) - Surfshark VPN account (optional, for VPN features) +- Sufficient disk space: 120GB+ system drive (NVMe or SSD highly recommended), 2TB+ for media & additional disks for services like Nextcloud that require lots of space ### Quick Setup (Dockge Structure) @@ -62,31 +63,29 @@ The infrastructure uses Traefik for reverse proxy with automatic SSL, Authelia f docker network create media-network ``` -5. **Deploy core infrastructure (in order):** +5. **Deploy core infrastructure stack:** ```bash - # 1. DuckDNS (Dynamic DNS) - mkdir -p /opt/stacks/duckdns && cp docker-compose/duckdns.yml /opt/stacks/duckdns/docker-compose.yml - cd /opt/stacks/duckdns && docker compose up -d + # Deploy the unified core stack (DuckDNS, Traefik, Authelia, Gluetun) + 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/ - # 2. Traefik (Reverse Proxy with SSL) - mkdir -p /opt/stacks/traefik/dynamic - cp docker-compose/traefik.yml /opt/stacks/traefik/docker-compose.yml - cp config-templates/traefik/* /opt/stacks/traefik/ - cd /opt/stacks/traefik && docker compose up -d + # From within the directory + cd /opt/stacks/core && docker compose up -d - # 3. Authelia (SSO) - mkdir -p /opt/stacks/authelia - cp docker-compose/authelia.yml /opt/stacks/authelia/docker-compose.yml - cp config-templates/authelia/* /opt/stacks/authelia/ - cd /opt/stacks/authelia && docker compose up -d - - # 4. Dockge (Stack Manager) - mkdir -p /opt/stacks/infrastructure - cp docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml - cd /opt/stacks/infrastructure && docker compose up -d dockge + # OR from anywhere with full path + docker compose -f /opt/stacks/core/docker-compose.yml up -d ``` -6. **Access Dockge:** +6. **Deploy infrastructure stack (includes Dockge):** + ```bash + mkdir -p /opt/stacks/infrastructure + cp docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml + cd /opt/stacks/infrastructure && docker compose up -d + ``` + +7. **Access Dockge:** Open `https://dockge.yourdomain.duckdns.org` (use Authelia login) Now deploy remaining stacks through Dockge's UI! diff --git a/docker-compose/authelia.yml b/docker-compose/authelia.yml deleted file mode 100644 index 0dd329c..0000000 --- a/docker-compose/authelia.yml +++ /dev/null @@ -1,39 +0,0 @@ -# Authelia SSO Stack -# Single Sign-On authentication for all services -# Place in /opt/stacks/authelia/docker-compose.yml - -services: - authelia: - image: authelia/authelia:4.37 - container_name: authelia - restart: unless-stopped - networks: - - traefik-network - volumes: - - /opt/stacks/authelia/configuration.yml:/config/configuration.yml:ro - - /opt/stacks/authelia/users_database.yml:/config/users_database.yml - - authelia-data:/config - environment: - - TZ=${TZ} - - AUTHELIA_JWT_SECRET=${AUTHELIA_JWT_SECRET} - - AUTHELIA_SESSION_SECRET=${AUTHELIA_SESSION_SECRET} - - AUTHELIA_STORAGE_ENCRYPTION_KEY=${AUTHELIA_STORAGE_ENCRYPTION_KEY} - - AUTHELIA_NOTIFIER_SMTP_PASSWORD=${SMTP_PASSWORD} # If using email notifications - labels: - - "traefik.enable=true" - - "traefik.http.routers.authelia.rule=Host(`auth.${DOMAIN}`)" - - "traefik.http.routers.authelia.entrypoints=websecure" - - "traefik.http.routers.authelia.tls.certresolver=letsencrypt" - - "traefik.http.services.authelia.loadbalancer.server.port=9091" - # Authelia middleware for other services - - "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.${DOMAIN}" - - "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true" - - "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email" - -volumes: - authelia-data: - driver: local - -networks: - traefik-network: - external: true diff --git a/docker-compose/duckdns.yml b/docker-compose/duckdns.yml deleted file mode 100644 index 16dec0a..0000000 --- a/docker-compose/duckdns.yml +++ /dev/null @@ -1,21 +0,0 @@ -# DuckDNS Dynamic DNS Stack -# Updates your DuckDNS domain with current public IP -# Place in /opt/stacks/duckdns/docker-compose.yml - -services: - duckdns: - image: lscr.io/linuxserver/duckdns:latest - container_name: duckdns - restart: unless-stopped - environment: - - PUID=${PUID:-1000} - - PGID=${PGID:-1000} - - TZ=${TZ} - - SUBDOMAINS=${DUCKDNS_SUBDOMAINS} # Your subdomain(s), comma separated - - TOKEN=${DUCKDNS_TOKEN} # Your DuckDNS token - - UPDATE_IP=ipv4 # or ipv6, or both - volumes: - - /opt/stacks/duckdns/config:/config - labels: - - "homelab.category=infrastructure" - - "homelab.description=Dynamic DNS updater" diff --git a/docker-compose/gluetun.yml b/docker-compose/gluetun.yml deleted file mode 100644 index 534d376..0000000 --- a/docker-compose/gluetun.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Gluetun VPN Stack -# VPN client for routing services through Surfshark (or other VPN providers) -# Place in /opt/stacks/gluetun/docker-compose.yml -# Services that need VPN use: network_mode: "service:gluetun" - -services: - gluetun: - image: qmcgaw/gluetun:latest - container_name: gluetun - restart: unless-stopped - cap_add: - - NET_ADMIN - devices: - - /dev/net/tun:/dev/net/tun - networks: - - gluetun-network - - traefik-network - ports: - # qBittorrent ports (service runs through Gluetun) - - "8080:8080" # qBittorrent WebUI - - "6881:6881" # qBittorrent TCP - - "6881:6881/udp" # qBittorrent UDP - environment: - - VPN_SERVICE_PROVIDER=surfshark - - VPN_TYPE=wireguard # or openvpn - - WIREGUARD_PRIVATE_KEY=${SURFSHARK_PRIVATE_KEY} - - WIREGUARD_ADDRESSES=${SURFSHARK_ADDRESSES} - - SERVER_COUNTRIES=${VPN_COUNTRY:-Netherlands} # Preferred VPN server country - - TZ=${TZ} - # For OpenVPN instead of WireGuard: - # - OPENVPN_USER=${SURFSHARK_USERNAME} - # - OPENVPN_PASSWORD=${SURFSHARK_PASSWORD} - volumes: - - /opt/stacks/gluetun/config:/gluetun - labels: - - "homelab.category=infrastructure" - - "homelab.description=VPN client for secure routing (Surfshark)" - - # qBittorrent - Torrent client routing through VPN - # Access at: https://qbit.yourdomain.duckdns.org - qbittorrent: - image: lscr.io/linuxserver/qbittorrent:4.6.2 - container_name: qbittorrent - network_mode: "service:gluetun" # Routes all traffic through VPN - depends_on: - - gluetun - volumes: - - /opt/stacks/qbittorrent/config:/config - - /mnt/downloads:/downloads # Large downloads on separate drive - environment: - - PUID=${PUID:-1000} - - PGID=${PGID:-1000} - - TZ=${TZ} - - WEBUI_PORT=8080 - labels: - - "homelab.category=media" - - "homelab.description=Torrent download client (via VPN)" - # Traefik labels (applied to Gluetun since qBittorrent uses its network) - # Configure these on the Gluetun container instead: - - # Traefik routing for qBittorrent (via Gluetun) - # Since qBittorrent uses Gluetun's network, we add a sidecar label container - qbit-labels: - image: alpine:latest - container_name: qbit-labels - command: tail -f /dev/null - networks: - - traefik-network - labels: - - "traefik.enable=true" - - "traefik.http.routers.qbittorrent.rule=Host(`qbit.${DOMAIN}`)" - - "traefik.http.routers.qbittorrent.entrypoints=websecure" - - "traefik.http.routers.qbittorrent.tls.certresolver=letsencrypt" - - "traefik.http.routers.qbittorrent.middlewares=authelia@docker" - - "traefik.http.services.qbittorrent.loadbalancer.server.url=http://gluetun:8080" - -networks: - gluetun-network: - driver: bridge - traefik-network: - external: true diff --git a/docker-compose/traefik.yml b/docker-compose/traefik.yml deleted file mode 100644 index adde6b1..0000000 --- a/docker-compose/traefik.yml +++ /dev/null @@ -1,43 +0,0 @@ -# Traefik Reverse Proxy Stack -# Main reverse proxy with Let's Encrypt SSL automation -# Place in /opt/stacks/traefik/docker-compose.yml - -services: - traefik: - image: traefik:v2.11 - container_name: traefik - restart: unless-stopped - security_opt: - - no-new-privileges:true - networks: - - traefik-network - ports: - - "80:80" # HTTP - - "443:443" # HTTPS - - "8080:8080" # Dashboard (protect with Authelia) - volumes: - - /etc/localtime:/etc/localtime:ro - - /var/run/docker.sock:/var/run/docker.sock:ro - - /opt/stacks/traefik/traefik.yml:/traefik.yml:ro - - /opt/stacks/traefik/dynamic:/dynamic:ro - - /opt/stacks/traefik/acme.json:/acme.json - environment: - - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN} # If using Cloudflare DNS challenge - - DUCKDNS_TOKEN=${DUCKDNS_TOKEN} # If using DuckDNS - labels: - - "traefik.enable=true" - # Dashboard - - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" - - "traefik.http.routers.traefik.entrypoints=websecure" - - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" - - "traefik.http.routers.traefik.middlewares=authelia@docker" - - "traefik.http.routers.traefik.service=api@internal" - # Global HTTP to HTTPS redirect - - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" - - "traefik.http.routers.http-catchall.entrypoints=web" - - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - -networks: - traefik-network: - external: true diff --git a/docker-compose/utilities.yml b/docker-compose/utilities.yml index 62acd9f..1eea30a 100644 --- a/docker-compose/utilities.yml +++ b/docker-compose/utilities.yml @@ -126,6 +126,38 @@ services: - "homelab.category=utilities" - "homelab.description=Form.io database" + # Bitwarden (Vaultwarden) - Password manager + # Access at: https://bitwarden.${DOMAIN} + vaultwarden: + image: vaultwarden/server:latest + container_name: vaultwarden + restart: unless-stopped + networks: + - homelab-network + - traefik-network + volumes: + - /opt/stacks/vaultwarden/data:/data + environment: + - DOMAIN=https://bitwarden.${DOMAIN} + - SIGNUPS_ALLOWED=${BITWARDEN_SIGNUPS_ALLOWED:-true} + - INVITATIONS_ALLOWED=${BITWARDEN_INVITATIONS_ALLOWED:-true} + - ADMIN_TOKEN=${BITWARDEN_ADMIN_TOKEN} + - SMTP_HOST=${SMTP_HOST} + - SMTP_FROM=${SMTP_FROM} + - SMTP_PORT=${SMTP_PORT:-587} + - SMTP_SECURITY=${SMTP_SECURITY:-starttls} + - SMTP_USERNAME=${SMTP_USERNAME} + - SMTP_PASSWORD=${SMTP_PASSWORD} + labels: + - "homelab.category=utilities" + - "homelab.description=Self-hosted password manager (Bitwarden)" + - "traefik.enable=true" + - "traefik.http.routers.vaultwarden.rule=Host(`bitwarden.${DOMAIN}`)" + - "traefik.http.routers.vaultwarden.entrypoints=websecure" + - "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt" + - "traefik.http.routers.vaultwarden.middlewares=authelia@docker" + - "traefik.http.services.vaultwarden.loadbalancer.server.port=80" + # Authelia Redis - Session storage for Authelia # No web UI - backend service authelia-redis: diff --git a/docs/getting-started.md b/docs/getting-started.md index 929c75f..7ba1052 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -11,7 +11,7 @@ Before you begin, ensure you have: - [ ] Docker Compose V2 installed - [ ] Git installed - [ ] At least 8GB RAM (16GB+ recommended) -- [ ] Sufficient disk space (100GB+ system, 1TB+ for media recommended) +- [ ] Sufficient disk space: 120GB+ system drive (NVMe or SSD highly recommended), 2TB+ for media & additional disks for services like Nextcloud that require lots of space - [ ] Static IP address for your server (or DHCP reservation) - [ ] DuckDNS account (free) with a domain - [ ] Surfshark VPN account (optional, for VPN features) @@ -174,10 +174,14 @@ nano users_database.yml # Copy .env file to core stack cp ~/AI-Homelab/.env /opt/stacks/core/.env -# Deploy the entire core stack +# Deploy the entire core stack - use either method: +# Method 1: From within directory cd /opt/stacks/core docker compose up -d +# Method 2: From anywhere with full path +docker compose -f /opt/stacks/core/docker-compose.yml up -d + # Check logs to ensure everything is running docker compose logs -f @@ -198,31 +202,6 @@ docker compose logs -f - If Authelia won't start, check your password hash and configuration.yml - If Gluetun fails, verify your Surfshark credentials in .env -```bash -# Create stack directory -mkdir -p /opt/stacks/infrastructure - -# Copy compose file -cp ~/AI-Homelab/docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml - -# Create necessary subdirectories -mkdir -p /opt/dockge/data -mkdir -p /opt/stacks/pihole/{etc-pihole,etc-dnsmasq.d} -mkdir -p /opt/stacks/glances/config - -# Copy .env -cp ~/AI-Homelab/.env /opt/stacks/infrastructure/.env - -# Deploy Dockge first -cd /opt/stacks/infrastructure -docker compose up -d dockge - -# Access Dockge at https://dockge.yourdomain.duckdns.org - -# Deploy remaining infrastructure services -docker compose up -d -``` - ## Step 8: Deploy Infrastructure Services (Dockge) ```bash diff --git a/docs/services-reference.md b/docs/services-reference.md index 9ebf56a..9eb0113 100644 --- a/docs/services-reference.md +++ b/docs/services-reference.md @@ -67,7 +67,8 @@ This document provides a comprehensive overview of all 60+ pre-configured servic | │ └─ mediawiki-db | MariaDB | - | /opt/stacks/productivity | No UI | | └─ Form.io | Form builder | ✓ | /opt/stacks/productivity | forms.${DOMAIN} | | └─ formio-mongo | MongoDB | - | /opt/stacks/productivity | No UI | -| **🛠️ utilities** (6) | | | | | +| **🛠️ utilities** (7) | | | | | +| ├─ Vaultwarden | Password manager | ✓ | /opt/stacks/utilities | bitwarden.${DOMAIN} | | ├─ Backrest | Backup (restic) | ✓ | /opt/stacks/utilities, /mnt/backups | backrest.${DOMAIN} | | ├─ Duplicati | Encrypted backups | ✓ | /opt/stacks/utilities, /mnt/backups | duplicati.${DOMAIN} | | ├─ Code Server | VS Code in browser | ✓ | /opt/stacks/utilities | code.${DOMAIN} | diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..59afdf3 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,74 @@ +# AI-Homelab Setup Scripts + +## setup-homelab.sh + +Automated first-run setup script for preparing a fresh Debian installation for AI-Homelab deployment. + +### What It Does + +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 +4. **Configure User Groups** - Adds user to sudo and docker groups +5. **Configure SSH** - Enables and starts SSH server for remote access +6. **Detect NVIDIA GPU** - Checks for NVIDIA graphics card and provides manual driver installation instructions +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 + +### Usage + +```bash +# Download the repository +git clone https://github.com/kelinfoxy/AI-Homelab.git +cd AI-Homelab + +# Make the script executable (if needed) +chmod +x scripts/setup-homelab.sh + +# Run with sudo +sudo ./scripts/setup-homelab.sh +``` + +### After Running + +1. Log out and log back in for group changes to take effect +2. Edit `.env` file with your configuration +3. Deploy the core infrastructure stack +4. Deploy the infrastructure stack (includes Dockge) +5. Access Dockge to manage remaining stacks + +### NVIDIA GPU Support + +If an NVIDIA GPU is detected, the script will provide instructions for manual driver installation: + +1. Identify your GPU model from the output +2. Visit https://www.nvidia.com/Download/index.aspx +3. Download the official driver for your GPU +4. Run the installer: `sudo bash NVIDIA-Linux-x86_64-XXX.XX.run` +5. Install container toolkit: + ```bash + sudo apt-get install -y nvidia-container-toolkit + sudo nvidia-ctk runtime configure --runtime=docker + sudo systemctl restart docker + ``` + +This manual approach avoids driver conflicts that often occur with automated installation methods. + +### Requirements + +- Fresh Debian installation (Debian 11 or 12) +- Root access (via sudo) +- Internet connection + +### Tested On + +- Debian 11 (Bullseye) +- Debian 12 (Bookworm) + +### Notes + +- The script is idempotent - safe to run multiple times +- Creates directories with proper ownership +- Configures Docker networks automatically +- SSH is enabled for remote management +- NVIDIA driver installation requires manual intervention for reliability diff --git a/scripts/setup-homelab.sh b/scripts/setup-homelab.sh new file mode 100755 index 0000000..963d0f9 --- /dev/null +++ b/scripts/setup-homelab.sh @@ -0,0 +1,227 @@ +#!/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}" +if [ "$ACTUAL_USER" = "root" ]; then + log_error "Please run this script with sudo, not as root user" + exit 1 +fi + +log_info "Setting up AI-Homelab for user: $ACTUAL_USER" +echo "" + +# Step 1: System Update +log_info "Step 1/8: 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/8: Installing required packages..." +apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg \ + lsb-release \ + software-properties-common \ + git \ + openssh-server \ + sudo \ + pciutils \ + net-tools + +log_success "Required packages installed" +echo "" + +# Step 3: Install Docker +log_info "Step 3/8: Installing Docker..." +if command -v docker &> /dev/null; then + log_warning "Docker is already installed ($(docker --version))" +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 + + log_success "Docker installed successfully ($(docker --version))" +fi +echo "" + +# Step 4: Configure User Groups +log_info "Step 4/8: 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 SSH +log_info "Step 5/8: 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 6: Detect and Install NVIDIA Drivers (if applicable) +log_info "Step 6/8: 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 "" + + log_warning "NVIDIA GPU found, but driver installation requires manual intervention." + log_info "For best results, please follow these steps manually:" + echo "" + echo " 1. Identify your GPU model from the output above" + echo " 2. Visit: https://www.nvidia.com/Download/index.aspx" + echo " 3. Download the official driver for your GPU" + echo " 4. Run the downloaded installer (example): sudo bash NVIDIA-Linux-x86_64-XXX.XX.run" + echo "" + log_info "After installing NVIDIA drivers, run:" + echo " sudo apt-get install -y nvidia-container-toolkit" + echo " sudo nvidia-ctk runtime configure --runtime=docker" + echo " sudo systemctl restart docker" + echo "" + log_warning "Skipping automatic NVIDIA driver installation to avoid conflicts" + echo "" +else + log_info "No NVIDIA GPU detected, skipping driver installation" + echo "" +fi + +# Step 7: Create Directory Structure +log_info "Step 7/8: Creating directory structure..." +mkdir -p /opt/stacks +mkdir -p /opt/dockge/data +mkdir -p /mnt/media +mkdir -p /mnt/downloads + +# Set ownership +chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/stacks +chown -R "$ACTUAL_USER:$ACTUAL_USER" /opt/dockge +chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/media +chown -R "$ACTUAL_USER:$ACTUAL_USER" /mnt/downloads + +log_success "Directory structure created" +echo "" + +# Step 8: Create Docker Networks +log_info "Step 8/8: 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" +log_success "Docker networks created" +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 AI-Homelab repository:" +echo " cd ~/AI-Homelab" +echo "" +echo " 3. Edit the .env file with your configuration:" +echo " cp .env.example .env" +echo " nano .env" +echo "" +echo " 4. Deploy the core infrastructure stack:" +echo " mkdir -p /opt/stacks/core" +echo " cp docker-compose/core.yml /opt/stacks/core/docker-compose.yml" +echo " cp -r config-templates/traefik /opt/stacks/core/" +echo " cp -r config-templates/authelia /opt/stacks/core/" +echo " cd /opt/stacks/core && docker compose up -d" +echo "" +echo " 5. Deploy the infrastructure stack (includes Dockge):" +echo " mkdir -p /opt/stacks/infrastructure" +echo " cp docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml" +echo " cd /opt/stacks/infrastructure && docker compose up -d" +echo "" +echo " 6. 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; then + echo "" + log_warning "REMINDER: Manual NVIDIA driver installation required" + echo " See instructions above in Step 6" + echo "==========================================" +fi + +echo "" +log_info "Setup complete! Please log out and log back in."