Dev Preview Plane (Bare Process + Signed Preview URL)
Dev Preview Plane
Section titled “Dev Preview Plane”FractalOps dev previews run as bare processes inside the Daytona sandbox and are exposed through the daytona-proxy signed preview URL. There is no in-sandbox container runtime and no compose-driven build-and-ship plane in the developer loop.
This page is the canonical model after the in-sandbox build/ship plane was deleted. The prior model (an in-sandbox compose build that drove a cluster image build and a Dokploy preview route) no longer exists; see git history.
A FractalOps workspace is for source editing, agents, tests, and short-lived client sessions — not a miniature production stack. Building and shipping images from inside the sandbox rotted: it duplicated the platform release pipeline, demanded a container runtime the sandbox should never have, and coupled the inner dev loop to cluster build infrastructure.
So docker is a permanent exit-127 wall inside the agent sandbox (a baked
stub that stays a stub even in-session). Dev previews instead run the project’s
own dev server as a bare process and surface it through the existing
daytona-proxy gateway.
The model
Section titled “The model”Daytona sandbox (no docker) -> bare dev server process (vite / next / uvicorn, HOST=0.0.0.0, PORT=<port>) -> daytona-proxy signed preview URL (https://{port}-{token}.proxy.monstore.io) -> per-project public host (https://<slug>.monstore.io when live)- Bare process. The dev server is launched as a detached bare process
(
setsid nohup ... & disown), bound to0.0.0.0so the proxy can reach it. The launch survives across separate sandbox exec calls, so a later call can poll the port and find it serving. - Signed preview URL. The proxy mints a short, externally-shareable, un-authed
token host (
{port}-{token}.proxy.monstore.io) — or, withsigned=false, the Keycloak-gated{port}-{sandboxId}.proxy...host. - Persistent backing services. Databases, static-site (vercel-sim) hosting, and big-facility compose remain on the project’s Dokploy plane. Dokploy is no longer used for dev servers.
Service and MCP surface
Section titled “Service and MCP surface”| Concern | Owner |
|---|---|
| Launch the bare dev server, wait until listening, mint the URL | DaytonaWorkspaceService.start_dev_preview |
| Mint a preview URL for an already-running port | DaytonaWorkspaceService.mint_preview_url |
| Preview-proxy gateway (HTTP + websocket reverse proxy) | daytona_preview_gateway |
| Agent self-service | dev-preview MCP (mcp__dev-preview__*): dev_preview_start / dev_preview_url / dev_preview_stop |
The default dev command falls back to the org default (pnpm dev) when the agent
does not pass one. start_dev_preview detects, launches, polls the port until a
server answers, then mints the signed URL — returning
{serving, previewUrl, token, port, command, repoDir}.
The dev-preview MCP binds identity and project server-side (project slug from
the request header), so agents never pass workspace ids or org ids as parameters.
Per-project public preview (<slug>.monstore.io)
Section titled “Per-project public preview (<slug>.monstore.io)”Each project gets one public host: <slug>.<base> where base is
FRACTALOPS_DAYTONA_PROJECT_PREVIEW_BASE_DOMAIN (default monstore.io).
- When the project has a live Daytona dev preview, the gateway claims that host and proxies the running dev server.
- When no live preview exists, the existing Dokploy delivery serves the same host untouched. There is no dual domain — one host, two possible backends, the live preview taking precedence.
The active preview is persisted per project (project_dev_preview columns on the
execution-workspace registry: port / sandbox id / signed / updated-at).
dev_preview_start records it; dev_preview_stop clears it.
ExecutionWorkspaceRepository.active_dev_preview(project_slug) reads it, and the
gateway fails closed to delivery on any registry hiccup — it never errors the
host.
Edge routing rule (no wildcard hijack)
Section titled “Edge routing rule (no wildcard hijack)”Edge-fronting (Cloudflare / edge-bridge sending <slug>.monstore.io to this
gateway) is per-slug, on preview lifecycle — added when a project has an
active preview and removed when it stops. It is not a wildcard. Already-
delivered hosts (for example sanmopia-modernization, teamclaw) must never be
hijacked by a wildcard preview route.
The preview-proxy domain is proxy.monstore.io (live) — cut over from the
former daytona-subdomain proxy host. Use proxy.monstore.io in all references.
dockeris hard-walled in the sandbox; do not reintroduce an in-sandbox compose/build plane or a docker-shim build router.- Dev previews are bare processes bound to
0.0.0.0, surfaced via the daytona-proxy signed URL — not Dokploy. - Dokploy is for persistent backing services only: databases, static-site (vercel-sim) hosting, and big-facility compose.
- Per-project edge routes are per-slug, on preview lifecycle. Never add a wildcard that could capture a delivered host.
- Image builds for the FractalOps platform itself are a separate, CI-owned release concern that pins GitOps — not part of the developer dev-preview loop.
Related
Section titled “Related”- Project Development Service Plane — workspace vs Dokploy backing-service boundary.
- Build & Package Cache Topology (Nexus) — the single Nexus cache plane.
- Build Plane Observability — telemetry for the CI runtime-image release pipeline and GlitchTip error tracking.