Your instinct is right but I'd push back gently on one assumption: the Pi 5 only buys you real containment if you also assume the attacker will escape the container — and container escapes from properly configured containers (no privileged, no docker socket mounted, seccomp default) are rare in practice. What's not rare is an attacker getting app-level access to one public service and then abusing that service's credentials: your Nextcloud app password, its SMTP credentials, its access to the reverse proxy config.
So the segmentation that pays off most for minimal effort:
- Move public services off the NAS box — yes, exactly as you planned. The Pi 5 handles a handful of public services fine. Even without container-escape paranoia, you've separated the machine that has your entire NAS/backup dataset mounted.
- Credentials are the actual lateral path. Whatever the Pi can reach, the Pi's compromise can reach: make its firewall allow only the specific ports it needs back into the LAN (DNS out, maybe the backup target port), and ideally have it push backups out rather than pull data in.
- Reverse proxy on the Pi too — your public-facing reverse proxy config is itself a target (acme account, upstream definitions). Keep it with the services it fronts, not with your private infrastructure.
One extra benefit you didn't mention: rebuilding is now cheap. If the public machine gets trashed — by an attacker, or more likely by you breaking it during an update — your NAS/VPN/DNS stack is untouched and you can redeploy the public box from a compose file in an hour. That separation-for-blast-radius argument sells itself in the first real incident.
The problem you're describing — reconfiguring things when the IP changes — has a standard fix that costs nothing: a domain with a short-TTL A record updated automatically. Two paths, pick by how your services are consumed:
If the audience is you/family: Tailscale or plain WireGuard to a $4-5 VPS, and the IP churn stops mattering entirely — you connect to the VPS/tailnet name, which never changes, and home-IP changes become invisible. This also sidesteps CGNAT if your ISP is doing that.
If services must be publicly reachable: dynamic DNS. With a Cloudflare-hosted domain, a cron (
curlthe API with a scoped token, or ddclient) updating the A record every 5 minutes with a 60-120s TTL means a change propagates within minutes. What you must not do is hand-configure the IP anywhere else — certificate SANs, firewall rules, client configs — everything references the hostname only. Once everything is hostname-based, an IP change is a non-event you'll never notice.Two honest caveats: if your ISP changes IP while a long-lived connection is up you'll get one brief blip mid-transfer — nothing reconfiguration can prevent anyway. And if your goal is email delivery from home, a dynamic residential IP is a deliverability problem no DDNS fixes; mail wants to go out via a VPS relay regardless.