diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..8f67c0d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,92 @@ +# Homelab Documentation + +Welcome to the homelab documentation! This folder contains comprehensive guides for setting up, configuring, and maintaining your self-hosted services. + +## 📚 Documentation Structure + +### Quick Start +- [Getting Started](./getting-started.md) - First-time setup walkthrough +- [Quick Reference](./quick-reference.md) - Common commands and URLs + +### Configuration +- [Environment Variables & Secrets](./guides/secrets-management.md) - How to configure secure secrets +- [DNS Configuration](./guides/dns-setup.md) - Setting up domain names +- [SSL/TLS Certificates](./guides/ssl-certificates.md) - Let's Encrypt configuration +- [GPU Acceleration](./guides/gpu-setup.md) - NVIDIA GPU setup for Jellyfin and Immich + +### Services +- [Service Overview](./services/README.md) - All available services +- [SSO Configuration](./services/sso-setup.md) - Single Sign-On with LLDAP and Tinyauth +- [Media Stack](./services/media-stack.md) - Jellyfin, Sonarr, Radarr setup +- [Backup Solutions](./services/backup.md) - Backrest configuration + +### Troubleshooting +- [Common Issues](./troubleshooting/common-issues.md) - Frequent problems and solutions +- [FAQ](./troubleshooting/faq.md) - Frequently asked questions +- [Debugging Guide](./troubleshooting/debugging.md) - How to diagnose problems + +### Operations +- [Maintenance](./operations/maintenance.md) - Regular maintenance tasks +- [Updates](./operations/updates.md) - Updating services +- [Backups](./operations/backups.md) - Backup and restore procedures +- [Monitoring](./operations/monitoring.md) - Service monitoring + +## 🚀 Quick Links + +### First Time Setup +1. [Prerequisites](./getting-started.md#prerequisites) +2. [Configure Secrets](./guides/secrets-management.md) +3. [Setup DNS](./guides/dns-setup.md) +4. [Deploy Services](./getting-started.md#deployment) + +### Common Tasks +- [Add a new service](./guides/adding-services.md) +- [Generate secure passwords](./guides/secrets-management.md#generating-secrets) +- [Enable GPU acceleration](./guides/gpu-setup.md) +- [Backup configuration](./operations/backups.md) +- [Update a service](./operations/updates.md) + +### Troubleshooting +- [Service won't start](./troubleshooting/common-issues.md#service-wont-start) +- [SSL certificate errors](./troubleshooting/common-issues.md#ssl-errors) +- [SSO not working](./troubleshooting/common-issues.md#sso-issues) +- [Can't access service](./troubleshooting/common-issues.md#access-issues) + +## 📖 Documentation Conventions + +Throughout this documentation: +- `command` - Commands to run in terminal +- **Bold** - Important concepts or UI elements +- `https://service.fig.systems` - Example URLs +- ⚠️ - Warning or important note +- 💡 - Tip or helpful information +- ✅ - Verified working configuration + +## 🔐 Security Notes + +Before deploying to production: +1. ✅ Change all passwords in `.env` files +2. ✅ Configure DNS records +3. ✅ Verify SSL certificates are working +4. ✅ Enable backups +5. ✅ Review security settings + +## 🆘 Getting Help + +If you encounter issues: +1. Check [Common Issues](./troubleshooting/common-issues.md) +2. Review [FAQ](./troubleshooting/faq.md) +3. Check service logs: `docker compose logs servicename` +4. Review the [Debugging Guide](./troubleshooting/debugging.md) + +## 📝 Contributing to Documentation + +Found an error or have a suggestion? Documentation improvements are welcome! +- Keep guides clear and concise +- Include examples and code snippets +- Test all commands before documenting +- Update the table of contents when adding new files + +## 🔄 Last Updated + +This documentation is automatically maintained and reflects the current state of the homelab repository. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..6e3f2ed --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,497 @@ +# Getting Started with Homelab + +This guide will walk you through setting up your homelab from scratch. + +## Prerequisites + +### Hardware Requirements +- **Server/VM**: Linux server with Docker support +- **CPU**: 2+ cores recommended +- **RAM**: 8GB minimum, 16GB+ recommended +- **Storage**: 100GB+ for Docker containers and config +- **Optional GPU**: NVIDIA GPU for hardware transcoding (Jellyfin, Immich) + +### Software Requirements +- **Operating System**: Ubuntu 22.04 or similar Linux distribution +- **Docker**: Version 24.0+ +- **Docker Compose**: Version 2.20+ +- **Git**: For cloning the repository +- **Domain Names**: `*.fig.systems` and `*.edfig.dev` (or your domains) + +### Network Requirements +- **Ports**: 80 and 443 accessible from internet (for Let's Encrypt) +- **DNS**: Ability to create A records for your domains +- **Static IP**: Recommended for your homelab server + +## Step 1: Prepare Your Server + +### Install Docker and Docker Compose + +```bash +# Update package index +sudo apt update + +# Install dependencies +sudo apt install -y ca-certificates curl gnupg lsb-release + +# Add Docker's official GPG key +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg + +# Set up the repository +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + +# Install Docker Engine +sudo apt update +sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +# Add your user to docker group (logout and login after this) +sudo usermod -aG docker $USER + +# Verify installation +docker --version +docker compose version +``` + +### Create Media Directory Structure + +```bash +# Create media folders +sudo mkdir -p /media/{audiobooks,books,comics,complete,downloads,homemovies,incomplete,movies,music,photos,tv} + +# Set ownership (replace with your username) +sudo chown -R $(whoami):$(whoami) /media + +# Verify structure +tree -L 1 /media +``` + +## Step 2: Clone the Repository + +```bash +# Clone the repository +cd ~ +git clone https://github.com/efigueroa/homelab.git +cd homelab + +# Checkout the main branch +git checkout main # or your target branch +``` + +## Step 3: Configure DNS + +You need to point your domains to your server's IP address. + +### Option 1: Wildcard DNS (Recommended) + +Add these A records to your DNS provider: + +``` +*.fig.systems A YOUR_SERVER_IP +*.edfig.dev A YOUR_SERVER_IP +``` + +### Option 2: Individual Records + +Create A records for each service: + +``` +traefik.fig.systems A YOUR_SERVER_IP +lldap.fig.systems A YOUR_SERVER_IP +auth.fig.systems A YOUR_SERVER_IP +home.fig.systems A YOUR_SERVER_IP +backup.fig.systems A YOUR_SERVER_IP +flix.fig.systems A YOUR_SERVER_IP +photos.fig.systems A YOUR_SERVER_IP +# ... and so on for all services +``` + +### Verify DNS + +Wait a few minutes for DNS propagation, then verify: + +```bash +# Test DNS resolution +dig traefik.fig.systems +short +dig lldap.fig.systems +short + +# Should return your server IP +``` + +## Step 4: Configure Environment Variables + +Each service needs its environment variables configured with secure values. + +### Generate Secure Secrets + +Use these commands to generate secure values: + +```bash +# For JWT secrets and session secrets (64 characters) +openssl rand -hex 32 + +# For passwords (32 alphanumeric characters) +openssl rand -base64 32 | tr -d /=+ | cut -c1-32 + +# For API keys (32 characters) +openssl rand -hex 16 +``` + +### Update Core Services + +**LLDAP** (`compose/core/lldap/.env`): +```bash +cd compose/core/lldap +nano .env + +# Update these values: +LLDAP_LDAP_USER_PASS= +LLDAP_JWT_SECRET= +``` + +**Tinyauth** (`compose/core/tinyauth/.env`): +```bash +cd ../tinyauth +nano .env + +# Update these values (LDAP_BIND_PASSWORD must match LLDAP_LDAP_USER_PASS): +LDAP_BIND_PASSWORD= +SESSION_SECRET= +``` + +**Immich** (`compose/media/frontend/immich/.env`): +```bash +cd ../../media/frontend/immich +nano .env + +# Update: +DB_PASSWORD= +``` + +### Update All Other Services + +Go through each service's `.env` file and replace all `changeme_*` values: + +```bash +# Find all files that need updating +grep -r "changeme_" ~/homelab/compose + +# Or update them individually +cd ~/homelab/compose/services/linkwarden +nano .env # Update NEXTAUTH_SECRET, POSTGRES_PASSWORD, MEILI_MASTER_KEY + +cd ../vikunja +nano .env # Update VIKUNJA_DATABASE_PASSWORD, VIKUNJA_SERVICE_JWTSECRET, POSTGRES_PASSWORD +``` + +💡 **Tip**: Keep your secrets in a password manager! + +See [Secrets Management Guide](./guides/secrets-management.md) for detailed instructions. + +## Step 5: Create Docker Network + +```bash +# Create the external homelab network +docker network create homelab + +# Verify it was created +docker network ls | grep homelab +``` + +## Step 6: Deploy Services + +Deploy services in order, starting with core infrastructure: + +### Deploy Core Infrastructure + +```bash +cd ~/homelab + +# Deploy Traefik (reverse proxy) +cd compose/core/traefik +docker compose up -d + +# Check logs to ensure it starts successfully +docker compose logs -f + +# Wait for "Server configuration reloaded" message, then Ctrl+C +``` + +```bash +# Deploy LLDAP (user directory) +cd ../lldap +docker compose up -d +docker compose logs -f + +# Access: https://lldap.fig.systems +# Default login: admin / +``` + +```bash +# Deploy Tinyauth (SSO) +cd ../tinyauth +docker compose up -d +docker compose logs -f + +# Access: https://auth.fig.systems +``` + +### Create LLDAP Users + +Before deploying other services, create your user in LLDAP: + +1. Go to https://lldap.fig.systems +2. Login with admin credentials +3. Create your user: + - Username: `edfig` (or your choice) + - Email: `admin@edfig.dev` + - Password: strong password + - Add to `lldap_admin` group + +### Deploy Media Services + +```bash +cd ~/homelab/compose/media/frontend + +# Jellyfin +cd jellyfin +docker compose up -d +# Access: https://flix.fig.systems + +# Immich +cd ../immich +docker compose up -d +# Access: https://photos.fig.systems + +# Jellyseerr +cd ../jellyseer +docker compose up -d +# Access: https://requests.fig.systems +``` + +```bash +# Media automation +cd ~/homelab/compose/media/automation + +cd sonarr && docker compose up -d && cd .. +cd radarr && docker compose up -d && cd .. +cd sabnzbd && docker compose up -d && cd .. +cd qbittorrent && docker compose up -d && cd .. +``` + +### Deploy Utility Services + +```bash +cd ~/homelab/compose/services + +# Dashboard (start with this - it shows all your services!) +cd homarr && docker compose up -d && cd .. +# Access: https://home.fig.systems + +# Backup manager +cd backrest && docker compose up -d && cd .. +# Access: https://backup.fig.systems + +# Other services +cd linkwarden && docker compose up -d && cd .. +cd vikunja && docker compose up -d && cd .. +cd lubelogger && docker compose up -d && cd .. +cd calibre-web && docker compose up -d && cd .. +cd booklore && docker compose up -d && cd .. +cd FreshRSS && docker compose up -d && cd .. +cd rsshub && docker compose up -d && cd .. +cd microbin && docker compose up -d && cd .. +cd filebrowser && docker compose up -d && cd .. +``` + +### Quick Deploy All (Alternative) + +If you've configured everything and want to deploy all at once: + +```bash +cd ~/homelab + +# Create a deployment script +cat > deploy-all.sh << 'SCRIPT' +#!/bin/bash +set -e + +echo "Deploying homelab services..." + +# Core +echo "==> Core Infrastructure" +cd compose/core/traefik && docker compose up -d && cd ../../.. +sleep 5 +cd compose/core/lldap && docker compose up -d && cd ../../.. +sleep 5 +cd compose/core/tinyauth && docker compose up -d && cd ../../.. + +# Media +echo "==> Media Services" +cd compose/media/frontend/immich && docker compose up -d && cd ../../../.. +cd compose/media/frontend/jellyfin && docker compose up -d && cd ../../../.. +cd compose/media/frontend/jellyseer && docker compose up -d && cd ../../../.. +cd compose/media/automation/sonarr && docker compose up -d && cd ../../../.. +cd compose/media/automation/radarr && docker compose up -d && cd ../../../.. +cd compose/media/automation/sabnzbd && docker compose up -d && cd ../../../.. +cd compose/media/automation/qbittorrent && docker compose up -d && cd ../../../.. + +# Utility +echo "==> Utility Services" +cd compose/services/homarr && docker compose up -d && cd ../.. +cd compose/services/backrest && docker compose up -d && cd ../.. +cd compose/services/linkwarden && docker compose up -d && cd ../.. +cd compose/services/vikunja && docker compose up -d && cd ../.. +cd compose/services/lubelogger && docker compose up -d && cd ../.. +cd compose/services/calibre-web && docker compose up -d && cd ../.. +cd compose/services/booklore && docker compose up -d && cd ../.. +cd compose/services/FreshRSS && docker compose up -d && cd ../.. +cd compose/services/rsshub && docker compose up -d && cd ../.. +cd compose/services/microbin && docker compose up -d && cd ../.. +cd compose/services/filebrowser && docker compose up -d && cd ../.. + +echo "==> Deployment Complete!" +echo "Access your dashboard at: https://home.fig.systems" +SCRIPT + +chmod +x deploy-all.sh +./deploy-all.sh +``` + +## Step 7: Verify Deployment + +### Check All Containers Are Running + +```bash +# List all containers +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + +# Check for any stopped containers +docker ps -a --filter "status=exited" +``` + +### Verify SSL Certificates + +```bash +# Test SSL certificate +curl -I https://home.fig.systems + +# Should show HTTP/2 200 and valid SSL cert +``` + +### Access Services + +Visit your dashboard: **https://home.fig.systems** + +This should show all your services with their status! + +### Test SSO + +1. Go to any SSO-protected service (e.g., https://tasks.fig.systems) +2. You should be redirected to https://auth.fig.systems +3. Login with your LLDAP credentials +4. You should be redirected back to the service + +## Step 8: Initial Service Configuration + +### Jellyfin Setup +1. Go to https://flix.fig.systems +2. Select language and create admin account +3. Add media libraries: + - Movies: `/media/movies` + - TV Shows: `/media/tv` + - Music: `/media/music` + - Photos: `/media/photos` + +### Immich Setup +1. Go to https://photos.fig.systems +2. Create admin account +3. Upload some photos to test +4. Configure storage in Settings + +### Sonarr/Radarr Setup +1. Go to https://sonarr.fig.systems and https://radarr.fig.systems +2. Complete initial setup wizard +3. Add indexers (for finding content) +4. Add download clients: + - SABnzbd: http://sabnzbd:8080 + - qBittorrent: http://qbittorrent:8080 +5. Configure root folders: + - Sonarr: `/media/tv` + - Radarr: `/media/movies` + +### Jellyseerr Setup +1. Go to https://requests.fig.systems +2. Sign in with Jellyfin +3. Connect to Sonarr and Radarr +4. Configure user permissions + +### Backrest Setup +1. Go to https://backup.fig.systems +2. Add Backblaze B2 repository (see [Backup Guide](./services/backup.md)) +3. Create backup plan for Immich photos +4. Schedule automated backups + +## Step 9: Optional Configurations + +### Enable GPU Acceleration + +If you have an NVIDIA GPU, see [GPU Setup Guide](./guides/gpu-setup.md). + +### Configure Backups + +See [Backup Operations Guide](./operations/backups.md). + +### Add More Services + +See [Adding Services Guide](./guides/adding-services.md). + +## Next Steps + +- ✅ [Set up automated backups](./operations/backups.md) +- ✅ [Configure monitoring](./operations/monitoring.md) +- ✅ [Review security settings](./guides/security.md) +- ✅ [Enable GPU acceleration](./guides/gpu-setup.md) (optional) +- ✅ [Configure media automation](./services/media-stack.md) + +## Troubleshooting + +If you encounter issues during setup, see: +- [Common Issues](./troubleshooting/common-issues.md) +- [FAQ](./troubleshooting/faq.md) +- [Debugging Guide](./troubleshooting/debugging.md) + +## Quick Command Reference + +```bash +# View all running containers +docker ps + +# View logs for a service +cd compose/path/to/service +docker compose logs -f + +# Restart a service +docker compose restart + +# Stop a service +docker compose down + +# Update and restart a service +docker compose pull +docker compose up -d + +# View resource usage +docker stats +``` + +## Getting Help + +- Check the [FAQ](./troubleshooting/faq.md) +- Review service-specific guides in [docs/services/](./services/) +- Check container logs for errors +- Verify DNS and SSL certificates + +Welcome to your homelab! 🎉 diff --git a/docs/guides/gpu-setup.md b/docs/guides/gpu-setup.md new file mode 100644 index 0000000..022114c --- /dev/null +++ b/docs/guides/gpu-setup.md @@ -0,0 +1,725 @@ +# NVIDIA GPU Acceleration Setup (GTX 1070) + +This guide covers setting up NVIDIA GPU acceleration for your homelab running on **Proxmox 9 (Debian 13)** with an **NVIDIA GTX 1070**. + +## Overview + +GPU acceleration provides significant benefits: +- **Jellyfin**: Hardware video transcoding (H.264, HEVC) +- **Immich**: Faster ML inference (face recognition, object detection) +- **Performance**: 10-20x faster transcoding vs CPU +- **Efficiency**: Lower power consumption, CPU freed for other tasks + +**Your Hardware:** +- **GPU**: NVIDIA GTX 1070 (Pascal architecture) +- **Capabilities**: NVENC (encoding), NVDEC (decoding), CUDA +- **Max Concurrent Streams**: 2 (can be unlocked) +- **Supported Codecs**: H.264, HEVC (H.265) + +## Architecture Overview + +``` +Proxmox Host (Debian 13) + │ + ├─ NVIDIA Drivers (host) + ├─ NVIDIA Container Toolkit + │ + └─ Docker VM/LXC + │ + ├─ GPU passthrough + │ + └─ Jellyfin/Immich containers + └─ Hardware transcoding +``` + +## Part 1: Proxmox Host Setup + +### Step 1.1: Enable IOMMU (for GPU Passthrough) + +**Edit GRUB configuration:** + +```bash +# SSH into Proxmox host +ssh root@proxmox-host + +# Edit GRUB config +nano /etc/default/grub +``` + +**Find this line:** +``` +GRUB_CMDLINE_LINUX_DEFAULT="quiet" +``` + +**Replace with (Intel CPU):** +``` +GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt" +``` + +**Or (AMD CPU):** +``` +GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt" +``` + +**Update GRUB and reboot:** +```bash +update-grub +reboot +``` + +**Verify IOMMU is enabled:** +```bash +dmesg | grep -e DMAR -e IOMMU + +# Should see: "IOMMU enabled" +``` + +### Step 1.2: Load VFIO Modules + +**Edit modules:** +```bash +nano /etc/modules +``` + +**Add these lines:** +``` +vfio +vfio_iommu_type1 +vfio_pci +vfio_virqfd +``` + +**Update initramfs:** +```bash +update-initramfs -u -k all +reboot +``` + +### Step 1.3: Find GPU PCI ID + +```bash +lspci -nn | grep -i nvidia + +# Example output: +# 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP104 [GeForce GTX 1070] [10de:1b81] (rev a1) +# 01:00.1 Audio device [0403]: NVIDIA Corporation GP104 High Definition Audio Controller [10de:10f0] (rev a1) +``` + +**Note the IDs**: `10de:1b81` and `10de:10f0` (your values may differ) + +### Step 1.4: Configure VFIO + +**Create VFIO config:** +```bash +nano /etc/modprobe.d/vfio.conf +``` + +**Add (replace with your IDs from above):** +``` +options vfio-pci ids=10de:1b81,10de:10f0 +softdep nvidia pre: vfio-pci +``` + +**Blacklist nouveau (open-source NVIDIA driver):** +```bash +echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf +``` + +**Update and reboot:** +```bash +update-initramfs -u -k all +reboot +``` + +**Verify GPU is bound to VFIO:** +```bash +lspci -nnk -d 10de:1b81 + +# Should show: +# Kernel driver in use: vfio-pci +``` + +## Part 2: VM/LXC Setup + +### Option A: Using VM (Recommended for Docker) + +**Create Ubuntu 24.04 VM with GPU passthrough:** + +1. **Create VM in Proxmox UI**: + - OS: Ubuntu 24.04 Server + - CPU: 4+ cores + - RAM: 16GB+ + - Disk: 100GB+ + +2. **Add PCI Device** (GPU): + - Hardware → Add → PCI Device + - Device: Select your GTX 1070 (01:00.0) + - ✅ All Functions + - ✅ Primary GPU (if no other GPU) + - ✅ PCI-Express + +3. **Add PCI Device** (GPU Audio): + - Hardware → Add → PCI Device + - Device: NVIDIA Audio (01:00.1) + - ✅ All Functions + +4. **Machine Settings**: + - Machine: q35 + - BIOS: OVMF (UEFI) + - Add EFI Disk + +5. **Start VM** and install Ubuntu + +### Option B: Using LXC (Advanced, Less Stable) + +**Note**: LXC with GPU is less reliable. VM recommended. + +If you insist on LXC: +```bash +# Edit LXC config +nano /etc/pve/lxc/VMID.conf + +# Add: +lxc.cgroup2.devices.allow: c 195:* rwm +lxc.cgroup2.devices.allow: c 509:* rwm +lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file +lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file +lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file +``` + +**For this guide, we'll use VM (Option A)**. + +## Part 3: VM Guest Setup (Debian 13) + +Now we're inside the Ubuntu/Debian VM where Docker runs. + +### Step 3.1: Install NVIDIA Drivers + +**SSH into your Docker VM:** +```bash +ssh user@docker-vm +``` + +**Update system:** +```bash +sudo apt update +sudo apt upgrade -y +``` + +**Debian 13 - Install NVIDIA drivers:** +```bash +# Add non-free repositories +sudo nano /etc/apt/sources.list + +# Add 'non-free non-free-firmware' to each line, example: +deb http://deb.debian.org/debian bookworm main non-free non-free-firmware +deb http://deb.debian.org/debian bookworm-updates main non-free non-free-firmware + +# Update and install +sudo apt update +sudo apt install -y linux-headers-$(uname -r) +sudo apt install -y nvidia-driver nvidia-smi + +# Reboot +sudo reboot +``` + +**Verify driver installation:** +```bash +nvidia-smi + +# Should show: +# +-----------------------------------------------------------------------------+ +# | NVIDIA-SMI 535.xx.xx Driver Version: 535.xx.xx CUDA Version: 12.2 | +# |-------------------------------+----------------------+----------------------+ +# | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +# | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +# |===============================+======================+======================| +# | 0 NVIDIA GeForce ... Off | 00000000:01:00.0 Off | N/A | +# | 30% 35C P8 10W / 150W | 0MiB / 8192MiB | 0% Default | +# +-------------------------------+----------------------+----------------------+ +``` + +✅ **Success!** Your GTX 1070 is now accessible in the VM. + +### Step 3.2: Install NVIDIA Container Toolkit + +**Add NVIDIA Container Toolkit repository:** +```bash +curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo 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' | \ + sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list +``` + +**Install toolkit:** +```bash +sudo apt update +sudo apt install -y nvidia-container-toolkit +``` + +**Configure Docker to use NVIDIA runtime:** +```bash +sudo nvidia-ctk runtime configure --runtime=docker +``` + +**Restart Docker:** +```bash +sudo systemctl restart docker +``` + +**Verify Docker can access GPU:** +```bash +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi + +# Should show nvidia-smi output from inside container +``` + +✅ **Success!** Docker can now use your GPU. + +## Part 4: Configure Jellyfin for GPU Transcoding + +### Step 4.1: Update Jellyfin Compose File + +**Edit compose file:** +```bash +cd ~/homelab/compose/media/frontend/jellyfin +nano compose.yaml +``` + +**Uncomment the GPU sections:** + +```yaml +services: + jellyfin: + container_name: jellyfin + image: lscr.io/linuxserver/jellyfin:latest + env_file: + - .env + volumes: + - ./config:/config + - ./cache:/cache + - /media/movies:/media/movies:ro + - /media/tv:/media/tv:ro + - /media/music:/media/music:ro + - /media/photos:/media/photos:ro + - /media/homemovies:/media/homemovies:ro + ports: + - "8096:8096" + - "7359:7359/udp" + restart: unless-stopped + networks: + - homelab + labels: + traefik.enable: true + traefik.http.routers.jellyfin.rule: Host(`flix.fig.systems`) || Host(`flix.edfig.dev`) + traefik.http.routers.jellyfin.entrypoints: websecure + traefik.http.routers.jellyfin.tls.certresolver: letsencrypt + traefik.http.services.jellyfin.loadbalancer.server.port: 8096 + + # UNCOMMENT THESE LINES FOR GTX 1070: + runtime: nvidia + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + +networks: + homelab: + external: true +``` + +**Restart Jellyfin:** +```bash +docker compose down +docker compose up -d +``` + +**Check logs:** +```bash +docker compose logs -f + +# Should see lines about NVENC/CUDA being detected +``` + +### Step 4.2: Enable in Jellyfin UI + +1. Go to https://flix.fig.systems +2. Dashboard → Playback → Transcoding +3. **Hardware acceleration**: NVIDIA NVENC +4. **Enable hardware decoding for**: + - ✅ H264 + - ✅ HEVC + - ✅ VC1 + - ✅ VP8 + - ✅ MPEG2 +5. **Enable hardware encoding** +6. **Enable encoding in HEVC format** +7. Save + +### Step 4.3: Test Transcoding + +1. Play a video in Jellyfin web UI +2. Click Settings (gear icon) → Quality +3. Select a lower bitrate to force transcoding +4. In another terminal: + ```bash + nvidia-smi + + # While video is transcoding, should see: + # GPU utilization: 20-40% + # Memory usage: 500-1000MB + ``` + +✅ **Success!** Jellyfin is using your GTX 1070! + +## Part 5: Configure Immich for GPU Acceleration + +Immich can use GPU for two purposes: +1. **ML Inference** (face recognition, object detection) +2. **Video Transcoding** + +### Step 5.1: ML Inference (CUDA) + +**Edit Immich compose file:** +```bash +cd ~/homelab/compose/media/frontend/immich +nano compose.yaml +``` + +**Change ML image to CUDA version:** + +Find this line: +```yaml +image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} +``` + +Change to: +```yaml +image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda +``` + +**Add GPU support:** + +```yaml + immich-machine-learning: + container_name: immich_machine_learning + image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda + volumes: + - model-cache:/cache + env_file: + - .env + restart: always + networks: + - immich_internal + + # ADD THESE LINES: + runtime: nvidia + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] +``` + +### Step 5.2: Video Transcoding (NVENC) + +**For video transcoding, add to immich-server:** + +```yaml + immich-server: + container_name: immich_server + image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} + # ... existing config ... + + # ADD THESE LINES: + runtime: nvidia + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] +``` + +**Restart Immich:** +```bash +docker compose down +docker compose up -d +``` + +### Step 5.3: Enable in Immich UI + +1. Go to https://photos.fig.systems +2. Administration → Settings → Video Transcoding +3. **Transcoding**: h264 (NVENC) +4. **Hardware Acceleration**: NVIDIA +5. Save + +6. Administration → Settings → Machine Learning +7. **Facial Recognition**: Enabled +8. **Object Detection**: Enabled +9. Should automatically use CUDA + +### Step 5.4: Test ML Inference + +1. Upload photos with faces +2. In terminal: + ```bash + nvidia-smi + + # While processing, should see: + # GPU utilization: 50-80% + # Memory usage: 2-4GB + ``` + +✅ **Success!** Immich is using GPU for ML inference! + +## Part 6: Performance Tuning + +### GTX 1070 Specific Settings + +**Jellyfin optimal settings:** +- Hardware acceleration: NVIDIA NVENC +- Target transcode bandwidth: Let clients decide +- Enable hardware encoding: Yes +- Prefer OS native DXVA or VA-API hardware decoders: No +- Allow encoding in HEVC format: Yes (GTX 1070 supports HEVC) + +**Immich optimal settings:** +- Transcoding: h264 or hevc +- Target resolution: 1080p (for GTX 1070) +- CRF: 23 (good balance) +- Preset: fast + +### Unlock NVENC Stream Limit + +GTX 1070 is limited to 2 concurrent transcoding streams. You can unlock unlimited streams: + +**Install patch:** +```bash +# Inside Docker VM +git clone https://github.com/keylase/nvidia-patch.git +cd nvidia-patch +sudo bash ./patch.sh + +# Reboot +sudo reboot +``` + +**Verify:** +```bash +nvidia-smi + +# Now supports unlimited concurrent streams +``` + +⚠️ **Note**: This is a hack that modifies NVIDIA driver. Use at your own risk. + +### Monitor GPU Usage + +**Real-time monitoring:** +```bash +watch -n 1 nvidia-smi +``` + +**Check GPU usage from Docker:** +```bash +docker stats $(docker ps --format '{{.Names}}' | grep -E 'jellyfin|immich') +``` + +## Troubleshooting + +### GPU Not Detected in VM + +**Check from Proxmox host:** +```bash +lspci | grep -i nvidia +``` + +**Check from VM:** +```bash +lspci | grep -i nvidia +nvidia-smi +``` + +**If not visible in VM:** +1. Verify IOMMU is enabled (`dmesg | grep IOMMU`) +2. Check PCI passthrough is configured correctly +3. Ensure VM is using q35 machine type +4. Verify BIOS is OVMF (UEFI) + +### Docker Can't Access GPU + +**Error**: `could not select device driver "" with capabilities: [[gpu]]` + +**Fix:** +```bash +# Reconfigure NVIDIA runtime +sudo nvidia-ctk runtime configure --runtime=docker +sudo systemctl restart docker + +# Test again +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi +``` + +### Jellyfin Shows "No Hardware Acceleration Available" + +**Check:** +```bash +# Verify container has GPU access +docker exec jellyfin nvidia-smi + +# Check Jellyfin logs +docker logs jellyfin | grep -i nvenc +``` + +**Fix:** +1. Ensure `runtime: nvidia` is uncommented +2. Verify `deploy.resources.reservations.devices` is configured +3. Restart container: `docker compose up -d` + +### Transcoding Fails with "Failed to Open GPU" + +**Check:** +```bash +# GPU might be busy +nvidia-smi + +# Kill processes using GPU +sudo fuser -v /dev/nvidia* +``` + +### Low GPU Utilization During Transcoding + +**Normal**: GTX 1070 is powerful. 20-40% utilization is expected for single stream. + +**To max out GPU:** +- Transcode multiple streams simultaneously +- Use higher resolution source (4K) +- Enable HEVC encoding + +## Performance Benchmarks (GTX 1070) + +**Typical Performance:** +- **4K HEVC → 1080p H.264**: ~120-150 FPS (real-time) +- **1080p H.264 → 720p H.264**: ~300-400 FPS +- **Concurrent streams**: 4-6 (after unlocking limit) +- **Power draw**: 80-120W during transcoding +- **Temperature**: 55-65°C + +**Compare to CPU (typical 4-core):** +- **4K HEVC → 1080p H.264**: ~10-15 FPS +- CPU would be at 100% utilization +- GPU: 10-15x faster! + +## Monitoring and Maintenance + +### Create GPU Monitoring Dashboard + +**Install nvtop (nvidia-top):** +```bash +sudo apt install nvtop +``` + +**Run:** +```bash +nvtop +``` + +Shows real-time GPU usage, memory, temperature, processes. + +### Check GPU Health + +```bash +# Temperature +nvidia-smi --query-gpu=temperature.gpu --format=csv + +# Memory usage +nvidia-smi --query-gpu=memory.used,memory.total --format=csv + +# Fan speed +nvidia-smi --query-gpu=fan.speed --format=csv + +# Power draw +nvidia-smi --query-gpu=power.draw,power.limit --format=csv +``` + +### Automated Monitoring + +Add to cron: +```bash +crontab -e + +# Add: +*/5 * * * * nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu --format=csv,noheader >> /var/log/gpu-stats.log +``` + +## Next Steps + +✅ GPU is now configured for Jellyfin and Immich! + +**Recommended:** +1. Test transcoding with various file formats +2. Upload photos to Immich and verify ML inference works +3. Monitor GPU temperature and utilization +4. Consider unlocking NVENC stream limit +5. Set up automated monitoring + +**Optional:** +- Configure Tdarr for batch transcoding using GPU +- Set up Plex (also supports NVENC) +- Use GPU for other workloads (AI, rendering) + +## Reference + +### Quick Command Reference + +```bash +# Check GPU from host (Proxmox) +lspci | grep -i nvidia + +# Check GPU from VM +nvidia-smi + +# Test Docker GPU access +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi + +# Monitor GPU real-time +watch -n 1 nvidia-smi + +# Check Jellyfin GPU usage +docker exec jellyfin nvidia-smi + +# Restart Jellyfin with GPU +cd ~/homelab/compose/media/frontend/jellyfin +docker compose down && docker compose up -d + +# View GPU processes +nvidia-smi pmon + +# GPU temperature +nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader +``` + +### GTX 1070 Specifications + +- **Architecture**: Pascal (GP104) +- **CUDA Cores**: 1920 +- **Memory**: 8GB GDDR5 +- **Memory Bandwidth**: 256 GB/s +- **TDP**: 150W +- **NVENC**: 6th generation (H.264, HEVC) +- **NVDEC**: 2nd generation +- **Concurrent Streams**: 2 (unlockable to unlimited) + +--- + +**Your GTX 1070 is now accelerating your homelab! 🚀** diff --git a/docs/guides/secrets-management.md b/docs/guides/secrets-management.md new file mode 100644 index 0000000..ab8dff7 --- /dev/null +++ b/docs/guides/secrets-management.md @@ -0,0 +1,567 @@ +# Secrets and Environment Variables Management + +This guide explains how to properly configure and manage secrets in your homelab. + +## Overview + +Every service uses environment variables stored in `.env` files for configuration. This approach: +- ✅ Keeps secrets out of version control +- ✅ Makes configuration changes easy +- ✅ Follows Docker Compose best practices +- ✅ Provides clear examples of what each secret should look like + +## Finding What Needs Configuration + +### Search for Placeholder Values + +All secrets that need changing are marked with `changeme_`: + +```bash +# Find all files with placeholder secrets +grep -r "changeme_" ~/homelab/compose + +# Output shows exactly what needs updating: +compose/core/lldap/.env:LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password +compose/core/lldap/.env:LLDAP_JWT_SECRET=changeme_please_set_random_secret +compose/core/tinyauth/.env:LDAP_BIND_PASSWORD=changeme_please_set_secure_password +... +``` + +### Count What's Left to Configure + +```bash +# Count how many secrets still need updating +grep -r "changeme_" ~/homelab/compose | wc -l + +# Goal: 0 +``` + +## Generating Secrets + +Each `.env` file includes comments showing: +1. What the secret is for +2. How to generate it +3. What format it should be in + +### Common Secret Types + +#### 1. JWT Secrets (64 characters) + +**Used by**: LLDAP, Vikunja, NextAuth + +**Generate:** +```bash +openssl rand -hex 32 +``` + +**Example output:** +``` +a1b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890 +``` + +**Where to use:** +- `LLDAP_JWT_SECRET` +- `VIKUNJA_SERVICE_JWTSECRET` +- `NEXTAUTH_SECRET` +- `SESSION_SECRET` + +#### 2. Database Passwords (32 alphanumeric) + +**Used by**: Postgres, Immich, Vikunja, Linkwarden + +**Generate:** +```bash +openssl rand -base64 32 | tr -d /=+ | cut -c1-32 +``` + +**Example output:** +``` +aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1 +``` + +**Where to use:** +- `DB_PASSWORD` (Immich) +- `POSTGRES_PASSWORD` (Vikunja, Linkwarden) +- `VIKUNJA_DATABASE_PASSWORD` + +#### 3. Strong Passwords (16+ characters, mixed) + +**Used by**: LLDAP admin, service admin accounts + +**Generate:** +```bash +# Option 1: Using pwgen (install: apt install pwgen) +pwgen -s 20 1 + +# Option 2: Using openssl +openssl rand -base64 20 | tr -d /=+ + +# Option 3: Manual (recommended for main admin password) +# Create something memorable but strong +# Example format: MyS3cur3P@ssw0rd!2024#HomeL@b +``` + +**Where to use:** +- `LLDAP_LDAP_USER_PASS` +- `LDAP_BIND_PASSWORD` (must match LLDAP_LDAP_USER_PASS!) + +#### 4. API Keys / Master Keys (32 characters) + +**Used by**: Meilisearch, various APIs + +**Generate:** +```bash +openssl rand -hex 16 +``` + +**Example output:** +``` +f6g7h8i901234abcdef567890a1b2c3d +``` + +**Where to use:** +- `MEILI_MASTER_KEY` + +## Service-Specific Configuration + +### Core Services + +#### LLDAP (`compose/core/lldap/.env`) + +```bash +# Edit the file +cd ~/homelab/compose/core/lldap +nano .env +``` + +**Required secrets:** + +```env +# Admin password - use a STRONG password you'll remember +# Example: MyS3cur3P@ssw0rd!2024#HomeL@b +LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password + +# JWT secret - generate with: openssl rand -hex 32 +# Example: a1b2c3d4e5f67890abcdef1234567890a1b2c3d4e5f67890abcdef1234567890 +LLDAP_JWT_SECRET=changeme_please_set_random_secret +``` + +**Generate and update:** +```bash +# Generate JWT secret +echo "LLDAP_JWT_SECRET=$(openssl rand -hex 32)" + +# Choose a strong password for LLDAP_LDAP_USER_PASS +# Write it down - you'll need it for Tinyauth too! +``` + +#### Tinyauth (`compose/core/tinyauth/.env`) + +```bash +cd ~/homelab/compose/core/tinyauth +nano .env +``` + +**Required secrets:** + +```env +# MUST match LLDAP_LDAP_USER_PASS from lldap/.env +LDAP_BIND_PASSWORD=changeme_please_set_secure_password + +# Session secret - generate with: openssl rand -hex 32 +SESSION_SECRET=changeme_please_set_random_session_secret +``` + +**⚠️ CRITICAL**: `LDAP_BIND_PASSWORD` must exactly match `LLDAP_LDAP_USER_PASS`! + +```bash +# Generate session secret +echo "SESSION_SECRET=$(openssl rand -hex 32)" +``` + +### Media Services + +#### Immich (`compose/media/frontend/immich/.env`) + +```bash +cd ~/homelab/compose/media/frontend/immich +nano .env +``` + +**Required secrets:** + +```env +# Database password - generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32 +DB_PASSWORD=changeme_please_set_secure_password +``` + +```bash +# Generate +echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)" +``` + +### Utility Services + +#### Linkwarden (`compose/services/linkwarden/.env`) + +```bash +cd ~/homelab/compose/services/linkwarden +nano .env +``` + +**Required secrets:** + +```env +# NextAuth secret - generate with: openssl rand -hex 32 +NEXTAUTH_SECRET=changeme_please_set_random_secret_key + +# Postgres password - generate with: openssl rand -base64 32 | tr -d /=+ | cut -c1-32 +POSTGRES_PASSWORD=changeme_please_set_secure_postgres_password + +# Meilisearch master key - generate with: openssl rand -hex 16 +MEILI_MASTER_KEY=changeme_please_set_meili_master_key +``` + +```bash +# Generate all three +echo "NEXTAUTH_SECRET=$(openssl rand -hex 32)" +echo "POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)" +echo "MEILI_MASTER_KEY=$(openssl rand -hex 16)" +``` + +#### Vikunja (`compose/services/vikunja/.env`) + +```bash +cd ~/homelab/compose/services/vikunja +nano .env +``` + +**Required secrets:** + +```env +# Database password (used in two places - must match!) +VIKUNJA_DATABASE_PASSWORD=changeme_please_set_secure_password +POSTGRES_PASSWORD=changeme_please_set_secure_password # Same value! + +# JWT secret - generate with: openssl rand -hex 32 +VIKUNJA_SERVICE_JWTSECRET=changeme_please_set_random_jwt_secret +``` + +**⚠️ CRITICAL**: Both password fields must match! + +```bash +# Generate +DB_PASS=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32) +echo "VIKUNJA_DATABASE_PASSWORD=$DB_PASS" +echo "POSTGRES_PASSWORD=$DB_PASS" +echo "VIKUNJA_SERVICE_JWTSECRET=$(openssl rand -hex 32)" +``` + +## Automated Configuration Script + +Create a script to generate all secrets at once: + +```bash +#!/bin/bash +# save as: ~/homelab/generate-secrets.sh + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo -e "${YELLOW}Homelab Secrets Generator${NC}\n" + +echo "This script will help you generate secure secrets for your homelab." +echo "You'll need to manually copy these values into the respective .env files." +echo "" + +# LLDAP +echo -e "${GREEN}=== LLDAP (compose/core/lldap/.env) ===${NC}" +echo "LLDAP_JWT_SECRET=$(openssl rand -hex 32)" +echo "LLDAP_LDAP_USER_PASS=" +echo "" + +# Tinyauth +echo -e "${GREEN}=== Tinyauth (compose/core/tinyauth/.env) ===${NC}" +echo "LDAP_BIND_PASSWORD=" +echo "SESSION_SECRET=$(openssl rand -hex 32)" +echo "" + +# Immich +echo -e "${GREEN}=== Immich (compose/media/frontend/immich/.env) ===${NC}" +echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)" +echo "" + +# Linkwarden +echo -e "${GREEN}=== Linkwarden (compose/services/linkwarden/.env) ===${NC}" +echo "NEXTAUTH_SECRET=$(openssl rand -hex 32)" +echo "POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32)" +echo "MEILI_MASTER_KEY=$(openssl rand -hex 16)" +echo "" + +# Vikunja +VIKUNJA_PASS=$(openssl rand -base64 32 | tr -d /=+ | cut -c1-32) +echo -e "${GREEN}=== Vikunja (compose/services/vikunja/.env) ===${NC}" +echo "VIKUNJA_DATABASE_PASSWORD=$VIKUNJA_PASS" +echo "POSTGRES_PASSWORD=$VIKUNJA_PASS # Must match above!" +echo "VIKUNJA_SERVICE_JWTSECRET=$(openssl rand -hex 32)" +echo "" + +echo -e "${YELLOW}Done! Copy these values into your .env files.${NC}" +echo "" +echo "Don't forget to:" +echo "1. Choose a strong LLDAP_LDAP_USER_PASS manually" +echo "2. Use the same password for LDAP_BIND_PASSWORD in tinyauth" +echo "3. Save all secrets in a password manager" +``` + +**Usage:** +```bash +chmod +x ~/homelab/generate-secrets.sh +~/homelab/generate-secrets.sh > secrets.txt + +# Review and copy secrets +cat secrets.txt + +# Keep this file safe or delete after copying to .env files +``` + +## Security Best Practices + +### 1. Use a Password Manager + +Store all secrets in a password manager: +- **1Password**: Great for teams +- **Bitwarden**: Self-hostable option +- **KeePassXC**: Offline, open-source + +Create an entry for each service with: +- Service name +- URL +- All secrets from `.env` file +- Admin credentials + +### 2. Never Commit Secrets + +The repository `.gitignore` already excludes `.env` files, but double-check: + +```bash +# Verify .env files are ignored +git status + +# Should NOT show any .env files +``` + +### 3. Backup Your Secrets + +```bash +# Create encrypted backup of all .env files +cd ~/homelab +tar czf env-backup-$(date +%Y%m%d).tar.gz $(find compose -name ".env") + +# Encrypt with GPG +gpg -c env-backup-$(date +%Y%m%d).tar.gz + +# Store encrypted file safely +mv env-backup-*.tar.gz.gpg ~/backups/ + +# Delete unencrypted tar +rm env-backup-*.tar.gz +``` + +### 4. Rotate Secrets Regularly + +Change critical secrets periodically: +- **Admin passwords**: Every 90 days +- **JWT secrets**: Every 180 days +- **Database passwords**: When personnel changes + +### 5. Limit Secret Access + +- Don't share raw secrets over email/chat +- Use password manager's sharing features +- Delete shared secrets when no longer needed + +## Verification + +### Check All Secrets Are Set + +```bash +# Should return 0 (no changeme_ values left) +grep -r "changeme_" ~/homelab/compose | wc -l +``` + +### Test Service Startup + +```bash +# Start a service and check for password errors +cd ~/homelab/compose/core/lldap +docker compose up -d +docker compose logs + +# Should NOT see: +# - "invalid password" +# - "authentication failed" +# - "secret not set" +``` + +### Verify SSO Works + +1. Start LLDAP and Tinyauth +2. Access protected service (e.g., https://tasks.fig.systems) +3. Should redirect to auth.fig.systems +4. Login with LLDAP credentials +5. Should redirect back to service + +If this works, your LLDAP ↔ Tinyauth passwords match! ✅ + +## Common Mistakes + +### ❌ Using Weak Passwords + +**Don't:** +```env +LLDAP_LDAP_USER_PASS=password123 +``` + +**Do:** +```env +LLDAP_LDAP_USER_PASS=MyS3cur3P@ssw0rd!2024#HomeL@b +``` + +### ❌ Mismatched Passwords + +**Don't:** +```env +# In lldap/.env +LLDAP_LDAP_USER_PASS=password1 + +# In tinyauth/.env +LDAP_BIND_PASSWORD=password2 # Different! +``` + +**Do:** +```env +# In lldap/.env +LLDAP_LDAP_USER_PASS=MyS3cur3P@ssw0rd!2024#HomeL@b + +# In tinyauth/.env +LDAP_BIND_PASSWORD=MyS3cur3P@ssw0rd!2024#HomeL@b # Same! +``` + +### ❌ Using Same Secret Everywhere + +**Don't:** +```env +# Same secret in multiple places +LLDAP_JWT_SECRET=abc123 +NEXTAUTH_SECRET=abc123 +SESSION_SECRET=abc123 +``` + +**Do:** +```env +# Unique secret for each +LLDAP_JWT_SECRET=a1b2c3d4e5f67890... +NEXTAUTH_SECRET=f6g7h8i9j0k1l2m3... +SESSION_SECRET=x9y8z7w6v5u4t3s2... +``` + +### ❌ Forgetting to Update Both Password Fields + +In Vikunja `.env`, both must match: +```env +# Both must be the same! +VIKUNJA_DATABASE_PASSWORD=aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1 +POSTGRES_PASSWORD=aB3dEf7HiJ9kLmN2oPqR5sTuV8wXyZ1 +``` + +## Troubleshooting + +### "Authentication failed" in Tinyauth + +**Cause**: LDAP_BIND_PASSWORD doesn't match LLDAP_LDAP_USER_PASS + +**Fix**: +```bash +# Check LLDAP password +grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env + +# Check Tinyauth password +grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env + +# They should be identical! +``` + +### "Invalid JWT" errors + +**Cause**: JWT_SECRET is too short or invalid format + +**Fix**: +```bash +# Regenerate with proper length +openssl rand -hex 32 + +# Update in .env file +``` + +### "Database connection failed" + +**Cause**: Database password mismatch + +**Fix**: +```bash +# Check both password fields match +grep -E "(POSTGRES_PASSWORD|DATABASE_PASSWORD)" compose/services/vikunja/.env + +# Both should be identical +``` + +## Next Steps + +Once all secrets are configured: +1. ✅ [Deploy services](../getting-started.md#step-6-deploy-services) +2. ✅ [Configure SSO](../services/sso-setup.md) +3. ✅ [Set up backups](../operations/backups.md) +4. ✅ Store secrets in password manager +5. ✅ Create encrypted backup of .env files + +## Reference + +### Quick Command Reference + +```bash +# Generate 64-char hex +openssl rand -hex 32 + +# Generate 32-char password +openssl rand -base64 32 | tr -d /=+ | cut -c1-32 + +# Generate 32-char hex +openssl rand -hex 16 + +# Find all changeme_ values +grep -r "changeme_" compose/ + +# Count remaining secrets to configure +grep -r "changeme_" compose/ | wc -l + +# Backup all .env files (encrypted) +tar czf env-files.tar.gz $(find compose -name ".env") +gpg -c env-files.tar.gz +``` + +### Secret Types Quick Reference + +| Secret Type | Command | Example Length | Used By | +|-------------|---------|----------------|---------| +| JWT Secret | `openssl rand -hex 32` | 64 chars | LLDAP, Vikunja, NextAuth | +| Session Secret | `openssl rand -hex 32` | 64 chars | Tinyauth | +| DB Password | `openssl rand -base64 32 \| tr -d /=+ \| cut -c1-32` | 32 chars | Postgres, Immich | +| API Key | `openssl rand -hex 16` | 32 chars | Meilisearch | +| Admin Password | Manual | 16+ chars | LLDAP admin | + +--- + +**Remember**: Strong, unique secrets are your first line of defense. Take the time to generate them properly! 🔐 diff --git a/docs/quick-reference.md b/docs/quick-reference.md new file mode 100644 index 0000000..643c216 --- /dev/null +++ b/docs/quick-reference.md @@ -0,0 +1,567 @@ +# Quick Reference Guide + +Fast reference for common tasks and commands. + +## Service URLs + +All services accessible via: +- Primary domain: `*.fig.systems` +- Secondary domain: `*.edfig.dev` + +### Core Services +``` +https://traefik.fig.systems # Reverse proxy dashboard +https://lldap.fig.systems # User directory +https://auth.fig.systems # SSO authentication +``` + +### Dashboard & Management +``` +https://home.fig.systems # Homarr dashboard (START HERE!) +https://backup.fig.systems # Backrest backup manager +``` + +### Media Services +``` +https://flix.fig.systems # Jellyfin media server +https://photos.fig.systems # Immich photo library +https://requests.fig.systems # Jellyseerr media requests +https://sonarr.fig.systems # TV show automation +https://radarr.fig.systems # Movie automation +https://sabnzbd.fig.systems # Usenet downloader +https://qbt.fig.systems # qBittorrent client +``` + +### Utility Services +``` +https://links.fig.systems # Linkwarden bookmarks +https://tasks.fig.systems # Vikunja task management +https://garage.fig.systems # LubeLogger vehicle tracking +https://books.fig.systems # Calibre-web ebook library +https://booklore.fig.systems # Book tracking +https://rss.fig.systems # FreshRSS reader +https://files.fig.systems # File Browser +``` + +## Common Commands + +### Docker Compose + +```bash +# Start service +cd ~/homelab/compose/path/to/service +docker compose up -d + +# View logs +docker compose logs -f + +# Restart service +docker compose restart + +# Stop service +docker compose down + +# Update and restart +docker compose pull +docker compose up -d + +# Rebuild service +docker compose up -d --force-recreate +``` + +### Docker Management + +```bash +# List all containers +docker ps + +# List all containers (including stopped) +docker ps -a + +# View logs +docker logs +docker logs -f # Follow logs + +# Execute command in container +docker exec -it bash + +# View resource usage +docker stats + +# Remove stopped containers +docker container prune + +# Remove unused images +docker image prune -a + +# Remove unused volumes (CAREFUL!) +docker volume prune + +# Complete cleanup +docker system prune -a --volumes +``` + +### Service Management + +```bash +# Start all core services +cd ~/homelab/compose/core +for dir in traefik lldap tinyauth; do + cd $dir && docker compose up -d && cd .. +done + +# Stop all services +cd ~/homelab +find compose -name "compose.yaml" -execdir docker compose down \; + +# Restart single service +cd ~/homelab/compose/services/servicename +docker compose restart + +# View all running containers +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" +``` + +### System Checks + +```bash +# Check all containers +docker ps --format "table {{.Names}}\t{{.Status}}" + +# Check network +docker network inspect homelab + +# Check disk usage +docker system df +df -h + +# Check logs for errors +docker compose logs --tail=100 | grep -i error + +# Test DNS resolution +dig home.fig.systems +short + +# Test SSL +curl -I https://home.fig.systems +``` + +## Secret Generation + +```bash +# JWT/Session secrets (64 char) +openssl rand -hex 32 + +# Database passwords (32 char alphanumeric) +openssl rand -base64 32 | tr -d /=+ | cut -c1-32 + +# API keys (32 char hex) +openssl rand -hex 16 + +# Find what needs updating +grep -r "changeme_" ~/homelab/compose +``` + +## Troubleshooting + +### Service Won't Start + +```bash +# Check logs +docker compose logs + +# Check container status +docker compose ps + +# Check for port conflicts +sudo netstat -tulpn | grep :80 +sudo netstat -tulpn | grep :443 + +# Recreate container +docker compose down +docker compose up -d +``` + +### SSL Certificate Issues + +```bash +# Check Traefik logs +docker logs traefik | grep -i certificate + +# Check Let's Encrypt logs +docker logs traefik | grep -i letsencrypt + +# Verify DNS +dig home.fig.systems +short + +# Test port 80 accessibility +curl -I http://home.fig.systems +``` + +### SSO Not Working + +```bash +# Check LLDAP +docker logs lldap + +# Check Tinyauth +docker logs tinyauth + +# Verify passwords match +grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env +grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env + +# Test LDAP connection +docker exec tinyauth nc -zv lldap 3890 +``` + +### Database Connection Failures + +```bash +# Check database container +docker ps | grep postgres + +# View database logs +docker logs + +# Test connection from app container +docker exec nc -zv 5432 + +# Verify password in .env +cat .env | grep POSTGRES_PASSWORD +``` + +## File Locations + +### Configuration +``` +~/homelab/compose/ # All services +~/homelab/compose/core/ # Core infrastructure +~/homelab/compose/media/ # Media services +~/homelab/compose/services/ # Utility services +``` + +### Service Data +``` +compose//config/ # Service configuration +compose//data/ # Service data +compose//db/ # Database files +compose//.env # Environment variables +``` + +### Media Files +``` +/media/movies/ # Movies +/media/tv/ # TV shows +/media/music/ # Music +/media/photos/ # Photos +/media/books/ # Books +/media/downloads/ # Active downloads +/media/complete/ # Completed downloads +``` + +### Logs +``` +docker logs # Container logs +compose//logs/ # Service-specific logs (if configured) +/var/lib/docker/volumes/ # Volume data +``` + +## Network + +### Create Network +```bash +docker network create homelab +``` + +### Inspect Network +```bash +docker network inspect homelab +``` + +### Connect Container to Network +```bash +docker network connect homelab +``` + +## GPU (NVIDIA GTX 1070) + +### Check GPU Status +```bash +nvidia-smi +``` + +### Test GPU in Docker +```bash +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi +``` + +### Monitor GPU Usage +```bash +watch -n 1 nvidia-smi +``` + +### Check GPU in Container +```bash +docker exec jellyfin nvidia-smi +docker exec immich_machine_learning nvidia-smi +``` + +## Backup + +### Backup Configuration Files +```bash +cd ~/homelab +tar czf homelab-config-$(date +%Y%m%d).tar.gz \ + $(find compose -name ".env") \ + $(find compose -name "compose.yaml") +``` + +### Backup Service Data +```bash +# Example: Backup Immich +cd ~/homelab/compose/media/frontend/immich +tar czf immich-backup-$(date +%Y%m%d).tar.gz upload/ config/ +``` + +### Restore Configuration +```bash +tar xzf homelab-config-YYYYMMDD.tar.gz +``` + +## Updates + +### Update Single Service +```bash +cd ~/homelab/compose/path/to/service +docker compose pull +docker compose up -d +``` + +### Update All Services +```bash +cd ~/homelab +for dir in $(find compose -name "compose.yaml" -exec dirname {} \;); do + echo "Updating $dir" + cd $dir + docker compose pull + docker compose up -d + cd ~/homelab +done +``` + +### Update Docker +```bash +sudo apt update +sudo apt upgrade docker-ce docker-ce-cli containerd.io +``` + +## Performance + +### Check Resource Usage +```bash +# Overall system +htop + +# Docker containers +docker stats + +# Disk usage +df -h +docker system df + +# Network usage +iftop +``` + +### Clean Up Disk Space +```bash +# Docker cleanup +docker system prune -a + +# Remove old logs +sudo journalctl --vacuum-time=7d + +# Find large files +du -h /media | sort -rh | head -20 +``` + +## DNS Configuration + +### Cloudflare Example +``` +Type: A +Name: * +Content: YOUR_SERVER_IP +Proxy: Off (disable for Let's Encrypt) +TTL: Auto +``` + +### Local DNS (Pi-hole/hosts file) +``` +192.168.1.100 home.fig.systems +192.168.1.100 flix.fig.systems +192.168.1.100 photos.fig.systems +# ... etc +``` + +## Environment Variables + +### List All Services with Secrets +```bash +find ~/homelab/compose -name ".env" -exec echo {} \; +``` + +### Check for Unconfigured Secrets +```bash +grep -r "changeme_" ~/homelab/compose | wc -l +# Should be 0 +``` + +### Backup All .env Files +```bash +cd ~/homelab +tar czf env-files-$(date +%Y%m%d).tar.gz $(find compose -name ".env") +gpg -c env-files-$(date +%Y%m%d).tar.gz +``` + +## Monitoring + +### Service Health +```bash +# Check all containers are running +docker ps --format "{{.Names}}: {{.Status}}" | grep -v "Up" + +# Check for restarts +docker ps --format "{{.Names}}: {{.Status}}" | grep "Restarting" + +# Check logs for errors +docker compose logs --tail=100 | grep -i error +``` + +### SSL Certificate Expiry +```bash +# Check cert expiry +echo | openssl s_client -servername home.fig.systems -connect home.fig.systems:443 2>/dev/null | openssl x509 -noout -dates +``` + +### Disk Space +```bash +# Overall +df -h + +# Docker +docker system df + +# Media +du -sh /media/* +``` + +## Common File Paths + +```bash +# Core services +~/homelab/compose/core/traefik/ +~/homelab/compose/core/lldap/ +~/homelab/compose/core/tinyauth/ + +# Media +~/homelab/compose/media/frontend/jellyfin/ +~/homelab/compose/media/frontend/immich/ +~/homelab/compose/media/automation/sonarr/ + +# Utilities +~/homelab/compose/services/homarr/ +~/homelab/compose/services/backrest/ +~/homelab/compose/services/linkwarden/ + +# Documentation +~/homelab/docs/ +~/homelab/README.md +``` + +## Port Reference + +``` +80 - HTTP (Traefik) +443 - HTTPS (Traefik) +3890 - LLDAP +6881 - qBittorrent (TCP/UDP) +8096 - Jellyfin +2283 - Immich +``` + +## Default Credentials + +⚠️ **Change these immediately after first login!** + +### qBittorrent +``` +Username: admin +Password: adminadmin +``` + +### Microbin +``` +Check compose/services/microbin/.env +MICROBIN_ADMIN_USERNAME +MICROBIN_ADMIN_PASSWORD +``` + +### All Other Services +Use SSO (LLDAP) or create admin account on first visit. + +## Quick Deployment + +### Deploy Everything +```bash +cd ~/homelab +chmod +x deploy-all.sh +./deploy-all.sh +``` + +### Deploy Core Only +```bash +cd ~/homelab/compose/core/traefik && docker compose up -d +cd ../lldap && docker compose up -d +cd ../tinyauth && docker compose up -d +``` + +### Deploy Media Stack +```bash +cd ~/homelab/compose/media/frontend +for dir in */; do cd "$dir" && docker compose up -d && cd ..; done + +cd ~/homelab/compose/media/automation +for dir in */; do cd "$dir" && docker compose up -d && cd ..; done +``` + +## Emergency Procedures + +### Stop All Services +```bash +cd ~/homelab +find compose -name "compose.yaml" -execdir docker compose down \; +``` + +### Remove All Containers (Nuclear Option) +```bash +docker stop $(docker ps -aq) +docker rm $(docker ps -aq) +``` + +### Reset Network +```bash +docker network rm homelab +docker network create homelab +``` + +### Reset Service +```bash +cd ~/homelab/compose/path/to/service +docker compose down -v # REMOVES VOLUMES! +docker compose up -d +``` + +--- + +**For detailed guides, see the [docs folder](./README.md).** diff --git a/docs/services/README.md b/docs/services/README.md new file mode 100644 index 0000000..d708748 --- /dev/null +++ b/docs/services/README.md @@ -0,0 +1,366 @@ +# Services Overview + +Complete list of all services in the homelab with descriptions and use cases. + +## Core Infrastructure (Required) + +### Traefik +- **URL**: https://traefik.fig.systems +- **Purpose**: Reverse proxy with automatic SSL/TLS +- **Why**: Routes all traffic, manages Let's Encrypt certificates +- **Required**: ✅ Yes - Nothing works without this + +### LLDAP +- **URL**: https://lldap.fig.systems +- **Purpose**: Lightweight LDAP directory for user management +- **Why**: Centralized user database for SSO +- **Required**: ✅ Yes (if using SSO) +- **Default Login**: admin / + +### Tinyauth +- **URL**: https://auth.fig.systems +- **Purpose**: SSO forward authentication middleware +- **Why**: Single login for all services +- **Required**: ✅ Yes (if using SSO) + +## Dashboard & Management + +### Homarr +- **URL**: https://home.fig.systems +- **Purpose**: Service dashboard with auto-discovery +- **Why**: See all your services in one place, monitor status +- **Required**: ⬜ No, but highly recommended +- **Features**: + - Auto-discovers Docker containers + - Customizable widgets + - Service status monitoring + - Integration with media services + +### Backrest +- **URL**: https://backup.fig.systems +- **Purpose**: Backup management with web UI (uses Restic) +- **Why**: Encrypted, deduplicated backups to Backblaze B2 +- **Required**: ⬜ No, but critical for data safety +- **Features**: + - Web-based backup management + - Scheduled backups + - File browsing and restore + - Encryption at rest + - S3-compatible storage support + +## Media Services + +### Jellyfin +- **URL**: https://flix.fig.systems +- **Purpose**: Media server (Netflix alternative) +- **Why**: Watch your movies/TV shows anywhere +- **Required**: ⬜ No +- **Features**: + - Stream to any device + - Hardware transcoding (with GPU) + - Live TV & DVR + - Mobile apps available + - Subtitle support + +### Immich +- **URL**: https://photos.fig.systems +- **Purpose**: Photo and video management (Google Photos alternative) +- **Why**: Self-hosted photo library with ML features +- **Required**: ⬜ No +- **Features**: + - Face recognition (with GPU) + - Object detection + - Mobile apps with auto-upload + - Timeline view + - Album organization + +### Jellyseerr +- **URL**: https://requests.fig.systems +- **Purpose**: Media request management +- **Why**: Let users request movies/shows +- **Required**: ⬜ No (only if using Sonarr/Radarr) +- **Features**: + - Request movies and TV shows + - Integration with Jellyfin + - User permissions + - Notification system + +## Media Automation + +### Sonarr +- **URL**: https://sonarr.fig.systems +- **Purpose**: TV show automation +- **Why**: Automatically download and organize TV shows +- **Required**: ⬜ No +- **Features**: + - Episode tracking + - Automatic downloading + - Quality management + - Calendar view + +### Radarr +- **URL**: https://radarr.fig.systems +- **Purpose**: Movie automation +- **Why**: Automatically download and organize movies +- **Required**: ⬜ No +- **Features**: + - Movie tracking + - Automatic downloading + - Quality profiles + - Collection management + +### SABnzbd +- **URL**: https://sabnzbd.fig.systems +- **Purpose**: Usenet downloader +- **Why**: Download from Usenet newsgroups +- **Required**: ⬜ No (only if using Usenet) +- **Features**: + - Fast downloads + - Automatic verification and repair + - Category-based processing + - Password support + +### qBittorrent +- **URL**: https://qbt.fig.systems +- **Purpose**: BitTorrent client +- **Why**: Download torrents +- **Required**: ⬜ No (only if using torrents) +- **Features**: + - Web-based UI + - RSS support + - Sequential downloading + - IP filtering + +## Productivity Services + +### Linkwarden +- **URL**: https://links.fig.systems +- **Purpose**: Bookmark manager +- **Why**: Save and organize web links +- **Required**: ⬜ No +- **Features**: + - Collaborative bookmarking + - Full-text search + - Screenshots and PDFs + - Tags and collections + - Browser extensions + +### Vikunja +- **URL**: https://tasks.fig.systems +- **Purpose**: Task management (Todoist alternative) +- **Why**: Track tasks and projects +- **Required**: ⬜ No +- **Features**: + - Kanban boards + - Lists and sub-tasks + - Due dates and reminders + - Collaboration + - CalDAV support + +### FreshRSS +- **URL**: https://rss.fig.systems +- **Purpose**: RSS/Atom feed reader +- **Why**: Aggregate news and blogs +- **Required**: ⬜ No +- **Features**: + - Web-based reader + - Mobile apps via API + - Filtering and search + - Multi-user support + +## Specialized Services + +### LubeLogger +- **URL**: https://garage.fig.systems +- **Purpose**: Vehicle maintenance tracker +- **Why**: Track mileage, maintenance, costs +- **Required**: ⬜ No +- **Features**: + - Service records + - Fuel tracking + - Cost analysis + - Reminder system + - Export data + +### Calibre-web +- **URL**: https://books.fig.systems +- **Purpose**: Ebook library manager +- **Why**: Manage and read ebooks +- **Required**: ⬜ No +- **Features**: + - Web-based ebook reader + - Format conversion + - Metadata management + - Send to Kindle + - OPDS support + +### Booklore +- **URL**: https://booklore.fig.systems +- **Purpose**: Book tracking and reviews +- **Why**: Track reading progress and reviews +- **Required**: ⬜ No +- **Features**: + - Reading lists + - Progress tracking + - Reviews and ratings + - Import from Goodreads + +### RSSHub +- **URL**: https://rsshub.fig.systems +- **Purpose**: RSS feed generator +- **Why**: Generate RSS feeds for sites without them +- **Required**: ⬜ No +- **Features**: + - 1000+ source support + - Custom routes + - Filter and transform feeds + +### MicroBin +- **URL**: https://paste.fig.systems +- **Purpose**: Encrypted pastebin with file upload +- **Why**: Share code snippets and files +- **Required**: ⬜ No +- **Features**: + - Encryption support + - File uploads + - Burn after reading + - Custom expiry + - Password protection + +### File Browser +- **URL**: https://files.fig.systems +- **Purpose**: Web-based file manager +- **Why**: Browse and manage media files +- **Required**: ⬜ No +- **Features**: + - Upload/download files + - Preview images and videos + - Text editor + - File sharing + - User permissions + +## Service Categories + +### Minimum Viable Setup +Just want to get started? Deploy these: +1. Traefik +2. LLDAP +3. Tinyauth +4. Homarr + +### Media Enthusiast Setup +For streaming media: +1. Core services (above) +2. Jellyfin +3. Sonarr +4. Radarr +5. qBittorrent +6. Jellyseerr + +### Complete Homelab +Everything: +1. Core services +2. All media services +3. All productivity services +4. Backrest for backups + +## Resource Requirements + +### Light (2 Core, 4GB RAM) +- Core services +- Homarr +- 2-3 utility services + +### Medium (4 Core, 8GB RAM) +- Core services +- Media services (without transcoding) +- Most utility services + +### Heavy (6+ Core, 16GB+ RAM) +- All services +- GPU transcoding +- Multiple concurrent users + +## Quick Deploy Checklist + +**Before deploying a service:** +- ✅ Core infrastructure is running +- ✅ `.env` file configured with secrets +- ✅ DNS record created +- ✅ Understand what the service does +- ✅ Know how to configure it + +**After deploying:** +- ✅ Check container is running: `docker ps` +- ✅ Check logs: `docker compose logs` +- ✅ Access web UI and complete setup +- ✅ Test SSO if applicable +- ✅ Add to Homarr dashboard + +## Service Dependencies + +``` +Traefik (required for all) +├── LLDAP +│ └── Tinyauth +│ └── All SSO-protected services +├── Jellyfin +│ └── Jellyseerr +│ ├── Sonarr +│ └── Radarr +│ ├── SABnzbd +│ └── qBittorrent +├── Immich +│ └── Backrest (for backups) +└── All other services +``` + +## When to Use Each Service + +### Use Jellyfin if: +- You have a movie/TV collection +- Want to stream from anywhere +- Have family/friends who want access +- Want apps on all devices + +### Use Immich if: +- You want Google Photos alternative +- Have lots of photos to manage +- Want ML features (face recognition) +- Have mobile devices + +### Use Sonarr/Radarr if: +- You watch a lot of TV/movies +- Want automatic downloads +- Don't want to manually search +- Want quality control + +### Use Backrest if: +- You care about your data (you should!) +- Want encrypted cloud backups +- Have important photos/documents +- Want easy restore process + +### Use Linkwarden if: +- You save lots of bookmarks +- Want full-text search +- Share links with team +- Want offline archives + +### Use Vikunja if: +- You need task management +- Work with teams +- Want Kanban boards +- Need CalDAV for calendar integration + +## Next Steps + +1. Review which services you actually need +2. Start with core + 2-3 services +3. Deploy and configure each fully +4. Add more services gradually +5. Monitor resource usage + +--- + +**Remember**: You don't need all services. Start small and add what you actually use! diff --git a/docs/troubleshooting/common-issues.md b/docs/troubleshooting/common-issues.md new file mode 100644 index 0000000..d056b7a --- /dev/null +++ b/docs/troubleshooting/common-issues.md @@ -0,0 +1,707 @@ +# Common Issues and Solutions + +This guide covers the most common problems you might encounter and how to fix them. + +## Table of Contents +- [Service Won't Start](#service-wont-start) +- [SSL/TLS Certificate Errors](#ssltls-certificate-errors) +- [SSO Authentication Issues](#sso-authentication-issues) +- [Access Issues](#access-issues) +- [Performance Problems](#performance-problems) +- [Database Errors](#database-errors) +- [Network Issues](#network-issues) +- [GPU Problems](#gpu-problems) + +## Service Won't Start + +### Symptom +Container exits immediately or shows "Exited (1)" status. + +### Diagnosis +```bash +cd ~/homelab/compose/path/to/service + +# Check container status +docker compose ps + +# View logs +docker compose logs + +# Check for specific errors +docker compose logs | grep -i error +``` + +### Common Causes and Fixes + +#### 1. Environment Variables Not Set + +**Error in logs:** +``` +Error: POSTGRES_PASSWORD is not set +Error: required environment variable 'XXX' is missing +``` + +**Fix:** +```bash +# Check .env file exists +ls -la .env + +# Check for changeme_ values +grep "changeme_" .env + +# Update with proper secrets (see secrets guide) +nano .env + +# Restart +docker compose up -d +``` + +#### 2. Port Already in Use + +**Error in logs:** +``` +Error: bind: address already in use +Error: failed to bind to port 80: address already in use +``` + +**Fix:** +```bash +# Find what's using the port +sudo netstat -tulpn | grep :80 +sudo netstat -tulpn | grep :443 + +# Stop conflicting service +sudo systemctl stop apache2 # Example +sudo systemctl stop nginx # Example + +# Or change port in compose.yaml +``` + +#### 3. Network Not Created + +**Error in logs:** +``` +network homelab declared as external, but could not be found +``` + +**Fix:** +```bash +# Create network +docker network create homelab + +# Verify +docker network ls | grep homelab + +# Restart service +docker compose up -d +``` + +#### 4. Volume Permission Issues + +**Error in logs:** +``` +Permission denied: '/config' +mkdir: cannot create directory '/data': Permission denied +``` + +**Fix:** +```bash +# Check directory ownership +ls -la ./config ./data + +# Fix ownership (replace 1000:1000 with your UID:GID) +sudo chown -R 1000:1000 ./config ./data + +# Restart +docker compose up -d +``` + +#### 5. Dependency Not Running + +**Error in logs:** +``` +Failed to connect to database +Connection refused: postgres:5432 +``` + +**Fix:** +```bash +# Start dependency first +cd ~/homelab/compose/path/to/dependency +docker compose up -d + +# Wait for it to be healthy +docker compose logs -f + +# Then start the service +cd ~/homelab/compose/path/to/service +docker compose up -d +``` + +## SSL/TLS Certificate Errors + +### Symptom +Browser shows "Your connection is not private" or "NET::ERR_CERT_AUTHORITY_INVALID" + +### Diagnosis +```bash +# Check Traefik logs +docker logs traefik | grep -i certificate +docker logs traefik | grep -i letsencrypt +docker logs traefik | grep -i error + +# Test certificate +echo | openssl s_client -servername home.fig.systems -connect home.fig.systems:443 2>/dev/null | openssl x509 -noout -dates +``` + +### Common Causes and Fixes + +#### 1. DNS Not Configured + +**Fix:** +```bash +# Test DNS resolution +dig home.fig.systems +short + +# Should return your server's IP +# If not, configure DNS A records: +# *.fig.systems -> YOUR_SERVER_IP +``` + +#### 2. Port 80 Not Accessible + +Let's Encrypt needs port 80 for HTTP-01 challenge. + +**Fix:** +```bash +# Test from external network +curl -I http://home.fig.systems + +# Check firewall +sudo ufw status +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp + +# Check port forwarding on router +# Ensure ports 80 and 443 are forwarded to server +``` + +#### 3. Rate Limiting + +Let's Encrypt has limits: 5 certificates per domain per week. + +**Fix:** +```bash +# Check Traefik logs for rate limit errors +docker logs traefik | grep -i "rate limit" + +# Wait for rate limit to reset (1 week) +# Or use Let's Encrypt staging environment for testing + +# Enable staging in traefik/compose.yaml: +# - --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory +``` + +#### 4. First Startup - Certificates Not Yet Generated + +**Fix:** +```bash +# Wait 2-5 minutes for certificate generation +docker logs traefik -f + +# Look for: +# "Certificate obtained for domain" +``` + +#### 5. Certificate Expired + +Traefik should auto-renew, but if manual renewal needed: + +**Fix:** +```bash +# Remove old certificates +cd ~/homelab/compose/core/traefik +rm -rf ./acme.json + +# Restart Traefik +docker compose restart + +# Wait for new certificates +docker logs traefik -f +``` + +## SSO Authentication Issues + +### Symptom +- Can't login to SSO-protected services +- Redirected to auth page but login fails +- "Invalid credentials" error + +### Diagnosis +```bash +# Check LLDAP is running +docker ps | grep lldap + +# Check Tinyauth is running +docker ps | grep tinyauth + +# View logs +docker logs lldap +docker logs tinyauth +``` + +### Common Causes and Fixes + +#### 1. Password Mismatch + +LDAP_BIND_PASSWORD must match LLDAP_LDAP_USER_PASS. + +**Fix:** +```bash +# Check both passwords +grep LLDAP_LDAP_USER_PASS ~/homelab/compose/core/lldap/.env +grep LDAP_BIND_PASSWORD ~/homelab/compose/core/tinyauth/.env + +# They must be EXACTLY the same! + +# If different, update tinyauth/.env +cd ~/homelab/compose/core/tinyauth +nano .env +# Set LDAP_BIND_PASSWORD to match LLDAP_LDAP_USER_PASS + +# Restart Tinyauth +docker compose restart +``` + +#### 2. User Doesn't Exist in LLDAP + +**Fix:** +```bash +# Access LLDAP web UI +# Go to: https://lldap.fig.systems + +# Login with admin credentials +# Username: admin +# Password: + +# Create user: +# - Click "Create user" +# - Set username, email, password +# - Add to "lldap_admin" group + +# Try logging in again +``` + +#### 3. LLDAP or Tinyauth Not Running + +**Fix:** +```bash +# Start LLDAP +cd ~/homelab/compose/core/lldap +docker compose up -d + +# Wait for it to be ready +docker compose logs -f + +# Start Tinyauth +cd ~/homelab/compose/core/tinyauth +docker compose up -d +docker compose logs -f +``` + +#### 4. Network Issue Between Tinyauth and LLDAP + +**Fix:** +```bash +# Test connection +docker exec tinyauth nc -zv lldap 3890 + +# Should show: Connection to lldap 3890 port [tcp/*] succeeded! + +# If not, check both are on homelab network +docker network inspect homelab +``` + +## Access Issues + +### Symptom +- Can't access service from browser +- Connection timeout +- "This site can't be reached" + +### Diagnosis +```bash +# Test from server +curl -I https://home.fig.systems + +# Test DNS +dig home.fig.systems +short + +# Check container is running +docker ps | grep servicename + +# Check Traefik routing +docker logs traefik | grep servicename +``` + +### Common Causes and Fixes + +#### 1. Service Not Running + +**Fix:** +```bash +cd ~/homelab/compose/path/to/service +docker compose up -d +docker compose logs -f +``` + +#### 2. Traefik Not Running + +**Fix:** +```bash +cd ~/homelab/compose/core/traefik +docker compose up -d +docker compose logs -f +``` + +#### 3. DNS Not Resolving + +**Fix:** +```bash +# Check DNS +dig service.fig.systems +short + +# Should return your server IP +# If not, add/update DNS A record +``` + +#### 4. Firewall Blocking + +**Fix:** +```bash +# Check firewall +sudo ufw status + +# Allow if needed +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +``` + +#### 5. Wrong Traefik Labels + +**Fix:** +```bash +# Check compose.yaml has correct labels +cd ~/homelab/compose/path/to/service +cat compose.yaml | grep -A 10 "labels:" + +# Should have: +# traefik.enable: true +# traefik.http.routers.servicename.rule: Host(`service.fig.systems`) +# etc. +``` + +## Performance Problems + +### Symptom +- Services running slowly +- High CPU/RAM usage +- System unresponsive + +### Diagnosis +```bash +# Overall system +htop + +# Docker resources +docker stats + +# Disk usage +df -h +docker system df +``` + +### Common Causes and Fixes + +#### 1. Insufficient RAM + +**Fix:** +```bash +# Check RAM usage +free -h + +# If low, either: +# 1. Add more RAM +# 2. Stop unused services +# 3. Add resource limits to compose files + +# Example resource limit: +deploy: + resources: + limits: + memory: 2G + reservations: + memory: 1G +``` + +#### 2. Disk Full + +**Fix:** +```bash +# Check disk usage +df -h + +# Clean Docker +docker system prune -a + +# Remove old logs +sudo journalctl --vacuum-time=7d + +# Check media folder +du -sh /media/* +``` + +#### 3. Too Many Services Running + +**Fix:** +```bash +# Stop unused services +cd ~/homelab/compose/services/unused-service +docker compose down + +# Or deploy only what you need +``` + +#### 4. Database Not Optimized + +**Fix:** +```bash +# For postgres services, add to .env: +POSTGRES_INITDB_ARGS=--data-checksums + +# Increase shared buffers (if enough RAM): +# Edit compose.yaml, add to postgres: +command: postgres -c shared_buffers=256MB -c max_connections=200 +``` + +## Database Errors + +### Symptom +- "Connection refused" to database +- "Authentication failed for user" +- "Database does not exist" + +### Diagnosis +```bash +# Check database container +docker ps | grep postgres + +# View database logs +docker logs + +# Test connection from app +docker exec nc -zv 5432 +``` + +### Common Causes and Fixes + +#### 1. Password Mismatch + +**Fix:** +```bash +# Check passwords match in .env +cat .env | grep PASSWORD + +# For example, in Vikunja: +# VIKUNJA_DATABASE_PASSWORD and POSTGRES_PASSWORD must match! + +# Update if needed +nano .env +docker compose down +docker compose up -d +``` + +#### 2. Database Not Initialized + +**Fix:** +```bash +# Remove database and reinitialize +docker compose down +rm -rf ./db/ # CAREFUL: This deletes all data! +docker compose up -d +``` + +#### 3. Database Still Starting + +**Fix:** +```bash +# Wait for database to be ready +docker logs -f + +# Look for "database system is ready to accept connections" + +# Then restart app +docker compose restart +``` + +## Network Issues + +### Symptom +- Containers can't communicate +- "Connection refused" between services + +### Diagnosis +```bash +# Inspect network +docker network inspect homelab + +# Test connectivity +docker exec container1 ping container2 +docker exec container1 nc -zv container2 PORT +``` + +### Common Causes and Fixes + +#### 1. Containers Not on Same Network + +**Fix:** +```bash +# Check compose.yaml has networks section +networks: + homelab: + external: true + +# Ensure service is using the network +services: + servicename: + networks: + - homelab +``` + +#### 2. Network Doesn't Exist + +**Fix:** +```bash +docker network create homelab +docker compose up -d +``` + +#### 3. DNS Resolution Between Containers + +**Fix:** +```bash +# Use container name, not localhost +# Wrong: http://localhost:5432 +# Right: http://postgres:5432 + +# Or use service name from compose.yaml +``` + +## GPU Problems + +### Symptom +- "No hardware acceleration available" +- GPU not detected in container +- "Failed to open GPU" + +### Diagnosis +```bash +# Check GPU on host +nvidia-smi + +# Check GPU in container +docker exec jellyfin nvidia-smi + +# Check Docker GPU runtime +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi +``` + +### Common Causes and Fixes + +#### 1. NVIDIA Container Toolkit Not Installed + +**Fix:** +```bash +# Install toolkit +sudo apt install nvidia-container-toolkit + +# Configure runtime +sudo nvidia-ctk runtime configure --runtime=docker + +# Restart Docker +sudo systemctl restart docker +``` + +#### 2. Runtime Not Specified in Compose + +**Fix:** +```bash +# Edit compose.yaml +nano compose.yaml + +# Uncomment: +runtime: nvidia +deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + +# Restart +docker compose up -d +``` + +#### 3. GPU Already in Use + +**Fix:** +```bash +# Check processes using GPU +nvidia-smi + +# Kill process if needed +sudo kill + +# Restart service +docker compose restart +``` + +#### 4. GPU Not Passed Through to VM (Proxmox) + +**Fix:** +```bash +# From Proxmox host, check GPU passthrough +lspci | grep -i nvidia + +# From VM, check GPU visible +lspci | grep -i nvidia + +# If not visible, reconfigure passthrough (see GPU guide) +``` + +## Getting More Help + +If your issue isn't listed here: + +1. **Check service-specific logs**: + ```bash + cd ~/homelab/compose/path/to/service + docker compose logs --tail=200 + ``` + +2. **Search container logs for errors**: + ```bash + docker compose logs | grep -i error + docker compose logs | grep -i fail + ``` + +3. **Check FAQ**: See [FAQ](./faq.md) + +4. **Debugging Guide**: See [Debugging Guide](./debugging.md) + +5. **Service Documentation**: Check service's official documentation + +--- + +**Most issues can be solved by checking logs and environment variables!** diff --git a/docs/troubleshooting/faq.md b/docs/troubleshooting/faq.md new file mode 100644 index 0000000..b951b87 --- /dev/null +++ b/docs/troubleshooting/faq.md @@ -0,0 +1,484 @@ +# Frequently Asked Questions (FAQ) + +Common questions and answers about the homelab setup. + +## General Questions + +### Q: What is this homelab setup? + +**A:** This is a GitOps-based infrastructure for self-hosting services using Docker Compose. It includes: +- 20+ pre-configured services (media, productivity, utilities) +- Automatic SSL/TLS with Let's Encrypt via Traefik +- Single Sign-On (SSO) with LLDAP and Tinyauth +- Automated backups with Backrest +- Service discovery dashboard with Homarr + +### Q: What are the minimum hardware requirements? + +**A:** +- **CPU**: 2+ cores (4+ recommended) +- **RAM**: 8GB minimum (16GB+ recommended) +- **Storage**: 100GB for containers, additional space for media +- **Network**: Static IP recommended, ports 80 and 443 accessible +- **GPU** (Optional): NVIDIA GPU for hardware transcoding + +### Q: Do I need my own domain name? + +**A:** Yes, you need at least one domain (two configured by default: `fig.systems` and `edfig.dev`). You can: +- Register a domain from any registrar +- Update all compose files to use your domain +- Configure wildcard DNS (`*.yourdomain.com`) + +### Q: Can I run this on a Raspberry Pi? + +**A:** Partially. ARM64 architecture is supported by most services, but: +- Performance will be limited +- No GPU acceleration available +- Some services may not have ARM images +- 8GB RAM minimum recommended (Pi 4 or Pi 5) + +### Q: How much does this cost to run? + +**A:** +- **Server**: $0 (if using existing hardware) or $5-20/month (VPS) +- **Domain**: $10-15/year +- **Backblaze B2**: ~$0.60/month for 100GB photos +- **Electricity**: Varies by hardware and location +- **Total**: $15-30/year minimum + +## Setup Questions + +### Q: Why won't my services start? + +**A:** Common causes: +1. **Environment variables not set**: Check for `changeme_*` in `.env` files +2. **Ports already in use**: Check if 80/443 are available +3. **Network not created**: Run `docker network create homelab` +4. **DNS not configured**: Services need valid DNS records +5. **Insufficient resources**: Check RAM and disk space + +**Debug:** +```bash +cd compose/path/to/service +docker compose logs +docker compose ps +``` + +### Q: How do I know if everything is working? + +**A:** Check these indicators: +1. **All containers running**: `docker ps` shows all services +2. **SSL certificates valid**: Visit https://home.fig.systems (no cert errors) +3. **Dashboard accessible**: Homarr shows all services +4. **SSO working**: Can login to protected services +5. **No errors in logs**: `docker compose logs` shows no critical errors + +### Q: What order should I deploy services? + +**A:** Follow this order: +1. **Core**: Traefik → LLDAP → Tinyauth +2. **Configure**: Create LLDAP users +3. **Media**: Jellyfin → Immich → Jellyseerr → Sonarr → Radarr → Downloaders +4. **Utility**: Homarr → Backrest → Everything else + +### Q: Do I need to configure all 20 services? + +**A:** No! Deploy only what you need: +- **Core** (required): Traefik, LLDAP, Tinyauth +- **Media** (optional): Jellyfin, Immich, Sonarr, Radarr +- **Utility** (pick what you want): Homarr, Backrest, Linkwarden, Vikunja, etc. + +## Configuration Questions + +### Q: What secrets do I need to change? + +**A:** Search for `changeme_*` in all `.env` files: +```bash +grep -r "changeme_" compose/ +``` + +Critical secrets: +- **LLDAP_LDAP_USER_PASS**: Admin password for LLDAP +- **LLDAP_JWT_SECRET**: 64-character hex string +- **SESSION_SECRET**: 64-character hex string for Tinyauth +- **DB_PASSWORD**: Database passwords (Immich, Vikunja, Linkwarden) +- **NEXTAUTH_SECRET**: NextAuth secret for Linkwarden +- **VIKUNJA_SERVICE_JWTSECRET**: JWT secret for Vikunja + +### Q: How do I generate secure secrets? + +**A:** Use these commands: + +```bash +# 64-character hex (for JWT secrets, session secrets) +openssl rand -hex 32 + +# 32-character password (for databases) +openssl rand -base64 32 | tr -d /=+ | cut -c1-32 + +# 32-character hex (for API keys) +openssl rand -hex 16 +``` + +See [Secrets Management Guide](../guides/secrets-management.md) for details. + +### Q: Can I change the domains from fig.systems to my own? + +**A:** Yes! You need to: +1. Find and replace in all `compose.yaml` files: + ```bash + find compose -name "compose.yaml" -exec sed -i 's/fig\.systems/yourdomain.com/g' {} \; + find compose -name "compose.yaml" -exec sed -i 's/edfig\.dev/yourotherdomain.com/g' {} \; + ``` +2. Update DNS records to point to your server +3. Update `.env` files with new URLs (e.g., `NEXTAUTH_URL`, `VIKUNJA_SERVICE_PUBLICURL`) + +### Q: Do all passwords need to match? + +**A:** No, but some must match: +- **LLDAP_LDAP_USER_PASS** must equal **LDAP_BIND_PASSWORD** (in tinyauth) +- **VIKUNJA_DATABASE_PASSWORD** must equal **POSTGRES_PASSWORD** (in vikunja) +- **Linkwarden POSTGRES_PASSWORD** is used in DATABASE_URL + +All other passwords should be unique! + +## SSL/TLS Questions + +### Q: Why am I getting SSL certificate errors? + +**A:** Common causes: +1. **DNS not configured**: Ensure domains point to your server +2. **Ports not accessible**: Let's Encrypt needs port 80 for HTTP challenge +3. **Rate limiting**: Let's Encrypt has rate limits (5 certs per domain/week) +4. **First startup**: Certs take a few minutes to generate + +**Debug:** +```bash +docker logs traefik | grep -i error +docker logs traefik | grep -i certificate +``` + +### Q: How long do SSL certificates last? + +**A:** Let's Encrypt certificates: +- Valid for 90 days +- Traefik auto-renews at 30 days before expiration +- Renewals happen automatically in the background + +### Q: Can I use my own SSL certificates? + +**A:** Yes, but it requires modifying Traefik configuration. The default Let's Encrypt setup is recommended. + +## SSO Questions + +### Q: What is SSO and do I need it? + +**A:** SSO (Single Sign-On) lets you log in once and access all services: +- **LLDAP**: Stores users and passwords +- **Tinyauth**: Authenticates users before allowing service access +- **Benefits**: One login for all services, centralized user management +- **Optional**: Some services can work without SSO (have their own auth) + +### Q: Why can't I log into SSO-protected services? + +**A:** Check: +1. **LLDAP is running**: `docker ps | grep lldap` +2. **Tinyauth is running**: `docker ps | grep tinyauth` +3. **User exists in LLDAP**: Go to https://lldap.fig.systems and verify +4. **Passwords match**: LDAP_BIND_PASSWORD = LLDAP_LDAP_USER_PASS +5. **User in correct group**: Check user is in `lldap_admin` group + +**Debug:** +```bash +cd compose/core/tinyauth +docker compose logs -f +``` + +### Q: Can I disable SSO for a service? + +**A:** Yes! Comment out the middleware line in compose.yaml: +```yaml +# traefik.http.routers.servicename.middlewares: tinyauth +``` + +Then restart the service: +```bash +docker compose up -d +``` + +### Q: How do I reset my LLDAP admin password? + +**A:** +1. Stop LLDAP: `cd compose/core/lldap && docker compose down` +2. Update `LLDAP_LDAP_USER_PASS` in `.env` +3. Remove the database: `rm -rf data/` +4. Restart: `docker compose up -d` +5. Recreate users in LLDAP UI + +⚠️ **Warning**: This deletes all users! + +## Service-Specific Questions + +### Q: Jellyfin shows "Playback Error" - what's wrong? + +**A:** Common causes: +1. **Media file corrupt**: Test file with VLC +2. **Permissions**: Check file ownership (`ls -la /media/movies`) +3. **Codec not supported**: Enable transcoding or use different file +4. **GPU not configured**: If using GPU, verify NVIDIA Container Toolkit + +### Q: Immich won't upload photos - why? + +**A:** Check: +1. **Database connected**: `docker logs immich_postgres` +2. **Upload directory writable**: Check permissions on `./upload` +3. **Disk space**: `df -h` +4. **File size limits**: Check browser console for errors + +### Q: Why isn't Homarr showing my services? + +**A:** Homarr needs: +1. **Docker socket access**: Volume mount `/var/run/docker.sock` +2. **Labels on services**: Each service needs `homarr.name` label +3. **Same network**: Homarr must be on `homelab` network +4. **Time to detect**: Refresh page or wait 30 seconds + +### Q: Backrest shows "Repository not initialized" - what do I do? + +**A:** +1. Go to https://backup.fig.systems +2. Click "Add Repository" +3. Configure Backblaze B2 settings +4. Click "Initialize Repository" + +See [Backup Guide](../services/backup.md) for detailed setup. + +### Q: Sonarr/Radarr can't find anything - help! + +**A:** +1. **Add indexers**: Settings → Indexers → Add indexer +2. **Configure download client**: Settings → Download Clients → Add +3. **Set root folder**: Series/Movies → Add Root Folder → `/media/tv` or `/media/movies` +4. **Test indexers**: Settings → Indexers → Test + +### Q: qBittorrent shows "Unauthorized" - what's the password? + +**A:** Default credentials: +- Username: `admin` +- Password: `adminadmin` + +⚠️ **Change this immediately** in qBittorrent settings! + +## Media Questions + +### Q: Where should I put my media files? + +**A:** Use the /media directory structure: +- Movies: `/media/movies/Movie Name (Year)/movie.mkv` +- TV: `/media/tv/Show Name/Season 01/episode.mkv` +- Music: `/media/music/Artist/Album/song.flac` +- Photos: `/media/photos/` (any structure) +- Books: `/media/books/` (any structure) + +### Q: How do I add more media storage? + +**A:** +1. Mount additional drive to `/media2` (or any path) +2. Update compose files to include new volume: + ```yaml + volumes: + - /media:/media:ro + - /media2:/media2:ro # Add this + ``` +3. Restart service: `docker compose up -d` +4. Add new library in service UI + +### Q: Can Sonarr/Radarr automatically download shows/movies? + +**A:** Yes! That's their purpose: +1. Add indexers (for searching) +2. Add download client (SABnzbd or qBittorrent) +3. Add a series/movie +4. Enable monitoring +5. Sonarr/Radarr will search, download, and organize automatically + +### Q: How do I enable hardware transcoding in Jellyfin? + +**A:** See [GPU Setup Guide](../guides/gpu-setup.md) for full instructions. + +Quick steps: +1. Install NVIDIA Container Toolkit on host +2. Uncomment GPU sections in `jellyfin/compose.yaml` +3. Restart Jellyfin +4. Enable in Jellyfin: Dashboard → Playback → Hardware Acceleration → NVIDIA NVENC + +## Network Questions + +### Q: Can I access services only from my local network? + +**A:** Yes, don't expose ports 80/443 to internet: +1. Use firewall to block external access +2. Use local DNS (Pi-hole, AdGuard Home) +3. Point domains to local IP (192.168.x.x) +4. Use self-signed certs or no HTTPS + +**Or** use Traefik's IP allowlist middleware. + +### Q: Can I use a VPN with these services? + +**A:** Yes, options: +1. **VPN on download clients**: Add VPN container for qBittorrent/SABnzbd +2. **VPN to access homelab**: Use WireGuard/Tailscale to access from anywhere +3. **VPN for entire server**: All traffic goes through VPN (not recommended) + +### Q: Why can't I access services from outside my network? + +**A:** Check: +1. **Port forwarding**: Ports 80 and 443 forwarded to homelab server +2. **Firewall**: Allow ports 80/443 through firewall +3. **DNS**: Domains point to your public IP +4. **ISP**: Some ISPs block ports 80/443 (use CloudFlare Tunnel) + +## Backup Questions + +### Q: What should I backup? + +**A:** Priority order: +1. **High**: Immich photos (`compose/media/frontend/immich/upload`) +2. **High**: Configuration files (all `.env` files, compose files) +3. **Medium**: Service data directories (`./config`, `./data` in each service) +4. **Low**: Media files (usually have source elsewhere) + +### Q: How do I restore from backup? + +**A:** See [Backup Operations Guide](../operations/backups.md). + +Quick steps: +1. Install fresh homelab setup +2. Restore `.env` files and configs +3. Use Backrest to restore data +4. Restart services + +### Q: Does Backrest backup everything automatically? + +**A:** Only what you configure: +- Default: Immich photos and homelab configs +- Add more paths in `backrest/compose.yaml` volumes +- Create backup plans in Backrest UI for each path + +## Performance Questions + +### Q: Services are running slow - how do I optimize? + +**A:** +1. **Check resources**: `docker stats` - are you out of RAM/CPU? +2. **Reduce services**: Stop unused services +3. **Use SSD**: Move Docker to SSD storage +4. **Add RAM**: Minimum 8GB, 16GB+ recommended +5. **Enable GPU**: For Jellyfin and Immich + +### Q: Docker is using too much disk space - what do I do? + +**A:** +```bash +# Check Docker disk usage +docker system df + +# Clean up +docker system prune -a --volumes + +# WARNING: This removes all stopped containers and unused volumes! +``` + +Better approach - clean specific services: +```bash +cd compose/path/to/service +docker compose down +docker volume rm $(docker volume ls -q | grep servicename) +docker compose up -d +``` + +### Q: How do I limit RAM/CPU for a service? + +**A:** Add resource limits to compose.yaml: +```yaml +services: + servicename: + deploy: + resources: + limits: + cpus: '2.0' + memory: 4G + reservations: + memory: 2G +``` + +## Update Questions + +### Q: How do I update a service? + +**A:** +```bash +cd compose/path/to/service +docker compose pull +docker compose up -d +``` + +See [Updates Guide](../operations/updates.md) for details. + +### Q: How often should I update? + +**A:** +- **Security updates**: Weekly +- **Feature updates**: Monthly +- **Major versions**: When stable + +Use Watchtower for automatic updates (optional). + +### Q: Will updating break my configuration? + +**A:** Usually no, but: +- Always backup before major updates +- Check release notes for breaking changes +- Test in staging environment if critical + +## Security Questions + +### Q: Is this setup secure? + +**A:** Reasonably secure with best practices: +- ✅ SSL/TLS encryption +- ✅ SSO authentication +- ✅ Secrets in environment files +- ⚠️ Some services exposed to internet +- ⚠️ Depends on keeping services updated + +See [Security Guide](../guides/security.md) for hardening. + +### Q: Should I expose my homelab to the internet? + +**A:** Depends on your risk tolerance: +- **Yes**: Convenient access from anywhere, Let's Encrypt works +- **No**: More secure, requires VPN for external access +- **Hybrid**: Expose only essential services, use VPN for sensitive ones + +### Q: What if someone gets my LLDAP password? + +**A:** They can access all SSO-protected services. Mitigations: +- Use strong, unique passwords +- Enable 2FA where supported +- Review LLDAP access logs +- Use fail2ban to block brute force +- Consider VPN-only access + +## Troubleshooting + +For specific error messages and debugging, see: +- [Common Issues](./common-issues.md) +- [Debugging Guide](./debugging.md) + +Still stuck? Check: +1. Service logs: `docker compose logs` +2. Traefik logs: `docker logs traefik` +3. Container status: `docker ps -a` +4. Network connectivity: `docker network inspect homelab`