fabro/docker/split-web
Bryan Helmkamp 3e881e9938
fix(server): allow required CSP handoffs
Permit GitHub App manifest form posts and signed HTTPS VNC preview iframes while keeping the rest of the SPA CSP locked down. Mirror the policy in the split-web Caddy config.
2026-06-01 18:24:45 -04:00
..
Caddyfile.edge Add split web Docker Compose PoC (#445) 2026-05-28 00:03:00 -04:00
Caddyfile.static fix(server): allow required CSP handoffs 2026-06-01 18:24:45 -04:00
README.md Add split web Docker Compose PoC (#445) 2026-05-28 00:03:00 -04:00
settings.toml Add split web Docker Compose PoC (#445) 2026-05-28 00:03:00 -04:00

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:

  • /runs and /assets/* are served by the static fabro-web container.
  • /api/*, /auth/*, and /health are served by the Rust fabro-api container through the same browser origin.
  • Dev-token login sets a same-origin session cookie, and /api/v1/auth/me accepts it.