From 99548fb86ee3dcc7c3e971740979f68ba93f470f Mon Sep 17 00:00:00 2001 From: herbygitea Date: Wed, 22 Apr 2026 15:00:22 +0000 Subject: [PATCH] Create herbys-dev-setup.md via n8n --- Tech/Projects/herbys-dev-setup.md | 240 ++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 Tech/Projects/herbys-dev-setup.md diff --git a/Tech/Projects/herbys-dev-setup.md b/Tech/Projects/herbys-dev-setup.md new file mode 100644 index 0000000..f84f024 --- /dev/null +++ b/Tech/Projects/herbys-dev-setup.md @@ -0,0 +1,240 @@ +--- +project: herbys-dev-setup +type: project-plan +status: active +path: Tech/Projects +tags: + - homelab + - proxmox + - ansible + - dev-environment + - backups + - tailscale +created: 2026-04-22 +updated: 2026-04-22 +--- +## herbys-dev — Primary Dev Environment + +Promote `us-test-authy` (VMID 100 on PVE, ZFS pool `vmstore`) from test VM +to the primary development environment. Rename to `herbys-dev`, harden it, +establish real backups, and codify the entire config as an idempotent +Ansible playbook in a new repo. + +The `ladybug` name stays with the Claude Desktop + Dispatch instance +running on the host — not the host itself. + +### Why + +The Manjaro tower pulls ~1500W when active. VM on PVE is accessible +anywhere via Tailscale, persistent across sessions, and cheap to run 24/7. +Keeping the tower asleep unless GPU work (Stable Diffusion, Ollama, Immich +ML) is actually needed. + +Current state has gaps: VM is named for its original test purpose, no +formal backup strategy beyond PVE snapshots, VNC exposed on LAN with +password-only auth, no config-as-code story. + +### Goals + +- Rename to `herbys-dev` everywhere (hostname, Tailscale, DNS, configs) +- Idempotent Ansible playbook that can rebuild the entire dev env from a +fresh Ubuntu VM +- Nightly file-level backups of entire `/home/herbyadmin` with offsite copy +- Weekly Proxmox VM backups with sensible retention +- Tailscale-only VNC access (no LAN exposure) +- SSH available on LAN + Tailscale +- Lightweight disk/health alerting +- Dotfiles repo created and sourced by the Ansible playbook + +### Scope — what this plan covers + +- Rename + DNS + Tailscale migration +- New Ansible repo with idempotent playbook +- Backup strategy (file-level + VM-level) +- Security hardening (VNC, SSH, unattended upgrades) +- Baseline tooling install +- Dotfiles repo creation +- Lightweight monitoring (disk space alert) + +### Out of scope (future projects) + +- Full Prometheus/Grafana observability +- Migration of other VMs to the same Ansible pattern +- Claude Desktop / Dispatch reconfiguration beyond what the rename requires + +### Decisions made + +- **Host name**: `herbys-dev` +- **Ansible repo**: new, separate from `trucktrav/ansible-drive` +- **Playbook must be idempotent** — safe to re-run anytime +- **Secrets**: Ansible Vault for anything sensitive; no plaintext tokens in +repo +- **File-level backup scope**: entire `/home/herbyadmin` with sensible +excludes (`.venv`, `node_modules`, `.cache`, `__pycache__`, build artifacts) +- **Backup frequency**: file-level nightly; VM-level weekly full + daily +incremental (pending retention window decision) +- **VNC**: Tailscale-bound only, remove LAN exposure +- **SSH**: allowed on LAN + Tailscale +- **Dotfiles**: include in this project, playbook pulls and symlinks from +the repo +- **Shell config**: existing setup to be pulled from current machines — not +creating from scratch + +### Open decisions (answer during implementation) + +- Proxmox backup target: shelved 1TB spinner re-added to PVE, or NAS over +NFS/SMB? +- File-level backup tool: Restic (leaning this way for rclone backend) or +Borg? +- Offsite destination: `tjgdrive` Google Drive remote, or different target? +- Backup retention windows: how many daily / weekly / monthly to keep? +- Rename approach: in-place (change hostname, Tailscale name, update DNS) +vs. fresh VM from snapshot with new name and data migration +- Ansible run mode: push from control node, or pull-mode via `ansible-pull` +cron? +- Baseline tooling list beyond the obvious (uv, Go, Node, git, tmux, +Neovim, Claude Code, ripgrep, fd, bat, jq, htop) — anything else to bake in? +- Disk alert delivery: local cron + email, or ping into existing +notification channel? + +### Tasks + +#### Phase 1: Preparation + +- [ ] Take a pre-work Proxmox snapshot of current VM 100 +- [ ] Document current state of `us-test-authy`: installed packages, +running services, `/home` contents, systemd user units, Claude Code config, +VNC config, OpenClaw state +- [ ] Decide rename approach (in-place vs fresh VM) +- [ ] Decide Proxmox backup target (spinner vs NAS) +- [ ] Decide file-level backup tool (Restic vs Borg) +- [ ] Decide offsite backup destination and retention policy + +#### Phase 2: Ansible repo setup + +- [ ] Create new GitHub repo `trucktrav/herbys-dev-ansible` (or similar) +- [ ] Initialize with inventory, playbook skeleton, roles directory +- [ ] Set up Ansible Vault for secrets +- [ ] Write first idempotent task as baseline (e.g., hostname set) +- [ ] Test run against current VM to verify no destructive behavior + +#### Phase 3: Dotfiles repo + +- [ ] Create new GitHub repo `trucktrav/dotfiles` +- [ ] Pull existing shell config from current setup +- [ ] Add git config, tmux config, Neovim config, SSH config template +- [ ] Document what's in there in a README + +#### Phase 4: Ansible roles + +- [ ] Role: `common` — hostname, timezone, locale, unattended-upgrades +- [ ] Role: `baseline-tools` — uv, Go, Node (via fnm or nvm), git, tmux, +Neovim, ripgrep, fd, bat, jq, htop, Claude Code +- [ ] Role: `dotfiles` — clone and symlink from dotfiles repo +- [ ] Role: `ssh-hardening` — key-only auth, sensible sshd_config +- [ ] Role: `tailscale` — ensure Tailscale running with key expiry disabled +- [ ] Role: `vnc` — XFCE + TigerVNC bound to Tailscale interface only, +systemd user unit for persistence +- [ ] Role: `claude-desktop` — install via patrickjaja apt repo, Dispatch + +Cowork service units, loginctl linger +- [ ] Role: `backups` — install backup tool, configure repo, systemd timer +for nightly runs +- [ ] Role: `monitoring` — disk space check cron, alert delivery +- [ ] Role: `firewall` — minimal ufw config (allow SSH LAN + Tailscale, VNC +Tailscale only) + +#### Phase 5: Backups + +- [ ] Configure Proxmox-level backup job (weekly full + daily incremental, +chosen target) +- [ ] Set up file-level backup tool (Restic or Borg) +- [ ] Test restore path end-to-end: delete a file, restore from backup, +verify integrity +- [ ] Document restore procedure in the Ansible repo README + +#### Phase 6: Rename migration + +- [ ] Take fresh snapshot immediately before rename +- [ ] Change Linux hostname to `herbys-dev` +- [ ] Update Tailscale node name +- [ ] Update Pi-hole local DNS record (if one exists) +- [ ] Update `/etc/hosts` on other machines (`truckslaptop`, `manjaro1`, +`pve`) +- [ ] Update SSH client config on other machines +- [ ] Update any hardcoded references in Claude Code configs, systemd +units, existing project `CLAUDE.md` files +- [ ] Update the `zero-check` skill if it references the old hostname +- [ ] Verify Dispatch still pairs correctly after rename +- [ ] Verify OpenClaw gateway still routes correctly over Tailscale + +#### Phase 7: Hardening + +- [ ] Migrate VNC to Tailscale-only binding +- [ ] Confirm no lingering LAN exposure on port scan +- [ ] Enable unattended-upgrades for security patches +- [ ] Verify SSH key-only auth (no password fallback) +- [ ] Review running services, disable anything unused + +#### Phase 8: Validation + +- [ ] Re-run full Ansible playbook against live VM — confirm zero changes +reported (true idempotency) +- [ ] Simulate fresh-rebuild scenario: clone fresh Ubuntu VM, run playbook +end-to-end, verify identical state +- [ ] Trigger a backup manually and verify offsite copy exists +- [ ] Trigger restore test on a throwaway file +- [ ] Trigger disk alert manually (e.g., create a test file to push past +threshold) and verify delivery + +#### Phase 9: Documentation + +- [ ] Write `MACHINE.md` on herbys-dev listing what's installed, where data +lives, what's backed up +- [ ] Update Obsidian memory / project notes: `us-test-authy` → +`herbys-dev`, role change from test to primary dev +- [ ] Update any references in other project plans +(project-scaffolding-skill plan currently says "Manjaro tower is primary +dev" — needs correction) +- [ ] README in Ansible repo: what the playbook does, how to run it, how to +add a new role + +### Testing strategy + +- Every Ansible role must be safe to run twice in a row with zero changes +on the second run +- Backup + restore must be validated before the old `us-test-authy` +snapshot is deleted +- Rename migration must include rollback plan (revert snapshot) in case +Dispatch, OpenClaw, or Tailscale break + +### Success criteria + +- Playbook runs green against a fresh Ubuntu VM and produces an identical +dev environment +- Backups running nightly with verified restore path +- Zero LAN-exposed services beyond SSH +- Host renamed everywhere it matters +- Dotfiles repo populated and Ansible-managed +- Machine documented + +### References + +- Current VM: `us-test-authy`, VMID 100, ZFS pool `vmstore` +- Existing Ansible pattern: `trucktrav/ansible-drive` (for structure +reference only, not extended) +- Related project: `zero-check` skill at `~/.claude/skills/zero-check/` +- Related project: `project-scaffolding-skill` plan (filed separately) +- Key infra facts: Tailscale mesh connects `truckslaptop`, `manjaro1`, +`pve`, current VM; Pi-hole + Unbound at `10.0.11.50` + +### Next session + +1. Answer the open decisions above (backup targets, tool choice, rename +approach) +2. Create the new Ansible repo and initialize skeleton +3. Create dotfiles repo and seed with current config +4. Start with the `common` role and test idempotency before scaling to the +full set + + +...sent from Jenny & Travis \ No newline at end of file