Builders

Choose how Dekka builds a service from GitHub with Railpack, a Dockerfile, a static site build or Cloud Native Buildpacks.

Updated 4 November 2026

A service deployed from GitHub is built into an image before it runs, and its Builder decides how. You choose one when you create the service, and you can change it later under Settings, then Build. Services that run a Docker image aren't built, so they have no builder.

Which builder should I use?

Builder Choose it when
Railpack Your repository is an app in a common language and has no Dockerfile. It's the default.
Dockerfile Your repository has a Dockerfile you want Dekka to build as it is.
Static Your build writes a folder of HTML, CSS and JavaScript, such as a Vite, Astro or Docusaurus site.
Buildpacks Your app already builds on Heroku or with Paketo buildpacks.

Each builder keeps its own settings, so switching to another and back leaves what you set for the first one in place.

Railpack

Railpack looks at the repository, works out the language and framework, and builds an image without a Dockerfile. It recognises Node.js, Bun, Deno, Python, Go, Ruby, PHP, Rust and Elixir projects, including frameworks such as Next.js, Django, Rails and Phoenix.

When the detected commands aren't right, set Build command, such as npm run build, and Start command, such as npm start or uvicorn main:app --host 0.0.0.0 --port $PORT. Empty commands use what Railpack detects. Services created before Railpack had its name used Automatic, which is the same builder, and the API still accepts auto and stores it as railpack.

Dockerfile

Dekka builds the Dockerfile in your repository with BuildKit.

Setting What it does Default
Dockerfile The Dockerfile's path, relative to the root directory Dockerfile
Build context The directory sent to the build, relative to the root directory .
Target stage The stage to stop at in a multi-stage Dockerfile the last stage
Build arguments KEY=value pairs passed as --build-arg, one per line none

Paths must stay inside the repository, so they can't start with / or contain ... A service can have up to 50 build arguments. Their values are never printed in the build log, and the service's variables are available as build arguments too, so a secret your build needs can live there instead.

The image's own CMD starts the service unless you set a Start command.

Static

The static builder runs your Build command, if you set one, and then serves the Publish directory the build writes, which is dist by default. Leave the build command empty to serve the repository's files as they are.

Turn on Single-page app for a site with client-side routing, so a path with no file of its own answers with index.html and the route loads in the browser. A static site is always a web service, it's served on port 80, and it runs no process of its own, so it has no start command.

Buildpacks

Cloud Native Buildpacks detect your language and build the image the way Heroku and Paketo do, so an app that already builds there builds the same way on Dekka. Builder image chooses which builder picks the buildpacks.

Builder image Value
Heroku heroku/builder:24, the default
Paketo paketobuildpacks/ubuntu-noble-builder

A Procfile or the buildpack's detection decides the start command unless you set one.

Set the builder in a config file

A dekka.toml or dekka.json in the service's root directory can set the builder and its settings in the build section, using these names.

Setting Name
Builder strategy, one of railpack, dockerfile, static or buildpacks
Dockerfile dockerfile_path
Build context dockerfile_context
Target stage dockerfile_target
Build arguments build_args, a table of strings
Publish directory static_publish_dir
Single-page app spa_fallback
Builder image buildpacks_builder
[build]
strategy = "dockerfile"
dockerfile_path = "docker/api.Dockerfile"
dockerfile_target = "runner"

[build.build_args]
NODE_ENV = "production"

In the API, the same names are fields of a service's spec.build.

Workers and scheduled jobs

A worker or scheduled job has no port, so it can't use the static builder. A worker built from a Dockerfile, or one that runs a Docker image, starts with the image's own command, so its Start command is optional. Railpack and Buildpacks workers, and every scheduled job, need a start command, because there's nothing else to tell Dekka what to run.