Routes adyrem.duckdns.org/mtg → http://10.10.2.10:3000 (claude-code-vm)
with StripPrefix so the app sees requests at /.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without -d 192.168.1.10, the DNAT rule intercepted all TCP port 80/443
traffic arriving on vmbr0 — including LAN or routed traffic destined for
internal VMs like Pi-hole (10.10.1.2), redirecting it to Traefik instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
common role: add nmcli task that ensures the static IP, gateway, and DNS
are configured in NetworkManager — idempotent, only applies when
network_gateway is defined. Fixes Gitea going offline after reboot
because the NM connection had reverted to DHCP.
group_vars/infra: add network vars (10.10.1.0/24, gw 10.10.1.1)
group_vars/claude_code_vms: add network vars (10.10.2.0/24, gw 10.10.2.1)
also fix ProxyJump to use adyrem@:2222 (root login was disabled)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Arch Linux cloud image, 4 cores/8GB, dev-net (10.10.2.10), autostart.
Cloud-init handles user/SSH key/network on first boot. Ansible role
installs Claude Code CLI, tmux, SSH keys, SSH config for all managed
VMs via ProxyJump, homelab repo clone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Set onboot=1 on VM 100 (gitea) and VM 101 (monitoring) so they start
automatically on Proxmox host boot.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
VM 102: Windows 11 Home N, 8 cores/16GB, OVMF+TPM2, QXL/SPICE display,
vmbr3 (desktop-net). SPICE used instead of RDP — Home N has no RDP server.
Clean-install snapshot taken and synced to HDD.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- sanoid: daily snapshots (7d) + weekly (4w) for rpool/data (VM disks)
and rpool/ROOT (Proxmox OS); runs every 15 min via systemd timer
- syncoid: daily replication from rpool/data and pve-root to hdd/backups
at 02:00; first full sync completed successfully
- All VM disks (gitea, monitoring) now backed up to HDD pool
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create claude-code user on Proxmox with chroot + ForceCommand internal-sftp
- Add dedicated SSH keypair (public key committed, private key in keys/)
- Update requirements to document that Claude Code runs in a persistent VM,
connects to other VMs via SSH, and to the Proxmox host via SFTP only
- Session persistence via tmux allows reconnecting from any WireGuard device
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old values were exposed in plaintext in the initial commit history.
New values generated via `gitea generate secret`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Node.js is required by JS-based actions (e.g. actions/checkout@v4)
on native host runners. python-pip is needed for ansible-lint install.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move group_vars into inventory/ so playbooks can find them (was only
visible to ad-hoc commands via CWD)
- Add Ansible Vault for sensitive variables (gitea/grafana passwords,
tokens, db credentials) with vault_password_file outside the repo
- Enable Gitea Actions and deploy act_runner with Docker backend on
the gitea VM
- Add .gitea/workflows/lint.yml to run ansible-lint on every push
- Set up Gitea → GitHub push mirror (sync_on_commit)
- Fix ansible.cfg stdout_callback for ansible-core 2.20 compatibility
- Add python-psycopg2 to gitea role (required for postgresql modules)
- Add docker to gitea_runner role (required by act_runner at startup)
- Exclude password hashes and VM images from git
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>