Skip to main content
floo builds every service from a Dockerfile in your repo. The full set of image requirements is the container contract.

Checklist

  • Build succeeds from a clean checkout
  • Process binds to $PORT on 0.0.0.0
  • All runtime dependencies in the final image
  • CMD or ENTRYPOINT starts the service
  • One Dockerfile per service directory
  • A .dockerignore beside it, so COPY . . cannot overwrite an installed dependency tree with a committed one, or your local one in a local docker build. See Build context.

Monorepos

A service builds with its own path as the context and cannot read files above that directory. If your services share workspace packages, set dockerfile to build from the repository root. See Monorepos.

Registry caching

Use standard Docker Hub images. floo routes pulls through a regional cache with no configuration, so builds read layers from the cache instead of Docker Hub.

Layer order

Each Dockerfile instruction makes a layer. When one changes, every layer after it is rebuilt, and floo uploads and starts each rebuilt layer on every push. Order instructions from what changes least to what changes most:
  1. Copy the dependency manifest and lockfile, then install.
  2. Copy the source, then build.
  3. In the final stage, copy installed dependencies before the build output.
On floo’s starter app, copying node_modules before .next/standalone instead of after took a code-only push from 56 s to 34 s. Multi-stage, with a final stage that holds only what the service runs, and a start command that reads $PORT.

Node.js (Next.js)

Set output: "standalone" in next.config.js, then:
The standalone server reads PORT and starts faster than npm start. If the image also runs a migration tool that needs the full production node_modules, copy it before .next/standalone. The Next.js guide covers build-time variables and faster pushes.

Python (FastAPI)

The shell form is what lets $PORT expand. Flask and Django templates use the same stages with gunicorn <module> --bind 0.0.0.0:$PORT.

Go

The binary must read PORT itself and listen on 0.0.0.0.

Container contract

Every requirement an image must meet, and the diagnostic each one raises.

Build context

Which files reach the build, and how to keep large or sensitive files out.