# HOPS - Claude Code Project Guide ## Project Overview HOPS (Homelab Orchestration Provisioning Script) is a bash-based tool that deploys homelab infrastructure via Docker Compose. It presents an interactive menu for selecting services, generates a docker-compose.yml and .env, installs Docker if needed, and manages the lifecycle of the deployment. **Target platform**: Linux only (Ubuntu 20.04+, Debian 11+, Linux Mint 20+). macOS and WSL2 are on the future roadmap, not in scope for 1.0.0. ## Install Pipeline (Path A -- canonical) ``` sudo ./hops # Entry point and management menu -> install # Full installation logic (sourced by hops) -> services # Service definitions and compose generators (sourced by install) -> uninstall # Removal logic (standalone) ``` All other top-level scripts and `lib/privileges.sh` were Path B artifacts and have been deleted. Do not recreate them. ## File Map | File | Purpose | |------|---------| | `hops` | Entry point, management menu, update logic | | `install` | Full install flow: Docker setup, service selection, compose generation, firewall | | `uninstall` | Reversal of install: stops containers, removes dirs, optionally purges Docker | | `services` | Single canonical service catalog: compose generators, port map, image refs | | `lib/common.sh` | Logging, UI helpers, shared utilities -- source this, don't duplicate | | `lib/system.sh` | OS detection, Docker install, system requirement checks | | `lib/docker.sh` | Docker service management, status checks, network helpers | | `lib/security.sh` | Password generation, validation, firewall, security audit | | `lib/validation.sh` | Input sanitisation and validation functions | | `lib/secrets.sh` | .env encryption at rest (being fixed and wired in -- see TODO M4/A4/S1) | ## Key Architectural Decisions - **One service catalog**: `services` is the single source of truth for images, ports, and compose definitions. `lib/docker.sh` has a secondary map that must be kept in sync until reconciled (TODO A2). - **Latest image tags**: all service images use `latest`, not pinned versions. - **Secrets**: `lib/secrets.sh` will encrypt the `.env` file at rest using gpg. Currently being fixed -- the old AES-GCM implementation was broken. - **No duplicate functions**: consolidate into `lib/common.sh`. Do not define `log`, `error_exit`, `warning`, `success`, or `info` in any other file. ## Coding Conventions - Bash only. No Python, no Node, no external interpreters required at runtime. - ASCII only -- no Unicode, no emojis in scripts or output strings. - No comments explaining what the code does. Only add a comment when the WHY is non-obvious (hidden constraint, workaround, subtle invariant). - Error handling: use `set -e` with care. Arithmetic increments must use `x=$((x + 1))` not `((x++))` -- the latter aborts under `set -e` when the pre-increment value is 0. - Temp files: always use `mktemp`, never `/tmp/name_$$`. - User home resolution: use `getent passwd "$SUDO_USER" | cut -d: -f6`, never `eval echo "~$SUDO_USER"`. - Command arrays: build commands as bash arrays, not strings, to avoid word-splitting on unusual usernames or paths. ## Running / Testing There is no test suite. Validate with: ```bash bash -n hops install uninstall services # syntax check bash -n lib/*.sh ``` Full integration testing requires a Linux VM. The scripts must be run as root or via sudo on a supported distro. ## Dynamic Information The following docs change frequently -- check them rather than this file: - **TODO.md** -- prioritised bug list, cleanup tasks, and feature backlog - **CHANGELOG.md** -- version history and unreleased changes - **SERVICES.md** -- supported service list with ports and upstream links