# Homelab Ansible — Ubuntu 24.04 (SER5 PRO) Bootstraps the headless mini PC for **arr-stack + Ternary-Bonsai (Vulkan)**. | Item | Value | |------|--------| | Host | `192.168.8.123:22` | | User | `tim` | | SSH key | `~/.ssh/id_ed25519` | | Stack | `/opt/stack` | | Media | `/storage` | ## What it installs 1. **common** — apt upgrade, essentials (`curl` `wget` `nano` `build-essential` `net-tools`), [Microsoft Edit](https://github.com/microsoft/edit), tools, unattended-upgrades, fail2ban 2. **docker** — Docker CE + Compose plugin, enabled on boot, user in `docker` 3. **amd_vulkan** — Mesa Vulkan, VA-API, firmware, `video`/`render` groups, udev rules 4. **firewall** — UFW: deny inbound, allow stack ports **from LAN only** (`192.168.8.0/24`) 5. **stack** — `/opt/stack` + `/storage`, rsync project, `.env`, Vulkan compose override, **`arr-stack.service`** so compose comes up after reboot (`restart: unless-stopped` on every service) ## Prerequisites (control machine) ```bash # Debian/Ubuntu control node sudo apt install -y ansible git rsync cd /path/to/arr-stack/ansible ansible-galaxy collection install -r requirements.yml ``` SSH must already work: ```bash ssh -i ~/.ssh/id_ed25519 tim@192.168.8.123 ``` On the **server**, either enable passwordless sudo (recommended for automation): ```bash echo 'tim ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/tim sudo chmod 440 /etc/sudoers.d/tim ``` …or pass the sudo password each run with `-K` / `--ask-become-pass`. ## Run ```bash cd ansible # Full bootstrap (prompt for sudo if not NOPASSWD) ansible-playbook site.yml -K # Or limit / tags ansible-playbook site.yml -K --tags docker,amd,firewall ansible-playbook site.yml -K --tags stack,deploy ansible-playbook site.yml -K --check # dry-run (partial) ``` First connection may prompt for host key (`accept-new` is set in `ansible.cfg`). ## After the playbook On the **server** (or via SSH): ```bash ssh tim@192.168.8.123 # new shell so docker/video/render groups apply cd /opt/stack # WireGuard (if not copied): edit wireguard/wg0.conf # Model (~7.2G): ./scripts/download-bonsai-model.sh # Vulkan image + stack docker compose build bonsai docker compose up -d docker compose ps ``` Verify GPU / tools inside the host: ```bash vulkaninfo --summary ls -l /dev/dri groups # should include docker, video, render edit --version # Microsoft terminal editor curl --version && wget --version && nano --version ``` Survive reboots: ```bash systemctl is-enabled docker arr-stack systemctl status arr-stack # containers use restart: unless-stopped; arr-stack.service runs compose up -d on boot ``` ## Layout on the server ``` /opt/stack/ # compose, config, models, workspace, wireguard docker-compose.yml docker-compose.override.yml # /dev/dri for bonsai + jellyfin .env config/ models/bonsai/ workspace/ wireguard/wg0.conf /storage/ # 1TB media disk media/{movies,tv,music} torrents/{movies,tv,music} ``` `.env` points `DATA_DIR=/storage` and `CONFIG_DIR=/opt/stack/config`. ## Variables Edit `group_vars/all.yml` (or host_vars) for: - `lan_subnet`, `timezone` - `bonsai_backend` / `bonsai_ngl` (default `vulkan` / `99`) - `ufw_allow_ssh_from_anywhere` (default `false` — SSH only from LAN) - `deploy_stack_files` — set `false` to skip rsync ## Security notes - Do not commit `wireguard/wg0.conf` or production `.env`. - UFW allows service ports only from `lan_subnet`. - Fail2ban protects SSH. - Re-login after first run so group membership (`docker`, `render`) is active.