Dockerfile and runs the image, which must meet the
requirements below. floo preflight checks the ones it can verify statically
before you push.
Bind $PORT on 0.0.0.0
floo sets PORT in the environment and routes to it. A fixed port or a bind to
127.0.0.1 makes the container unreachable and the deploy fails with
port_mismatch.
Answer at your route root within 60 seconds
After each deploy, floo polls every routed service at its own path-prefixed URL for up to 60 seconds, waiting for any response that is not a 5xx. A service still booting when the window closes does not fail the deploy: the deploy goes live, the health-check step records a warning, and thehealth_check_timeout
diagnostic names the URL that never answered. Traffic reaches the new revision
either way, so a slow boot serves errors until the container is up.
Move slow work out of startup, and run migrations through migrate_command,
not on boot.
/healthz is reserved
The serving edge upstream of floo’s gateway answers that exact path with a 404
before the request reaches the gateway or your container. A handler bound to it
is unreachable. Use /health or /livez. Deploy config validation reports a
/healthz route in your source as the reserved_path_healthz diagnostic.
Thread build args into the build
A build arg is not an environment variable. Forward it in the same stage, before the build step, or the value is empty at build time and bakesundefined into
your bundle.
NEXT_PUBLIC_*, VITE_*, or REACT_APP_* to
the build as a build arg and also injects it at runtime. Set them with
floo env set; there is no separate build-arg flag or config key. See
Build-time variables.
No unguarded localhost fallbacks
Inside a deployed service,localhost is that service and cannot reach another
one. For service-to-service calls use an injected discovery variable such as
API_URL, or a relative gateway path such as /api. Keep any local default
behind an explicit development-only guard.
Know which directory is your build context
By default the build context is the service’s ownpath, and the Dockerfile
must sit inside it. A service at path = "./api" builds with ./api as its root
and cannot read files above it.
In a workspace repository, a service at ./apps/web cannot reach a sibling
packages/, so pnpm install cannot resolve workspace:*. Set dockerfile to
move the context to the repository root:
floo.app.toml partial
COPY paths in that Dockerfile are then written from the root. See
Monorepos.
Run migrations through migrate_command
Set migrate_command on the service that owns the schema. floo runs it as a
one-off job against the target environment before shifting traffic to the new
revision. Push deploys, CLI promotion, and GitHub-release promotion all stop on
migration failure and leave the previous live revision serving. An explicitly
requested floo redeploy --rebuild --skip-migrations skips this step.
The old revision can serve the migrated schema until cutover, or longer if
rollout fails. Use expand-then-contract migrations
and keep both versions compatible. floo does not undo database writes from a
failed migration. Source checks report missing_migrate_command when migration
files exist without a configured command; that warning does not run them.
Keep the build small
Builds run with bounded memory and fail withbuild_oom when they exceed it. Use
multi-stage builds and copy only the built output into the final stage.