Home Cloud Tracker (Path D)¶
Goal: Family home cloud serving 3-5 family members with secure remote access, on the same homelab foundation as Path A.
Scope and users¶
- 3-5 family members as named user accounts
- Mix of access patterns: in-home (LAN), remote (Cloudflare Tunnel via browser), admin (WireGuard)
- Family-data sensitivity: photos, calendar, contacts, media, files
- MFA mandatory for all user accounts (enrolled at onboarding, backup codes printed)
- Audit logs required (who accessed what, when) for the family-data services
Services in scope¶
| Service | Purpose | Access |
|---|---|---|
| Nextcloud | Files, photos, calendar, contacts | Family-facing via Cloudflare Tunnel |
| Jellyfin | Media server (movies, music) | Family-facing via Cloudflare Tunnel |
| SMB shares on homeNas | Direct OS-level file access | LAN only; existing, unchanged |
Architecture (locked 2026-05-31 — do NOT revisit without new context)¶
- External access: Cloudflare Tunnel for user-facing services (no port forwarding required). WireGuard for admin paths (PVE, iLO, monitoring) — admin-only.
- DNS: Cloudflare hosts
iamkay.euandhm.iamkay.eupublic records (registrar: Namecheap). Internal*.hm.iamkay.euserved by a new Debian 12 LXC + Unbound, built fresh as part of Phase 3 item 2 (the pre-existing LXC 500 "demo-centos" was investigated 2026-05-31 and turned out NOT to be a DNS server — see investigation inSESSION-LOG.md2026-05-31 evening). Fresh VMID allocated, NOT a reuse of 500. - TLS: Let's Encrypt wildcard
*.hm.iamkay.euvia DNS-01 challenge against the Cloudflare API. Cert renewal automated. - Reverse proxy: Traefik. TLS termination at Traefik; routing by hostname. Chosen over HAProxy / Nginx because Kay has prior experience with all three and Traefik's dynamic-config + Let's Encrypt + provider integration is the lightest operational load for this scale.
- Authentication: Authelia for SSO + MFA in front of every user-facing service. Chosen over Keycloak because user count is small (3-5) and Authelia is simpler to operate.
These are committed decisions, not options. Only reopen for genuine new context (platform changes, scale shift, family request).
Foundation dependencies (must be DONE before any Path D item starts)¶
Path D is gated on these homelab-tracker.md items being COMPLETE:
- Phase 1 — switch VLAN config + Cat6A cable run + riser install + RAID battery replacement
- Phase 2 — network rebuild: VLANs 10/20/30/40 operational, iLO moved to VLAN 40
- Phase 3 — service infrastructure:
- 3.1 Proxmox Backup Server deployed + first successful backup + restore drill
- 3.2 Build new Debian 12 LXC + Unbound for internal DNS (
*.hm.iamkay.eu); fresh VMID. NOT a migration of LXC 500 (which is "demo-centos", not a DNS server — see SESSION-LOG.md 2026-05-31 evening). - 3.3 Traefik + Let's Encrypt DNS-01 (Cloudflare API)
- 3.4 Authelia SSO + MFA
- 3.5 Monitoring + log shipping (for audit)
Path A (GitLab CE, developer services) starts in parallel with Path D once the same Phase 3 infra is in place — they share PBS, Traefik, Authelia, DNS.
Path D items (deploy order)¶
D.1 Nextcloud deployment — DONE 2026-06-07 (Session 10 marathon)¶
- Deployed:
https://cloud.hm.iamkay.eu/internal +https://cloud.iamkay.eu/external via Cloudflare Tunnel - LXC 258
nextcloud, Debian 12 + Docker-in-LXC (nesting=1,keyctl=1), unprivileged, onboot=1 - Static
10.0.10.60/24on VLAN 10 - Resources: 4 vCPU / 8 GB RAM / 50 GB local-lvm rootfs (rootfs only, NFS for data)
- Stack: docker-compose with nextcloud:fpm-alpine + nginx:alpine + postgres:16-alpine + redis:alpine + cron container; web on 8095 internal
- Storage architecture: Nextcloud's
/var/www/html/dataLOCAL on LXC rootfs (app init, metadata, thumbnails); homenas NFS exportnextcloud-data(on s-tank, 1.4 TB free) bind-mounted into LXC at/mnt/nfsand registered through Nextcloud's built-in External Storage as mount point "Family Storage" (Local type, all users, sharing enabled). Verified storage status=ok viaocc files_external:verify. Reason not direct NFS at /data: nextcloud:fpm-alpine entrypoint'srsync --chown www-data:rootconflicts with NFS+unprivileged-LXC permission model regardless ofall_squash/anonuid=100033setup — External Storage is the upstream-blessed pattern for NAS-backed Nextcloud. - NFS configured
all_squash,anonuid=100033,anongid=100033,subtree_check,insecureon OMV side, exported only to10.0.10.5/32(PVE host). PVE mounts at/mnt/pve/nextcloud-data(NFSv4 pseudo-root path10.0.10.11:/nextcloud-data), bind-mounts into LXC 258 at/data(then container mounts as/mnt/nfs). - Internal cert: existing Traefik
*.hm.iamkay.euLE wildcard - External cert: separate LE cert auto-issued for
cloud.iamkay.euvia DNS-01 against existing Cloudflare token (same token scoped to iamkay.eu zone covers both subdomains and sibling apex subdomains) - NOT behind Authelia — by design, on purpose. Sync clients (mobile/desktop Nextcloud app, CalDAV/CardDAV) don't tolerate ForwardAuth redirects; would break sync entirely. Nextcloud has its own brute-force throttle + per-user TOTP 2FA + app passwords for clients. Pattern applies to GitLab, Vaultwarden, Jellyfin similarly.
- PBS backup: LXC 258 captured by the daily 02:00 backup job (rootfs only; data dir is small since real user files live on NFS which homenas's RAID5 + OS-level discipline protects)
- Credentials: Vaultwarden entries "Nextcloud - kay admin" + "Nextcloud - PostgreSQL" + "LXC 258 nextcloud - root"
- Action remaining: enroll TOTP 2FA for
kayin Nextcloud Settings → Security - First-family-onboarding follow-up: configure SMTP for password reset / share invites; create family user accounts; design folder/quota policy
D.2 Jellyfin deployment¶
- Status: NOT STARTED
- Depends on: same Phase 3 foundations as D.1 (no dependency on D.1 itself, can parallel)
- Deliverable:
https://media.hm.iamkay.eu/same pattern (Traefik front, Authelia auth, PBS backup of config) - VM specs: 2 vCPU, 4 GB RAM, modest OS disk + media storage (NFS mount from homeNas or dedicated bay)
- Transcode: software only for now (G7 CPUs are old, no hardware transcode); fine for 1-2 concurrent streams. Reassess if family-load justifies a dedicated GPU NIC later.
- Validation: family test account streams a media file via Cloudflare Tunnel on mobile data, at least one mobile-targeted transcode profile works
D.3 Cloudflare Tunnel for user-facing services — DONE 2026-06-07 (Session 10 marathon, for Nextcloud)¶
- Deployed: LXC 259
cloudflared, Debian 12 + Docker-in-LXC runningcloudflare/cloudflared:latest - Static
10.0.10.70/24on VLAN 10 - Resources: 1 vCPU / 512 MB / 8 GB local-lvm
- Tunnel name:
homelab(tunnel ID006ccc6c-c0c9-4811-9244-d6df77b8c966) - Token in
TUNNEL_TOKENenv (token-mode tunnel, config via Cloudflare dashboard not local config file) - Route: cloud.iamkay.eu → https://cloud.iamkay.eu:443 (URL uses hostname not IP so cloudflared's TLS cert validation against URL hostname matches the Traefik-served LE cert)
- Critical workaround: docker-compose adds
extra_hosts: ["cloud.iamkay.eu:10.0.10.10"]so cloudflared resolves cloud.iamkay.eu LOCALLY to Traefik's internal IP (avoiding loopback through Cloudflare's edge → tunnel → cloudflared again). The new Cloudflare dashboard UI under Networks → Routes doesn't expose Origin Server Name / No TLS Verify settings; the extra_hosts trick at the resolver layer achieves the same effect. - Cloudflare DNS: CNAME
cloud.iamkay.eu→006ccc6c-c0c9-4811-9244-d6df77b8c966.cfargotunnel.com(proxied, orange cloud). Created manually after the auto-create returned 400 (stale record from a deleted earlier tunnel attempt was blocking the API). - Verified end-to-end by Kay from phone on 4G: https://cloud.iamkay.eu/ → Cloudflare edge → tunnel → Traefik → Nextcloud login page renders, accepts credentials.
- Cert pre-condition handled: Traefik fetched a dedicated LE cert for cloud.iamkay.eu via DNS-01 (existing Cloudflare token covers iamkay.eu zone).
nextcloud-externalrouter on websecure entrypoint uses that cert.nextcloud-internaluses the *.hm.iamkay.eu wildcard. - Build gotchas captured for next time:
- Traefik's
webentrypoint has hard-coded HTTP→HTTPS redirect. Putting cloudflared backend on HTTP (port 80) causes infinite redirect loop. Solution: backend MUST be HTTPS, which requires a valid cert (browser-trusted or self-signed with No TLS Verify on cloudflared). - LXC 251's
/etc/resolv.confwas still pointing at the dead LXC 250 Unbound (10.0.10.53) after Pi-hole replaced it in Session 10's Phase 3.6.5. ACME requests failed because LE API couldn't resolve. Fix:pct set 251 -nameserver 10.0.10.54(persistent across reboot) + restart Traefik. - Cloudflare's new "Routes" UI (under Tunnels) is a stripped-down replacement for the older "Public Hostnames" tab. No Type dropdown, no TLS settings expander. Workarounds at the cloudflared (extra_hosts) and Traefik (full cert chain) layers cover what those settings would have done.
- Cloudflare Tunnel token: stored in Vaultwarden ("Cloudflare Tunnel - homelab") and at
/root/cloudflared-build/cf-tunnel.tokenon PVE host (mode 0600). On-disk copy delete pending after Vaultwarden migration confirmed. - Future: when D.2 Jellyfin lands, add another public hostname
media.iamkay.euto the same tunnel
D.4 Remote admin access — TAILSCALE (committed 2026-06-05, next session)¶
- Status: QUEUED for next session
- Decision: Tailscale (was deferred between WireGuard and Tailscale per architecture decision; chosen 2026-06-05 because Kay wanted phone access to Vaultwarden + Authelia + admin tools from anywhere with minimal setup overhead).
- Depends on: foundation Phase 2 + Phase 3 (PBS available so we don't get locked out without a known-good snapshot) — all met as of Session 9.
- Out of the original two viable approaches:
Option WG: native WireGuard (DIY, self-hosted) - Run WireGuard server on pfSense (built-in package) or a dedicated VM - Manage keys + peer configs manually - Pros: no third-party dependency, full L3 control over routing, free - Cons: must expose UDP/51820 (or another port) to internet, manual key rotation, peer config friction
Option TS: Tailscale (managed control plane, built on WireGuard) - Install tailscale agent on PVE host, NAS, laptop, phones - Identity-based auth via Google / GitHub / Tailscale account - Pros: zero port forwarding (NAT punch), auto key rotation, MagicDNS, ACLs in JSON, easy phone enrollment, free for up to 100 devices - Cons: depends on Tailscale's coordination service (not 100% self-hosted; alternatives: Headscale self-hosted control plane) - Note: Tailscale is built on WireGuard - both end up with WG datapath, just different control plane
- Deliverable: remote admin reach to MGMT VLAN 40 (iLO, PVE web UI, monitoring) and SERVERS VLAN 10 host admin paths
- Validation: from the laptop on a non-home network, the chosen tool comes up and
ssh pve+ iLO web UI both work - Risk: a misconfigured admin VPN can lock out admin recovery - test from the same network before relying on it for remote admin, and keep iLO web UI + chassis console reachable as backup recovery paths.
- Recommendation when deciding: start with Tailscale for ease (zero port-forward, phone enrollment is trivial), self-host with Headscale later if Tailscale's coordination dependency becomes a concern. WireGuard-native remains valid for full purist self-hosting.
D.5 SMB continuity check¶
- Status: ONGOING (existing homeNas SMB shares)
- Action: verify the existing SMB stack still works after the network rebuild lands, particularly SMB-from-VLAN-10 client paths
- No new deployment; the goal here is "don't accidentally break it during Phase 2"
D.6 Family onboarding (3-5 members)¶
- Status: NOT STARTED
- Depends on: D.1, D.2, D.3 all working end-to-end
- Per user steps:
- Provision Authelia account (TOTP MFA enrollment, backup codes printed and handed off securely)
- Provision Nextcloud user account
- Walk through first-time login on the family member's primary phone + a laptop
- Hand over a short "how to use this" doc (kept separately from D:\PVE)
- Second-admin handover: identify one trusted family member who can act as backup admin if Kay is unavailable. Document the recovery path for that person — at minimum: how to log in to PVE, how to launch PBS restore, who else has emergency contact for iLO/network.
D.7 Audit logging¶
- Status: NOT STARTED
- Depends on: monitoring stack from
homelab-tracker.mdPhase 3.5 - Deliverable: per-user access logs for Nextcloud and Jellyfin shipped to Loki (or equivalent), basic Grafana dashboard "who accessed what, when"
- Required, not optional — family-data services need accountability, not just nice-to-have observability
D.8 Off-site backup target decision + rollout¶
- Status: NOT STARTED, decision deferred to before D.1 ships data
- Options: Cloudflare R2 vs Backblaze B2 (cost / latency / lock-in tradeoffs to weigh at decision time)
- Deliverable: PBS configured to push to chosen target, encryption verified, end-to-end restore drill from off-site
D.9 Family handover documentation¶
- Status: NOT STARTED
- Deliverable: a short non-technical doc for the family covering: how to log in, how to use Nextcloud / Jellyfin, who to contact when something's broken, what NOT to do (don't share login, don't disable MFA)
- This is for the family, not for Claude — kept outside D:\PVE\
Risk acknowledgments¶
- Family-data responsibility: once the family is onboarded, an outage or data loss is no longer "my homelab is down for a day", it's "I lost my sister's wedding photos". Backups (PBS local + off-site cold) MUST be verified end-to-end (restore drill on a throwaway VM) before family is told to upload anything important.
- MFA is non-negotiable for user accounts. No exceptions. Backup codes printed.
- Admin path separation: family-facing Cloudflare Tunnel must not expose admin surfaces (iLO, PVE web UI, Prometheus, Authelia admin). Admin is WireGuard only.
- Single-admin risk: if Kay is unavailable / out-of-pocket, the family loses access. Plan a documented second-admin handover in D.6.
- Cloudflare dependency: if Cloudflare Tunnel goes down, family loses remote access. Acceptable trade vs port-forwarding + DDNS + cert juggling. SMB on the LAN still works locally regardless.
- Internal DNS is new-build, not migration. The pre-existing LXC 500 ("demo-centos") was investigated 2026-05-31 and turned out to be unrelated to DNS — stopped + unrecoverable + a different identity than Kay remembered. Internal DNS will be built fresh as a new Debian 12 LXC running Unbound. Tracked in homelab-tracker Phase 3 item 2.