mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
## Summary Adds a standalone Docker Compose proof that runs the Fabro Rust API, a Caddy static SPA server, and a Caddy edge proxy as separate services. This demonstrates split web asset serving while keeping `/api/*`, `/auth/*`, and `/health` same-origin with the API server. ## Changes - Adds `docker-compose.split-web.yaml` with private `fabro-api` and `fabro-web` services behind an exposed `edge` proxy on port 8080. - Adds Caddy edge routing that sends `/api/*`, `/auth/*`, and `/health` to Rust, while everything else goes to the static web service. - Adds a static Caddy config for `apps/fabro-web/dist` with SPA fallback, source-map blocking, security headers, immutable asset caching, and `X-Fabro-PoC-Upstream` route-proof headers. - Adds PoC server settings and a README with build, run, and validation commands. ## Verification - `cargo dev docker-build --tag fabro-sh/fabro:split-web-poc` - `docker compose -f docker-compose.split-web.yaml up -d` - `docker compose -f docker-compose.split-web.yaml ps` - `curl` checks for `/runs`, `/assets/app.css`, `/assets/app.css.map`, `/api/v1/health`, `/api/v1/auth/config`, `/auth/login/dev-token`, `/api/v1/auth/me`, and `/api/v1/attach` - Browser login flow via `browser-use`: loaded `/login`, submitted the dev token, and landed on the authenticated Runs screen - `docker compose -f docker-compose.split-web.yaml config` - `caddy validate` for both Caddyfiles - `git diff --check` --- [](https://github.com/EveryInc/compound-engineering-plugin) 🤖 Generated with GPT-5 via [Codex](https://openai.com/codex)
1.8 KiB
1.8 KiB
Split Web Compose PoC
This Compose stack proves that Fabro can serve the React SPA from a separate static process while the Rust server remains the API and browser-auth origin.
Request ownership:
/api/*->fabro-api:32276/auth/*->fabro-api:32276/health->fabro-api:32276- everything else ->
fabro-web:80
The Rust server still contains bundled SPA assets. In this PoC they are simply
not reachable through the edge service for normal web paths.
The edge proxy adds X-Fabro-PoC-Upstream to responses so manual checks can
confirm which service handled a request.
Run
Build the local Fabro image from the current tree:
cargo dev docker-build --tag fabro-sh/fabro:split-web-poc
Set local auth secrets:
export SESSION_SECRET="$(openssl rand -hex 32)"
export FABRO_DEV_TOKEN="fabro_dev_$(openssl rand -hex 32)"
Start the split stack:
docker compose -f docker-compose.split-web.yaml up
Open http://localhost:8080.
Use SPLIT_WEB_PORT to expose a different local port, or FABRO_IMAGE to use
a different API image.
Validate
curl -i http://localhost:8080/health
curl -i http://localhost:8080/api/v1/health
curl -I http://localhost:8080/runs
curl -I http://localhost:8080/assets/app.css
curl -c /tmp/fabro.cookies \
-H "content-type: application/json" \
-d "{\"token\":\"$FABRO_DEV_TOKEN\"}" \
http://localhost:8080/auth/login/dev-token
curl -b /tmp/fabro.cookies http://localhost:8080/api/v1/auth/me
Expected results:
/runsand/assets/*are served by the staticfabro-webcontainer./api/*,/auth/*, and/healthare served by the Rustfabro-apicontainer through the same browser origin.- Dev-token login sets a same-origin session cookie, and
/api/v1/auth/meaccepts it.