Dockerfile in your service directory and runs the image. These
are the requirements that image must meet. floo preflight checks most of them
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 and waits for a response that is not a 5xx. A service that is still booting when the window closes does not fail the deploy: the deploy still goes live, the health-check step records a warning, and thehealth_check_timeout diagnostic tells you which URL never answered. Traffic
reaches the new revision either way, so a slow boot is served as errors until
the container comes up.
Move slow work out of startup. Run migrations through migrate_command rather
than 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. The deploy’s 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. It cannot reach another
one. For service-to-service calls use the 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.
For a workspace repository that is not enough: 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. What a non-zero exit does depends
on the lane: on a dev deploy it is recorded as the migration_failed
diagnostic and the rollout continues; on a promote with no build-time env vars
in prod, the migration runs before any prod revision changes and a failure
marks the deploy FAILED with production traffic left where it was; on a promote
that rebuilds because prod has build-time env vars, a failure is only logged.
Shipping code that expects tables nothing created fails with
missing_migrate_command.
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.