Config as code

Keep a service's settings in dekka.toml or dekka.json next to its code, and describe a whole environment in a dekka.yaml blueprint.

A dekka.toml or dekka.json in a service's root directory sets its build and runtime settings from the repository. Dekka reads the file from the commit being deployed, so a settings change can go through code review with the code that needs it.

Write a config file

The file has two sections, build and runtime, and accepts the names listed in Build and deploy settings without their prefix.

[build]
build_command = "pip install -r requirements.txt"
start_command = "uvicorn main:app --host 0.0.0.0 --port $PORT"
pre_deploy_command = "alembic upgrade head"
watch_paths = ["api/**"]

[runtime]
health_check_path = "/healthz"
memory_mib = 512

The same settings in JSON look like this, and a $schema key is ignored if you add one for your editor.

{
  "build": { "pre_deploy_command": "python manage.py migrate --noinput" },
  "runtime": { "health_check_path": "/health/", "port": 8000 }
}

Which value wins?

A setting in the file overrides the same setting in the service's dashboard settings, for every deployment of a commit that contains the file. Settings the file leaves out keep their dashboard values, and settings set in neither place use their defaults. Removing a line from the file hands that setting back to the dashboard on the next deploy.

The file only applies to services deployed from GitHub. An image service has no repository to read it from.

See where a deployment's settings came from

In Deployments, a deployment that used a config file shows a line such as "3 settings came from dekka.toml in the repository", which opens to list each setting. The API returns the same information for every setting in config_sources, with one of dekka.toml, dekka.json, service settings or default, and the merged result in effective_spec.

What if the file is wrong?

Dekka checks the file before anything is built, and an unknown section or setting, a value out of range or a file it can't parse fails the deployment with invalid_config and a message naming the problem, such as dekka.toml is invalid: runtime.memory_mib Input should be less than or equal to 16384. The release that is serving keeps serving.

A few other cases fail the same way. A root directory can hold only one of the two files, and a file can't change how a service runs, so a cron_schedule in a web service's file is an error. A value over your plan's limit, such as replicas = 4 on Starter, fails the deployment with entitlement_exceeded.

Describe a whole environment in dekka.yaml

A dekka.yaml blueprint describes an environment's services, databases, buckets, variables and connections in one file. Choose Add, then Template or dekka.yaml, and either pick one of Dekka's templates, such as Next.js with Postgres or FastAPI with Postgres and Redis, or paste your own under dekka.yaml and choose Plan blueprint. Dekka shows everything it would create or change, and nothing exists until you deploy the plan from the same dialog.

version: 1
name: Next.js with Postgres
variables:
  SENTRY_DSN: https://…
resources:
  - name: web
    kind: application
    spec:
      source: { repo_full_name: acme/storefront, branch: main }
      runtime: { port: 3000 }
    variables:
      NODE_ENV: production
      SENTRY_DSN: ${{shared.SENTRY_DSN}}
  - name: db
    kind: postgres
    spec: { version: "16", storage_mib: 100 }
connections:
  - { from: web, to: db }

Each resource's spec takes the same settings as the API, top-level variables become shared variables, and connections join a service to a database or bucket by name. Dekka reads a blueprint only when you paste it or send it to the API, never from the repository.

With the API, POST /v1/blueprints/validate checks a blueprint and lists every problem with its path, and POST /v1/environments/{id}/blueprint/plan compares it with the environment and returns the plan as a changeset, which you deploy with POST /v1/changesets/{id}/deploy. A plan only deletes what the blueprint leaves out when you send "prune": true, and a plan answers 409 plan_stale if the environment changed after it was made.