Thirty-One Apps, One Desktop
Date: 2026-03-24 Duration: Continuation from 2026-03-23 session Status: Implementation complete, ready for final user setup Commit: d2b41ab1
What Happened
ArgoBox OS is live. Deployed to CF Pages at argobox-os.pages.dev/os. A full KDE Plasma-like desktop interface running in the browser with 31 container apps listed in the Start Menu.
This is the thing I've been building toward. A web-based operating system that fronts my entire homelab. Click Jellyfin, it loads in an iframe. Click Sonarr, same thing. Click Grafana, terminal, file manager — all proxied through Cloudflare tunnels to containers running on argobox-lite at 10.0.0.199.
And 24 of the 27 tunnel routes work perfectly. 89% success rate on first deploy. I'll take it.
The User Management API
Built a POST endpoint for managing KV user roles:
POST /api/admin/users
Takes email, displayName, role (admin/member/demo), optional osProfile override, optional service list for limited access. Returns HTTP 201 with the created record. Stored in KV under data:user-roles.
The immediate use case: adding Bogie as a member with the homelabber profile. But the API is generic enough for any future user. CF Access handles authentication. The KV store handles authorization. Two separate layers.
Commit d2b41ab1 — pushed to origin/main, ready for production.
The Three Broken Routes
Spent time debugging the 3 routes that aren't working. Plot twist: none of them are tunnel problems. All three are container configuration issues.
Healthchecks (port 8084): Returns 400 Bad Request. Django's DisallowedHost error. The container doesn't have healthchecks.argobox.com in its ALLOWED_HOSTS config. Tunnel delivers the request fine. Django rejects it.
SABnzbd (port 18085): Returns 403 Forbidden. API authentication or authorization misconfiguration on the container side. The tunnel routes correctly. SABnzbd just won't let anyone in.
Finance (port 4200): Returns 404 Not Found. App might not be initialized, or it expects a different URL path. Need to check if it wants / or /finance at the root.
Three different failure modes. Three different containers. Zero tunnel issues. The infrastructure layer works. The application layer needs per-container fixes. Should be 2-3 hours of work.
The Infrastructure Scorecard
| Component | Status |
|---|---|
| CF Pages | Live at argobox-os.pages.dev/os |
| Container Backend | Running at argobox-lite:9000 (authenticated) |
| CF Tunnel | 24/27 routes operational |
| Service Registry | 31 apps registered |
| API Auth | Bearer token enforcement working |
| Demo Mode | Fixed, no more crashes |
| KV Roles Store | Ready, data:user-roles key |
| User Mgmt API | Ready, POST /api/admin/users |
What's Left for Me to Do
Three manual steps. All in the Cloudflare dashboard.
- Add custom domain
os.argobox.comto the CF Pages project. Should be a DNS record and a 5-10 minute certificate provisioning wait. - Update CF Access application to point to the custom domain instead of
argobox-os.pages.dev. - Test live access — login via CF Access, verify Start Menu loads, click through some apps.
After that, add Bogie via the API:
curl -X POST https://os.argobox.com/api/admin/users \
-H "Content-Type: application/json" \
-d '{
"email": "bogie@yourdomain.com",
"displayName": "Bogie",
"role": "member",
"osProfile": "homelabber"
}' \
--cookie "CF_Authorization=<token>"
What's Not Done Yet
The stuff that didn't make this session:
- Binary WebSocket protocol for terminal sessions — designed, not implemented. Target is under 20ms latency and 50x message size reduction.
- Durable Objects for session persistence — commented out in wrangler.toml. Right now sessions live in-memory only.
- Terminal scrollback ring buffer — planned.
- AsyncFileSystemAdapter for the file manager — planned.
- Virtual scrolling for 10,000+ file directories — planned.
All optional enhancements. The core OS works. 31 apps load. The desktop interface is functional. The tunnel routes are 89% operational.
The Feeling
I keep looking at the Start Menu and counting. 31 apps. All of them running on a box under my desk. All of them accessible through a browser interface that looks like a real desktop environment. Click, iframe, done.
It's not perfect. Three routes are broken. The terminal still uses JSON protocol instead of binary. Session persistence relies on in-memory state. But the bones are right. The architecture is right.
Implementation 90% complete. The last 10% is dashboard configuration and container debugging. Not glamorous work, but it's the kind that turns a demo into something someone else can actually use.
31 apps. One desktop. 24 out of 27 working. I'll fix the other 3 tomorrow. Probably.