Skip to content

Z2 Container Architecture

Host

Platform: Proxmox VE 8.x on Debian 12 (kernel 7.0.2-6-pve) Storage: WD 2TB enterprise (WDC WD2000FYYZ) via Ugreen USB 3.0 enclosure (Realtek 0bda:9201), mounted at /mnt/data (ext4) USB driver: usb-storage (UAS disabled via modprobe quirk at /etc/modprobe.d/usb-storage-quirks.conf)

Containers

All containers are unprivileged LXC (Debian 12), using local-lvm for rootfs.

VMIDHostnameOwnerCoresRAMRootfsAuto-start
100jimmy-neutron-postgresjimmy-neutron22048 MB32Gyes
101heimerdinger-nlpheimerdinger22048 MB32Gyes
102iroh-mail-polleriroh22048 MB32Gyes
103itachi-securityitachi22048 MB32Gyes
104l-researchl22048 MB32Gyes
105nujabes-audionujabes22048 MB32Gyes
106minato-telegramminato22048 MB32Gyes
107orochimaru-transcriptsorochimaru22048 MB32Gyes
108zoro-fitnesszoro22048 MB32Gyes
109bulma-financebulma22048 MB32Gyes
110hinata-desktopjimmy-neutron22048 MB10Gyes
111hinata-exit-nodejimmy-neutron1512 MB8Gyes

CT110 runs Debian 13 (trixie). All other containers run Debian 12.

CT111 carries TUN passthrough (lxc.cgroup2.devices.allow: c 10:200 rwm + lxc.mount.entry for /dev/net/tun) and runs the Mullvad WireGuard tunnel (wg-quick@mullvad, relay gb-lon, DNS 10.64.0.1) plus Tailscale advertised as exit node (--advertise-exit-node --accept-dns=false). The WireGuard private key lives only at CT111 /etc/wireguard/private.key (0600). The Z2 host carries no WireGuard configuration.

Bind Mounts

CT100 — jimmy-neutron-postgres

MountHost pathContainer pathMode
mp0/mnt/data/postgres-backup/mnt/backuprw
mp1/mnt/data/shared/sharedrw

CT101 — heimerdinger-nlp

MountHost pathContainer pathMode
mp0/mnt/data/shared/sharedrw
mp1/mnt/data/hinata/mail-archive/mail-archiverw
mp2/mnt/data/hinata/resources/email-intelligence/email-intelligencerw

CT102 — iroh-mail-poller

MountHost pathContainer pathMode
mp0/mnt/data/shared/sharedrw
mp1/mnt/data/hinata/mail-archive/mail-archiverw

CT103 — itachi-security

MountHost pathContainer pathMode
mp0/mnt/data/shared/sharedrw

CT104 — l-research

MountHost pathContainer pathMode
mp0/mnt/data/shared/sharedrw

CT105 — nujabes-audio

MountHost pathContainer pathMode
mp0/mnt/data/shared/sharedrw
mp1/mnt/data/hinata/media/mediarw

CT106 — minato-telegram

MountHost pathContainer pathMode
mp0/opt/jimmy-brain-ops/scripts/opt/scriptsro
mp1/mnt/data/transcripts/transcriptsrw
mp2/opt/hinata-vault/opt/vaultro
mp4/opt/telegram-gateway/opt/telegram-gatewayrw

CT107 — orochimaru-transcripts

MountHost pathContainer pathMode
mp0/mnt/data/transcripts/transcriptsrw

CT108 — zoro-fitness

MountHost pathContainer pathMode
mp0/mnt/data/zoro-fitness/mnt/data/zoro-fitnessrw
mp1/opt/hinata-sandpit/root/Sandpit/hinata-sandpitro

CT109 — bulma-finance

MountHost pathContainer pathMode
mp0/mnt/data/hinata/data/bulma/root/data/bulmarw
mp1/opt/hinata-sandpit/root/Sandpit/hinata-sandpitro
mp2/mnt/data/shared/sharedrw

CT110 — hinata-desktop

MountHost pathContainer pathMode
mp0/mnt/data/hinata/mnt/hinataro

Remote Desktop

VMIDHostnameIPServicePortLogin userGroupsVaultwarden item
110hinata-desktop192.168.1.114 (DHCP)xrdp (XFCE session)3389 (LAN-only)nnamdisudoct110-hinata-desktop

Shared Paths

Host pathPurposeContainers
/mnt/data/sharedCross-container shared dataCT100, 101, 102, 103, 104, 105, 109
/mnt/data/transcriptsCLI transcript storageCT106, 107
/opt/hinata-sandpitNative git clone of /opt/hinata-sandpit-bare. Updated on every push by the bare repo's post-receive hook.CT108, 109
/mnt/data/hinata/mail-archiveEmail archive (4 accounts)CT101, 102

Host Services

PortServiceUnitPurpose
5173studio-previewstudio-preview.serviceVite dev staging of applications/hinata-studio (exact localhost replica, --host 0.0.0.0)
8080hinata-collector (read API)hinata-collector.servicePublic FastAPI surface (uvicorn). Routers: bulma, events, football, leaderboard, mastery, musicmastery, sanji, shogi, zoro, allmight. Public via CT112 tunnel.
8090collector-bulmahinata-collector-bulma.serviceBulma write/ingest (split from former bulma+zoro twin)
8091collector-eventshinata-collector-events.serviceEvents write/ingest
8092collector-zorohinata-collector-zoro.serviceZoro fitness write/ingest. New 2026-06-12; /zoro/workouts, /zoro/summary, /zoro/posture, /zoro/posture/latest. EnvironmentFile=/etc/hinata/collector.env.
8093collector-masteryhinata-collector-mastery.serviceMastery write/ingest
8094collector-musicmasteryhinata-collector-musicmastery.serviceMusicmastery write/ingest
8095collector-quizhinata-collector-quiz.serviceQuiz write/ingest
8096collector-brookhinata-collector-brook.serviceBrook write/ingest
8097collector-housinghinata-collector-housing.serviceHousing write/ingest
8099collector-allmightcollector-allmight.serviceHealth Auto Export receiver — Apple Health JSON (/v2/health) + GPX routes (/v2/workout-route) to /mnt/data/hinata/data/allmight/

Public ingress — CT112 hinata-edge

FieldValue
ContainerCT112 hinata-edge
Tunnel IDfe668023-b168-41f0-b3b0-5b3891239b65
Hostnameapi.michael-engineer.dev
Originhttp://192.168.1.153:8080
Path regex^/(events|mastery|musicmastery|football|leaderboard|bulma|sanji|zoro|allmight|shogi)
Catch-allhttp_status:404
Config path/etc/cloudflared/config.yml (CT112)
Sandpit mirrorz2-collector/cloudflared/ct112-hinata-edge-config.yml
Key gatingNone (read API is keyless)

Twin-unit retirement

FieldValue
Retired unitcollector-bulma.service
Replacement pairhinata-collector-bulma.service (:8090, bulma-only) · hinata-collector-zoro.service (:8092)
Pre-split backup/opt/jimmy-brain-ops/scripts/collector-bulma.py.pre-split-20260612
Bulma script size264 lines
Zoro script size224 lines
EnvironmentFile/etc/hinata/collector.env
Retired2026-06-12

Zero-stub-endpoints ruling

FieldValue
Ruled2026-06-12
Stripped endpoint/healthz from collectors: brook, events, football, mastery, musicmastery, quiz, bulma, zoro
Stripped endpoint/ping from app/main.py
Collateralclass LeaderboardEntryIn removed from collector-events.py, restored from collector-quiz.py:37
VerificationSymtable scan across 9 touched files
Outstanding callerapplications/hinata-studio/src/musicmastery/api.ts lines 174–182 (404 fleet-wide)

Stale duplicate residue

PathState
/opt/hinata-z2/scripts/ (Z2 host)Stale duplicate collector copies; live runtime path is /opt/jimmy-brain-ops/scripts/

USB Storage Quirk

The Ugreen USB enclosure (Realtek 0bda:9201) triggers UAS protocol abort errors under sustained I/O, causing container bind mount flaps. Fixed by forcing the usb-storage driver:

Config: /etc/modprobe.d/usb-storage-quirks.conf

options usb-storage quirks=0bda:9201:u

Applied via update-initramfs -u + reboot. Kernel confirms: UAS is ignored for this device, using usb-storage instead.

Known Failure Modes

SymptomCauseResolution
lxc.hook.pre-start error on container startBind mount host source path missingCorrect mp* path in /etc/pve/lxc/[vmid].conf
I/O error inside container, host path accessibleStale bind mount after USB device resetContainer reboot (pct reboot [vmid])
All containers lose bind access simultaneouslyUSB storage device flapHost reboot to rebind all mounts

Cross-links: reference_z2-service-catalog · reference_container-storage-strategy