3.7 KiB
3.7 KiB
Illusory IOTAM
A SaaS platform that lets users run specific Android applications on hosted Docker-Android instances — instead of on their own device. Users get a unique link, install a PWA, and are streamed a live Android session from the cloud.
Currently in alpha. Greenfield. Subject to change.
How It Works
- Admin generates a unique link and assigns it to a user (or a slot).
- User opens that link in their browser — served by
apps/front. - User waits while a Docker-Android device is allocated to their session.
- User is prompted to install the PWA.
- User opens the PWA — they are routed into a live stream of their assigned Android instance.
- Admin manages the entire fleet from
apps/main(the dashboard), which communicates withapps/orchestratorrunning on each VPS to control Docker-Android containers.
Implementation Checklist
Foundation
- Monorepo setup (Turborepo + pnpm)
- Shared packages:
@pkg/logic,@pkg/db,@pkg/logger,@pkg/result,@pkg/keystore,@pkg/settings - PostgreSQL with Drizzle ORM
- Redis (Valkey) via
@pkg/keystore - OpenTelemetry end-to-end (logs, traces, metrics → SigNoz)
- Auth system (Better Auth — email/password, magic link, 2FA/TOTP, sessions)
- User management (roles, bans, account operations)
- Notifications system (priority, archiving, bulk ops)
- Admin dashboard shell (
apps/main— SvelteKit) - Background task tracking schema (task table)
Device Management (Orchestrator + Admin)
- Device schema — DB model for a device (host VPS, container ID, status, assigned session, etc.)
- Device domain in
@pkg/logic— controller + repository + errors - Orchestrator command interface — secured Hono routes the admin dashboard calls:
POST /devices/:id/start— start a Docker-Android containerPOST /devices/:id/stop— stop a containerPOST /devices/:id/restart— restart a containerGET /devices— list all devices and their current statusGET /devices/:id— page to view the device in more detail (info, live stream feed with ws-scrcpy)
- Device allocation logic — mark a device as in-use for a user session
- Device release logic — free up a device when a session ends
- Admin dashboard: Devices page — list fleet, show status, trigger start/stop/restart
- Internal API key auth between
apps/mainandapps/orchestrator
Link Management (Admin + Front App)
- Link schema — DB model (unique token, expiry, status, linked device ID)
- Link domain in
@pkg/logic— controller + repository + errors - Admin dashboard: Links page — generate links, view detail, configure linked device, revoke, delete
apps/front: validate incoming link token on requestapps/front: return appropriate error page for invalid/expired/revoked links
PWA & User Session Flow (apps/front)
apps/front: serve static PWA shell (HTML + manifest + service worker)apps/front: wait/loading page — poll for device allocation statusapps/front: PWA install prompt flow (beforeinstallprompt handling)apps/front: session binding — tie the PWA launch to the user's allocated deviceapps/front: route/proxy authenticated PWA requests to the Android instance stream
Android Streaming (scrcpy + ws-scrcpy)
- Docker-Android image setup and validation on VPS
- ws-scrcpy WebSocket server running per container, exposed via orchestrator
apps/front: scrcpy client embedded in PWA — renders the Android stream in browser- Input forwarding (touch/keyboard events → scrcpy → Android container)
- Session timeout + stream teardown on inactivity