webhouse.appwebhouse.appdocs

Volume-backed Fly.io deploys. First push creates the infrastructure; every edit after that syncs only changed files in ~200 ms–1 s.

What it is

Fly.io Live is a deploy provider that decouples infrastructure from content. The Docker image contains only a lightweight web server and a signed sync endpoint. Your site's files live on a persistent Fly Volume. Publishing a content change uploads only the changed files — not the whole image.

Result: typical text edit is live in 200 ms–1 s, vs. ~30–120 s for a full Docker rebuild.

When to use Fly.io Live

  • You want everything in Fly (EU data residency, same account as your other services)
  • Your site is static (build.ts outputs HTML/CSS/JS/images)
  • You want "save in CMS → live" feedback without waiting on Docker
  • You also run Fly apps for dynamic services (forms, auth, SSR pages) and want the static content there too

When NOT to use it

If your site is pure static with no Fly requirement, Cloudflare Pages is faster (300+ PoPs) and free. Fly Live is single-region by default — use only if you have a Fly-specific reason.

If your site is a Next.js SSR app or a custom server, use the classic Fly.io (rebuild) provider — SSR apps can't be expressed as static files.

How it works

First deploy (infrastructure setup)

  1. CMS admin runs flyctl apps create, flyctl volumes create
  2. Generates an HMAC secret and stores it in Fly Secrets as SYNC_SECRET
  3. Builds and deploys the sync-endpoint Docker image (Caddy/Bun serving from the volume)
  4. Waits for /_icd/health to respond
  5. Does the first content sync

This takes about 30–60 seconds, one time.

Subsequent deploys (content sync, every save)

  1. CMS admin builds your site locally (deploy/)
  2. Fetches the remote file manifest: GET /_icd/manifest{ files: { path: sha256 } }
  3. Diffs against local — computes { added, changed, removed, unchanged }
  4. POST /_icd/deploys → begins a new staging deploy
  5. PUT each changed/added file, DELETE each removed file
  6. POST /_icd/deploys/:id/commit → atomic symlink swap on the server

Transport is HMAC-SHA256 signed (same pattern as Instant Content Deployment). All requests expire after 5 minutes.

Atomic deploys

Each deploy lives in its own directory under /srv/deploys/<id>/. On commit, the server atomically swaps the /srv/current symlink to point at the new directory. Requests in flight never see a half-updated tree. The server keeps the last 5 deploys for rollback; older ones are pruned.

Setup

1. Configure the provider

Settings → Deploy → Fly.io Live (instant sync). Provide:

  • API token — Fly personal access token (get one)
  • App name — auto-generated from your site name if left empty
  • Region — default arn (Stockholm); pick the closest Fly region to your users
  • Volume name — default site_data; you rarely need to change this

The organisation slug is auto-detected from your token.

2. Click Deploy

First click provisions the infrastructure and then does the first content sync. You'll see the live URL (https://<app-name>.fly.dev) when it completes.

3. Subsequent saves

Once set up, every deploy is fast. Enable Deploy on save in the same panel if you want auto-publish on content changes.

Rebuilding infrastructure

The Docker image rarely needs rebuilding. When cms-admin ships a new version of the sync-endpoint server, the admin UI surfaces a "Rebuild infrastructure" prompt — click it to refresh the image. Volume data is preserved, so content survives rebuilds.

Triggers that require an infra rebuild:

  • cms-admin update with a new sync-endpoint version
  • Custom server configuration (headers, redirects) — requires editing the image template
  • Fly machine resize (memory, CPU) — via fly.toml

Custom domain

Add your domain in Settings → Deploy → Custom domain. Fly Live automatically runs flyctl certs add on the next deploy. Configure the DNS records at your registrar per Fly's instructions.

Limitations

  • Single-region: Fly volumes are region-pinned. For global low latency, pair with a CDN in front, or use Cloudflare Pages instead.
  • One writer: The volume has one primary machine. Don't scale horizontally without understanding Fly volume semantics.
  • 1 GB volume default: Fine for most sites (content is small). Resize via flyctl volumes extend if needed.

Troubleshooting

"Sync endpoint did not come online" — first deploy timed out waiting for the container. Check Fly logs: flyctl logs -a <app-name>. Most common cause: the volume failed to mount.

"Invalid signature" on sync requests — the SYNC_SECRET in Fly Secrets got out of sync with the CMS config. Re-run the deploy; the admin will regenerate and push a new secret.

"Version mismatch, rebuilding infra" — expected when you upgrade cms-admin to a version with a newer sync-endpoint. Let it run; the rebuild takes ~60 s.

Comparison

Fly.io LiveFly.io (rebuild)Cloudflare PagesGitHub Pages
Time per content edit~200 ms–1 s30–120 s3–10 s15–30 s
Global edgeNo (1 region)NoYes (300+ PoPs)Yes (CDN)
SSR supportNo (static only)YesWorkers onlyNo
Monthly cost (small site)~$3–5~$3–5$0$0
When to pick itFly ecosystemNext.js / SSR appsPure static, globalOpen-source projects
Tags:Deploy: Fly.ioDeploy: Docker
Previous
Releases & downloads
Next
Cloudflare Pages — global edge, free
JSON API →Edit on GitHub →