Skip to content

Build settings

How Cloud picks a build type and commands for a repository, and how to change them.

Updated

A service built from a GitHub repository has a build type, up to three commands, and a directory in the repository to build in. Cloud reads the repository to fill these in, and every one of them can be changed on the Source card of the service's Overview section.

Builds run on a shared build server, separate from the machines your services run on. The first lines of a build log say so. The only time limit Cloud puts on a build is the two-hour ceiling on a whole deployment, which Deployments explains.

Build types

Build with offers four, named as the builders name themselves:

Build withWhat it does
nixpacks"Reads the repository and builds it without a Dockerfile." The default.
Dockerfile"Builds the Dockerfile at the top of the build path."
railpack"Reads the repository the way railpack does."
Static site"Serves what the build wrote, with no server of its own." See Deploy a static site.

How Cloud chooses

When you pick a repository and a branch on the create form, Cloud lists the repository's top directory and takes the first match:

The directory holdsBuild withThe line under the field
DockerfileDockerfileFrom the repository: a Dockerfile, which the build runs as it is written.
railpack.jsonrailpackFrom the repository: a railpack.json.
package.jsonnixpacks, with commands filled inFrom the repository: package.json, with pnpm. (or Yarn, Bun, npm)
index.html, and none of the aboveStatic siteFrom the repository: an index.html and nothing to build.
Anything elsenixpacksFrom the repository: nixpacks reads the repository and builds what it finds.

Reading the repository never blocks you. If Cloud cannot read it, the field stays empty and you choose.

If you choose a different build type yourself, your choice is used, and commands Cloud read for another builder are not sent with it: a repository read as nixpacks with npm commands, switched to Dockerfile, is created with no npm commands.

Node projects

For a package.json, the lock file in the same directory names the package manager, and the scripts in package.json name the commands:

Lock fileInstall commandScripts run with
pnpm-lock.yamlpnpm install --frozen-lockfilepnpm run
yarn.lockyarn install --frozen-lockfileyarn run
bun.lockb or bun.lockbun installbun run
package-lock.jsonnpm cinpm run
None of thesenpm installnpm run

A build script becomes the build command, such as pnpm run build, and a start script the start command. A script the file does not have leaves its command empty for nixpacks to work out. Cloud fills these in because nixpacks on its own runs npm against a pnpm lock file, which is the mistake most worth preventing.

The Source card

The card reads "What this service is built from, and what makes it build again. A change here is read at the next deploy." Which fields it shows depends on Build with:

FieldShown forWhat it is
Install commandnixpacks"Run before the build. Empty leaves nixpacks to work it out."
Build commandnixpacks"Run to build. Empty leaves nixpacks to work it out."
Publish directoryStatic site"Where the build wrote what is served, under the build path."
Start commandevery build typeWhat the container runs. For nixpacks it is also what nixpacks builds in.
Build pathevery build type"The directory in the repository the build runs in. Empty is its root."

Deploy on and Watch paths are on the same card; Source and deploy triggers covers them. Press Save source to keep your changes.

A field that does not belong to the chosen builder is hidden rather than cleared, so switching to Dockerfile and back to nixpacks before you save gives you your nixpacks commands back.

Read the repository again

Changing Repository or Branch on the card makes Cloud read the new one and fill Build with, the commands and Publish directory from it, over what the fields held. The round arrow button in the card's corner, labelled "Read the repository again", does the same for the repository already chosen, using the Build path in the field. Nothing is saved until you press Save source. If Cloud cannot read the repository, the fields keep what they had.

Commands

A command is one line of at most 500 characters. An empty command leaves the choice to the builder or the image.

Set a start command when package.json has none

nixpacks settles the start command while it builds. A Node repository whose package.json has no start script fails the build with "No start command could be found" before any container exists. Set Start command, such as npm run start, save, and deploy again.

The start command is split on spaces and run directly, with no shell, so quotes, pipes, redirections and && reach the program as literal words. A container that needs several steps at boot should run a script from the repository instead.

For a nixpacks build, Cloud passes the three commands to the build through its environment, as NIXPACKS_INSTALL_CMD, NIXPACKS_BUILD_CMD and NIXPACKS_START_CMD, without writing them into the environment you edit. If your own environment already sets one of those names, yours is used. Other build types are sent none of them.

Build path

For a repository that holds more than one application, set Build path to the application's directory, such as apps/web. The build runs there, a Dockerfile is read from there, the publish directory is counted from there, and Cloud looks for an environment template there first. A path is written from the repository's root: apps/web, /apps/web and /apps/web/ are the same path. A path is at most 255 characters, and one holding .. is refused with "A build path names a directory in the repository, such as /apps/web."

  • apps
    • web
      • package.json
      • pnpm-lock.yaml
    • api
      • Dockerfile

In this repository, one service with the build path apps/web builds with nixpacks and pnpm, and a second with apps/api builds from its Dockerfile. Give each watch paths so that a push to one does not rebuild the other.

When changes apply

Build settings are read at the next deploy, so saving one does not touch what is running. Start command is the exception: it is what the container runs rather than how it was built, so saving a new one restarts a running service with it at once, whatever the card's own line says.