Home Assistant Performance Fix & Infrastructure Migration
Problem Summary
Home Assistant at ha.hideawaygaming.com.au (HAOS 2026.5.3) periodically becomes unresponsive. Because critical infrastructure services (AdGuard DNS, Tailscale VPN, Guacamole RDP, Nginx Proxy Manager) all run as HA add-ons inside the same VM, any HA freeze causes house-wide network and access failures.
Network Plan
| Service | CT ID | IP | Port(s) |
|---|---|---|---|
| OPNsense (gateway) | — | 10.0.0.254 | — |
| Proxmox (HAL-HOST) | — | 10.0.0.240 | 8006 |
| HAOS VM | — | 10.0.0.55 | 8123 |
| AdGuard Home (LXC) | 120 | 10.0.0.224 | 53, 80 |
| Guacamole (LXC) | 121 | 10.0.0.225 | 8080 |
| NPM (LXC) | 122 | 10.0.0.226 | 80, 443, 81 |
Execution Order
Run the scripts on the Proxmox host (10.0.0.240) as root.
1. Apply recorder exclude (HA side)
Merge recorder_exclude.yaml into /config/configuration.yaml, restart HA.
2. Deploy AdGuard LXC
chmod +x setup-adguard-lxc.sh
./setup-adguard-lxc.sh
- The script attempts SSH config migration from HAOS (no GUI export exists)
- If SSH fails, follow the manual migration steps printed at the end
- After setup: update OPNsense DHCP DNS from 10.0.0.55 → 10.0.0.224
3. Deploy NPM LXC
chmod +x setup-npm-lxc.sh
./setup-npm-lxc.sh
- Migrates SQLite DB, Let's Encrypt certs, and custom configs from HA addon
- After setup: update OPNsense port forwards (80/443) from 10.0.0.55 → 10.0.0.226
- For automated backup-based migration, set
HA_TOKENenv var before running
4. Deploy Guacamole LXC
chmod +x setup-guacamole-lxc.sh
./setup-guacamole-lxc.sh
- Re-create RDP connections in the web UI
- Set up NPM proxy with WebSocket support
5. Cleanup HA
- Stop AdGuard, NPM, and Guacamole add-ons in HA
- Clean up browser_mod, Plex, Pioneer VSX-832 stale entities
- Increase HAOS VM memory to 8 GB
- Optionally re-add AdGuard as HA integration pointing to 10.0.0.224
Docker-in-LXC Note
The Guacamole and NPM scripts create unprivileged LXC containers with lxc.apparmor.profile: unconfined set automatically. This is required because Docker inside unprivileged LXC cannot access net.ipv4.ip_unprivileged_port_start under the default AppArmor profile. The setup scripts handle this automatically — the fix is applied between container creation and first start.
If you already deployed the containers before this fix was baked in, run fix-docker-lxc.sh followed by fix-guac-npm.sh to retroactively apply it.
Architecture After Migration
Internet
│
┌────┴────┐
│ OPNsense │ 10.0.0.254
│ Gateway │
└────┬────┘
│
┌───────────┬───────┴───────┬───────────┐
│ │ │ │
┌──┴──┐ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐
│ AGH │ │ NPM │ │ HAOS │ │ Guac │
│ LXC │ │ LXC │ │ VM │ │ LXC │
│.224 │ │ .226 │ │ .55 │ │ .225 │
│DNS │ │ HTTP/S│ │HA only│ │ RDP │
└─────┘ └───────┘ └───┬───┘ └───────┘
│
┌────┴────┐
│Tailscale│
│(in HA) │
└─────────┘
Files
| File | Purpose |
|---|---|
recorder_exclude.yaml |
Recorder exclude config — merge into configuration.yaml |
setup-adguard-lxc.sh |
CT 120 — AdGuard Home with SSH config migration |
setup-guacamole-lxc.sh |
CT 121 — Guacamole via Docker Compose (AppArmor fix baked in) |
setup-npm-lxc.sh |
CT 122 — NPM with DB/cert migration (AppArmor fix baked in) |
fix-docker-lxc.sh |
Retroactive fix — adds AppArmor unconfined to CT 121 & 122 |
fix-guac-npm.sh |
Retroactive fix — reinits Guacamole DB + retries NPM migration |