Skip to content

Auto-build (Railpack)

Auto-build (Railpack) lets Pier compile your project straight from a Git repository — no Dockerfile, no buildpack config, no language-specific scaffolding. Pier shells out to the Railpack CLI (Railway’s open-source builder and the active successor to Nixpacks), which talks to a moby/buildkit daemon and produces an OCI image Pier then runs like any other service.

Railpack auto-detects the project type from common marker files. Zero configuration is needed for any of these:

Language / frameworkDetected from
Node.js / Bun / Denopackage.json, bun.lockb, deno.json
Pythonrequirements.txt, pyproject.toml, Pipfile
Gogo.mod
RustCargo.toml
PHPcomposer.json
Javapom.xml, build.gradle
RubyGemfile
Elixirmix.exs
Vite / Astro / Create React Appbundler config + build output directory
  1. Clone — Pier clones the configured branch into a temp directory using the same git machinery as other Git sources (public, deploy-key or GitHub App).
  2. Detect + planrailpack build analyses the source tree and produces a BuildKit LLB graph. Unlike layered Dockerfiles, the graph is fully parallel — independent steps run concurrently, and caching is content-addressable rather than line-by-line.
  3. Build — BuildKit executes the graph against the daemon container started by install.sh, producing an OCI image tagged pier-railpack/<service-id>:<deploy-id>.
  4. Run — Pier synthesises a small docker-compose.yml pointing at the new image and hands it to the same docker compose up path used by Dockerfile builds. Traefik labels, auto-SSL, port allocation and stack networking are all reused — only the build step is new.

For projects that need overrides, drop a railpack.json at the repo root — Railpack picks it up automatically and Pier doesn’t need to know about it. Example:

{
"providers": ["node"],
"buildAptPackages": ["libpq-dev"],
"deploy": {
"startCommand": "node dist/server.js"
}
}

The full reference lives at railpack.com/configuration/file.

Three environment variables (set in the systemd unit or before install.sh) and one UI tab control Auto-build behaviour:

  • PIER_RAILPACK_MAX_PARALLEL_BUILDS=N — cap concurrent builds (default 1). Also editable from Settings → Auto-build (Railpack) in the dashboard.
  • PIER_BUILDKIT_MEMORY=4g — RAM limit for the moby/buildkit container (default 4g).
  • PIER_SKIP_RAILPACK=1 — skip provisioning entirely. The card stays in the UI but build attempts will surface a clear “railpack binary not found” message.

railpack binary not found in PATH The host was installed with PIER_SKIP_RAILPACK=1, or install.sh couldn’t download the release binary. Re-run install.sh without the skip flag, or install the binary manually from github.com/railwayapp/railpack/releases to /usr/local/bin/railpack.

build failed (exit 137) — OOM kill Your build exceeded available RAM. Either upgrade the VPS to 4 GB+ (8 GB for Rust), or constrain BuildKit with a lower PIER_BUILDKIT_MEMORY to fail-fast rather than starve neighbour processes. The Pier UI surfaces this state with a red banner when the host has less than 4 GB.

Builds stuck queued Pier caps parallel builds at 1 by default to protect the host. If multiple users deploy at once, the others wait. Raise the cap in Settings → Auto-build (Railpack) if your host has spare RAM.

Could not detect language Railpack didn’t find a marker file it recognises. Either add the expected lockfile (e.g. package-lock.json for npm projects), drop a railpack.json declaring providers, or fall back to the Dockerfile source.