Build types
How the platform decides whether your source is a compose project, a Dockerfile, or a Nixpacks build — and what it does when it is none of them.
Detection runs at the first deployment. It is not a setting you choose up front, though you
can override it with composePath or dockerfilePath.
The order
An operator override. If composePath or dockerfilePath is set on the
application, only that file is considered.
A compose file at the source root, in the order Compose itself looks for
them: compose.yaml, compose.yml, docker-compose.yaml,
docker-compose.yml.
A Dockerfile at the source root. The platform generates a one-service
compose file wrapping it.
Nixpacks, if enabled and the tree carries a manifest the platform recognises.
Nothing. The deployment fails with a message naming what it looked for.
Why compose wins over a Dockerfile
A tree carrying both is almost always a multi-service application whose Dockerfile is one of its services. Inferring a single-service build from it would ignore what the author already said.
COMPOSE
Your file, sanitised. Multi-service applications work; name
the service that faces traffic with exposedServiceName if the file declares more than one.
DOCKERFILE
The platform generates a one-service compose file wrapping your Dockerfile, then treats it
exactly as it would a compose project. contextPath sets the build context.
NIXPACKS
Nixpacks is the fallback, not a peer: a tree carrying its own build definition has told the platform how it wants to be built.
It is gated twice — on DEPLOY_NIXPACKS_ENABLED (on by default) and on the tree carrying one
of these at the source root:
package.json, pnpm-workspace.yaml, requirements.txt, pyproject.toml,
Pipfile, go.mod, Cargo.toml, Gemfile, composer.json, mix.exs,
build.gradle, build.gradle.kts, pom.xml, Package.swift,
project.clj, deno.json, deno.jsonc.
Nixpacks itself detects far more than this and would happily produce an image from a directory
holding one .py file. The narrower list is the gate: a tree matching none of it is much more
likely to be the wrong archive than a project whose language nobody has heard of, and "no
build definition found" is a better answer than a 400 MB image of a README.
Nixpacks runs as a pinned container mounting the Docker socket
(DEPLOY_NIXPACKS_IMAGE, default ghcr.io/railwayapp/nixpacks:v1.39.0),
never as a host binary. Turning DEPLOY_NIXPACKS_ENABLED off restores the
behaviour from before Nixpacks existed: such a tree is refused.
When detection fails
The error names both options — a compose file or a Dockerfile — and, when Nixpacks is
enabled, says that it found no manifest it recognises and lists some of the ones it looks for.