Builds
Every deployment of a Git-backed site starts with a build. Falak builds once per deployment, on a builder, and ships the result to every server. Your app servers never compile code, install Composer packages or run npm install.
Where builds run
Section titled “Where builds run”| Builder | How you get it | Build modes |
|---|---|---|
| Control plane builder | The builder service of every installation (falak-builder serve, name control-plane) |
native only by default (FALAK_LOCAL_BUILDER_MODES=native) |
| Builder server | A server of type builder. falak-builder is installed automatically when it finishes provisioning. |
native and docker (with Docker installed) |
| External builder | Created under Settings → Builders; run falak-builder serve --url … --token … anywhere |
Organization-scoped |
A builder long-polls GET /api/internal/builds/next and takes the next job it is eligible for (organization and build mode). See Builders.
Build modes
Section titled “Build modes”| Mode | API value | Output | Used by |
|---|---|---|---|
| Native | native |
A deterministic tar.gz release (for example vendor/, node_modules/, built assets) |
PHP, Node, Bun, Deno and static sites (default) |
| Docker | docker |
An image pushed to Falak’s registry: <registry>/<namespace>/<site-slug>:<build-id> |
Docker and Compose sites |
| On server | on-server |
Not supported yet: deployments fail fast with a clear error |
Stack detection (native builds)
Section titled “Stack detection (native builds)”The builder inspects the repository root and picks the first match:
| Found | Stack | Steps |
|---|---|---|
composer.json |
PHP (Laravel when laravel/framework is required and artisan exists) |
composer install --no-dev --optimize-autoloader --no-interaction --prefer-dist --no-progress; then, if package.json has a build script, install JS dependencies and run build with NODE_ENV=production. node_modules is not shipped. |
deno.json / deno.jsonc |
Deno | deno install (--frozen with deno.lock); deno task build if defined |
package.json |
Node or Bun | Install, build script if present, prune dev dependencies |
index.html |
Static | none |
public/index.html |
Static (output public) |
none |
Package manager (Node): packageManager in package.json, else bun.lock/bun.lockb → bun, pnpm-lock.yaml → pnpm, yarn.lock → yarn, else npm.
| Package manager | Install | Prune |
|---|---|---|
| npm | npm ci --include=dev (with a lockfile), else npm install --include=dev |
npm prune --omit=dev |
| pnpm | pnpm install --frozen-lockfile |
pnpm prune --prod |
| yarn classic | yarn install --frozen-lockfile |
yarn install --production … |
yarn berry (.yarnrc.yml) |
yarn install --immutable |
(keeps all dependencies) |
| bun | bun install (--frozen-lockfile with a lockfile) |
bun install --production |
Versions are read from your project: PHP from config.platform.php or require.php in composer.json; Node from your version files or engines; Bun from packageManager.
Static output: Vite (dist), Create React App (build) and Astro (dist, unless @astrojs/node is installed) produce static sites when there is no start script. With the static runtime, the first existing of dist, build, out, public is used.
When Railpack is installed on the builder, its detection enriches the plan (versions, start command).
Overriding install and build commands
Section titled “Overriding install and build commands”Set these site variables to replace the detected steps (both run with sh -c):
| Variable | Replaces |
|---|---|
FALAK_INSTALL_COMMAND |
The dependency install step |
FALAK_BUILD_COMMAND |
The build step |
FALAK_INSTALL_COMMAND=pnpm install --frozen-lockfile --filter web...FALAK_BUILD_COMMAND=pnpm --filter web buildSee Monorepos and build commands.
Build-time variables
Section titled “Build-time variables”Builds do not see all your site variables. They see:
- variables whose names start with a public front-end prefix:
VITE_,NEXT_PUBLIC_,NUXT_PUBLIC_,PUBLIC_,REACT_APP_; - variables you expose to the deploy script (a per-variable opt-in in the Variables editor), for other build-time settings such as Astro’s
SITE_URL.
${{ service.KEY }} references in those variables are resolved before the build.
What is excluded from artifacts
Section titled “What is excluded from artifacts”.git, .DS_Store, /.env, /.env.*.local, /.falak-build, Thumbs.db and /storage/logs/* (except storage/logs/.gitignore) are never shipped. PHP builds also exclude /node_modules.
Docker builds
Section titled “Docker builds”For docker mode, the builder chooses a Dockerfile in this order:
- The Dockerfile path set on the site.
Dockerfilein the repository root.- A Railpack build plan, when Railpack is available.
- A Dockerfile generated for the detected stack (printed in the build log).
Images are built with BuildKit and pushed to the built-in registry. Images no build or release needs any more are deleted daily, and a weekly garbage collection frees their layers.
Caching and limits
Section titled “Caching and limits”| Setting | Default | Variable |
|---|---|---|
| Build timeout | 1800 s | FALAK_BUILD_TIMEOUT |
| Queued build expires if no builder takes it | 3600 s | FALAK_BUILD_QUEUE_TTL |
| Running build fails without a builder heartbeat | 90 s | FALAK_BUILD_HEARTBEAT_TIMEOUT |
| Artifacts kept per site | 10 | FALAK_ARTIFACTS_KEEP |
| Artifact maximum age | 90 days | FALAK_ARTIFACTS_MAX_AGE_DAYS |
| Maximum artifact size | 4 GiB | FALAK_ARTIFACTS_MAX_BYTES |
| Build log retention | 30 days |
Package-manager and BuildKit caches persist in the builder’s cache directory between builds. Clone credentials are fetched when a job is handed out and never stored.
If a builder restarts mid-build, the build fails with “Builder <name> restarted during the build.” instead of hanging.