Fly.io Deployment¶
This page deploys Strata on Fly.io as a single-tenant, personal-mode server, from the template fly.example.toml at the repository root.
Trust model¶
Read before deploying to a public URL
fly.example.toml deploys Strata in personal mode with
STRATA_ALLOW_REMOTE_CLIENTS_IN_PERSONAL = "true". Personal mode
has no authentication and enables write endpoints (create / delete
notebooks, upload artifacts). Anyone who reaches the Fly app's URL
can use it.
This is fine for: a personal scratch instance behind a URL you don't share, a hosted demo, or a deployment fronted by an authenticating proxy (Cloudflare Access, Pomerium, etc.).
This is not appropriate for: shared team deployments without an auth proxy, anything with sensitive data, anything you'd be upset about a stranger writing to. For those, use service mode with the trusted-proxy auth pattern instead. See Deployment Modes for the full comparison.
Prerequisites¶
- Fly CLI installed (
brew install flyctlon macOS). fly auth logincompleted (opens a browser; one-time).- A Fly.io account with a payment method on file. The template runs
one
shared-cpu-4xVM with 2 GB of memory. It suspends idle machines but keeps one running, so it does not scale to zero unless you changemin_machines_running. See Fly pricing for what that costs.
Deploy¶
From the repository root, copy the template to fly.toml (gitignored,
so your values stay out of commits):
Replace its placeholders:
app: your app name. App names are global on Fly, so pick one nobody has taken.primary_region: the region the machine and its volume live in (fly platform regionslists the codes).STRATA_ALLOWED_HOSTS:<your-app-name>.fly.dev, plus any custom domain.
Then:
# First time
fly apps create <your-app-name> # add --org <org> for an organization other than your personal one
fly deploy
# Subsequent deploys
fly deploy
The volume defined in [[mounts]] (strata_data, 5 GB auto-extending to
20 GB) is created automatically on first deploy, no separate
fly volumes create step needed.
Verify¶
After fly deploy reports success:
Expected response: exactly {"status":"ok"}. The detailed views are /health/dependencies and /health/ready. If you get a
504 or connection error, run fly logs to inspect the startup -
the most common cause is a cold-start delay on the first request.
Configuration¶
The template configures:
- VM size:
shared-cpu-4xwith 2 GB RAM - Auto-scaling: machines suspend when idle, auto-start on requests
- Persistent storage: 5 GB volume at
/home/strata/.stratawith auto-extend - Health check: HTTP on
/healthevery 15 s
Key environment variables¶
[env]
STRATA_DEPLOYMENT_MODE = "personal"
STRATA_ALLOW_REMOTE_CLIENTS_IN_PERSONAL = "true"
STRATA_ALLOWED_HOSTS = "<your-app-name>.fly.dev"
STRATA_NOTEBOOK_PYTHON_VERSIONS = '["3.12","3.13"]'
UV_PYTHON_DOWNLOADS = "automatic"
STRATA_ALLOW_REMOTE_CLIENTS_IN_PERSONAL is what lets personal-mode
bind to 0.0.0.0 instead of loopback only - without it, Strata
refuses to start on a Fly machine because the Fly proxy can't reach
a loopback bind. Setting this is the explicit acknowledgment that
you understand the personal-mode trust model (see the warning above).
STRATA_ALLOWED_HOSTS names the host browsers reach the app on.
Personal mode answers only to loopback names, IP literals and the names
listed here, which keeps DNS-rebinding pages out; a request for any
other Host gets a 400. Set it to <your-app-name>.fly.dev and add
any custom domain, comma-separated.