Skip to main content
Every floo app has two environments, dev and prod, plus a preview per pull request when previews are on.

The two URLs

Dev gets the clean URL because many apps never need prod. When an app does go to prod, it usually gets a custom domain. Apps created before November 5, 2026 keep their original URLs, which never change: dev at <app-name>-dev.getfloo.app and prod at <app-name>.getfloo.app. Apps created before September 29, 2026 use on.getfloo.com the same way (<app-name>-dev.on.getfloo.com and <app-name>.on.getfloo.com). A push to the default branch deploys to dev. Prod stays untouched until you publish a release.

Do you need production?

Not always. Dev gets the same runtime as production, including floo’s keep-warm and sign-in warm-up.
  • A small internal tool used by you or a few teammates can live in dev alone. Every push goes live, and there is nothing to promote.
  • An app more people rely on is better with both: push and check changes in dev, then release to prod when they are ready, so a bad push never reaches your users.

The flow

For your own GitHub repo, publish a GitHub release with the command above or the GitHub UI. floo deploys the release’s commit to prod once that commit is LIVE in dev. Without --target, gh release create tags the default branch’s latest commit; if that commit is not yet live in dev, the release waits and then fails. To release exactly what you verified, pass the dev deploy’s commit, which floo deploys status --app my-app --json reports as commit_sha:
For a floo-hosted project created with floo projects, run floo releases promote --app <name> [--tag <tag>]. It deploys the latest LIVE dev deploy to prod, then publishes a GitHub release on the repo floo hosts. An app with no repo uses the same command; it deploys to prod without publishing a release. See Releases. A promote reuses the dev image, with one exception: when the prod environment has any env var prefixed VITE_, NEXT_PUBLIC_, or REACT_APP_, floo rebuilds the same commit from archived source with the prod build args, so the prod bundle carries prod values.

App config across environments

access_mode applies to every environment by default, and each environment can override it:
Each environment has its own access mode: [environments.<env>] access_mode overrides [app] access_mode for dev, prod, or preview, and a dev deploy never changes prod. See App sign-in for when a change applies and how an approval policy affects loosening access. An [environments.<name>] table with a name other than dev, prod, or preview fails the deploy when it sets access_mode or edge; otherwise the deploy ignores it with an unknown_manifest_key warning. Per-environment edge policy goes under [environments.dev.edge] and [environments.prod.edge]. See the config spec for its fields.

Per-environment resources

[resources] applies to every environment. [environments.<env>.resources] changes cpu, memory, min_instances, or max_instances for one environment, so prod can stay warm while dev and previews scale to zero:
Each deploy uses the values for the environment it deploys into, and a release to prod uses prod’s values. See the config spec for the rules.

Per-environment env vars

Set an env var for only one environment with --env:
Scope every secret or key that differs between test and live systems this way. A prod change takes effect with the next prod release. --restart and floo redeploy only target dev. To apply a prod change now, for example after rotating a leaked key, publish a new release (the flow).

Releases and rollbacks

How promote flows work, and how to roll back production when you need to.

Environment variables

Full scoping rules: app, service, environment.