npx create-next-app@latest) to a live app at https://<app>.getfloo.app, with managed Postgres, signed-in users, and your own domain.
New to floo? Start with the Quickstart.
1. Add a Dockerfile
Configure standalone output, which makes a much smaller container:next.config.js
Dockerfile
2. Build-time env vars (NEXT_PUBLIC_*)
Any NEXT_PUBLIC_* variable your code references is baked into the JS bundle at build time, not read at runtime. floo passes every env var whose name starts with NEXT_PUBLIC_, VITE_, or REACT_APP_ to the image build as a Docker build arg, and injects it at runtime too. Two things have to line up.
First, once step 4 has created the app, set the value as an ordinary env var. The name prefix is what makes it a build arg; no extra flag is needed.
ARG makes Docker accept the value; ENV puts it in process.env for next build.
Dockerfile
undefined baked in. The build step records a diagnostic when a build-time var is passed but not threaded into the stage that runs next build.
Env vars are per environment (--env dev is the default). A promote rebuilds the image with prod’s values whenever prod has any NEXT_PUBLIC_/VITE_/REACT_APP_ var, and otherwise reuses the dev image with the dev values baked in. When the values differ, set the var in prod too. The prod environment exists after the first promote; promote again to rebuild with the prod value:
/api/...) avoid the question entirely. See Container contract and Environment variables.
3. Initialize the floo config
Install the CLI and sign in:curl -fsSL https://getfloo.com/install.sh | bash, then floo auth login. An agent can run the same journey over the HTTP API instead, starting from getfloo.com/agents.md.
floo.app.toml
migrate_command under [services.web]. It runs as a one-off job with the new image before traffic
moves to it. A failed migration stops the deploy. Use
expand-then-contract migrations
to keep the schema compatible with both old and new code.
4. Connect the repo and deploy
floo builds from GitHub, not local files, so push first.floo apps github connect needs the floo GitHub App on the account that owns the repository, and opens a browser to install it if it is missing.
Your Next.js app is live at
https://my-nextjs-app-dev.getfloo.app.Every git push origin main ships to dev. floo releases promote --app my-nextjs-app publishes to https://my-nextjs-app.getfloo.app.5. Add a Postgres database
floo.app.toml
DATABASE_URL is injected into the runtime. Configure your database client to read it. For Prisma, follow the configuration for your installed Prisma version.
Next.js standalone output does not automatically include the Prisma CLI, schema, or migration files. Include those in the runtime image and generate the client during the build before setting migrate_command = "npx prisma migrate deploy". The command must run from the packaged dependencies without downloading tools at deploy time.
File storage
Add[managed.uploads] with type = "storage", attach storage:uploads, and deploy. Configure the client in a server route; see Cloud storage for paygo restrictions and file operations. Keep keys server-side.
6. Add per-user auth
Setaccess_mode = "accounts" and floo handles sign-in:
floo.app.toml
- Redirects unauthenticated requests to a hosted login page.
- Validates the session cookie on every request.
- Injects identity headers into every request that reaches your Next.js app.
app/dashboard/page.tsx
floo dev --fixture-user (see section 8) or hit your dev server with curl -H 'X-Floo-User-Email: you@example.com'. Access modes and identity headers in full: Auth.
7. Add a custom domain
Declare the domain infloo.app.toml:
show prints, then watch
activation:
Host and X-Forwarded-Host from the request, so it needs no extra config. DNS setup and troubleshooting: Custom domains.
8. Local development with dev credentials
dev_command locally with DATABASE_URL and readable env vars from the app’s dev environment: a real connection to your dev Postgres, with no credentials in your shell history. Write-only secrets are withheld; supply separate local values when needed. Prod credentials never reach a local session.
To test signed-in flows, add --fixture-user:
floo dev then puts a proxy in front of each accounts-mode service that injects the same X-Floo-User-* headers floo’s gateway adds in production. The output table shows the raw service URL and the auth-proxied URL; use the auth-proxied one for any path that reads identity headers.
Common gotchas
/healthzis reserved. floo’s edge intercepts that exact path. Use/healthor/livez.HOSTNAME=0.0.0.0. Next.js standalone defaults tolocalhost, which floo cannot reach.NEXT_PUBLIC_*build args. Set them withfloo env setand thread them through the build stage asARGplusENV, or the bundle hasundefinedbaked in.output: "standalone"innext.config.js. The Dockerfile above assumes standalone output. Without it, the build artifact is much larger and theCOPY --from=build /app/.next/standaloneline fails.- A
.dockerignorelistingnode_modules.COPY . .runs after the clean install is copied in, so without one your localnode_modulesoverwrites it.
What’s next
Auth, full reference
Identity headers, access policies, and access modes in detail.
Multi-service routing
Deploy Next.js alongside a FastAPI or Express backend with shared origin.
Environment variables
Build-time vs runtime env vars, secrets, and per-service scoping.
Custom domains
DNS, verification, multi-service routing.