Skip to content

paas.toml Schema

paas.toml is an optional file at the root of your repo that lets you override defaults for build, deploy, processes, environments, cron, addons, and domains. PaaS reads it on every git push paas main.

Quick example

[app]
name = "hello-paas"
plan = "starter"
region = "fr-par-1"

[build]
buildpack = "paketo-buildpacks/nodejs"
nodejs_version = "20"
cache = true

[deploy]
strategy = "canary"
canary_steps = [10, 25, 50, 75, 100]
healthcheck_path = "/healthz"
healthcheck_timeout = 30

[[processes]]
name = "web"
command = "node server.js"
cpu = "500m"
memory = "256Mi"
replicas_min = 1
replicas_max = 5
hpa_target_cpu = 70

[[processes]]
name = "worker"
command = "node worker.js"
cpu = "250m"
memory = "128Mi"
replicas_min = 1
replicas_max = 1

[env]
NODE_ENV = "production"
LOG_LEVEL = "info"

[[addons]]
type = "database"
plan = "standard"
name = "my-db"

[[addons]]
type = "valkey"
plan = "micro"
name = "my-cache"

[cron]
nightly_report = { schedule = "0 2 * * *", command = "node scripts/report.js" }

[domains]
custom = ["www.example.com", "example.com"]

[app] — top-level metadata

Field Type Default Description
name string repo name App identifier — visible in URLs and CLI
plan enum free free | starter | pro | enterprise
region string fr-par-1 Deploy region

[build]

Field Type Default Description
buildpack string auto-detect Force a Paketo buildpack
nodejs_version string latest LTS Override Node.js version
python_version string 3.12 Override Python version
go_version string 1.22 Override Go version
ruby_version string 3.3 Override Ruby version
java_version string 17 Override JDK version
cache bool true Reuse buildpack layer cache

[deploy]

Field Type Default Description
strategy enum rolling rolling | canary | blue_green
canary_steps list[int] [10, 25, 50, 100] Traffic % per canary step (only if strategy = canary)
healthcheck_path string / Path probed before sending traffic
healthcheck_timeout int 30 Seconds before failing deploy
release_timeout int 300 Max seconds for release process

[[processes]] — process types (TOML array of tables)

Field Type Default Description
name string required Process name (web, worker, release, cron-*)
command string from Procfile Override the command
cpu string 100m CPU request and limit
memory string 128Mi Memory request and limit
replicas_min int 1 HPA lower bound
replicas_max int 1 HPA upper bound (= replicas_min ⇒ no HPA)
hpa_target_cpu int 70 HPA scale-up trigger (% CPU)

The web process automatically receives a Service and is exposed on <app>.runtime.di2amp.com. Other processes (worker, release, cron-*) are network-isolated.

[env] — non-sensitive config

[env]
NODE_ENV = "production"
LOG_LEVEL = "info"
SENTRY_DSN = "https://..."

These end up as plain env vars. For secrets, use paas secrets:set instead.

[[addons]] — managed services

Field Type Description
type enum database (postgres) | valkey | opensearch
plan enum free | starter | standard | pro
name string Local alias for the addon

Each addon injects connection details as env vars (e.g. DATABASE_URL).

[cron] — scheduled jobs

[cron]
nightly = { schedule = "0 2 * * *", command = "node scripts/cron.js", timezone = "UTC" }
Field Type Default Description
schedule string required crontab format (min hour dom mon dow)
command string required Command to run
timezone string UTC IANA timezone (e.g. Europe/Paris)
concurrency_policy enum Forbid Allow | Forbid | Replace

[domains]

Field Type Description
custom list[string] Custom domains attached to web

cert-manager auto-issues Let's Encrypt certs once DNS validates.

[environments.preview] — preview env overrides

[environments.preview]
DEBUG = "true"
LOG_LEVEL = "debug"

These override [env] only for branch-based preview environments (non-main pushes).

Full example by language

[build]
nodejs_version = "20"

[[processes]]
name = "web"
command = "node server.js"
cpu = "500m"
memory = "256Mi"
[build]
python_version = "3.12"

[[processes]]
name = "web"
command = "gunicorn config.wsgi --workers 3"
cpu = "500m"
memory = "512Mi"

[[processes]]
name = "worker"
command = "celery -A config worker --loglevel=info"
cpu = "1"
memory = "1Gi"

[[processes]]
name = "release"
command = "python manage.py migrate --no-input"
[build]
buildpack = "paketo-buildpacks/go"

[[processes]]
name = "web"
command = "./web"
cpu = "200m"
memory = "64Mi"

[[processes]]
name = "worker"
command = "./worker"
cpu = "1"
memory = "256Mi"
[build]
ruby_version = "3.3"

[[processes]]
name = "web"
command = "bundle exec puma -C config/puma.rb"
cpu = "500m"
memory = "512Mi"

[[processes]]
name = "worker"
command = "bundle exec sidekiq"

[[processes]]
name = "release"
command = "bundle exec rails db:migrate"

Validation

paas validate checks paas.toml syntax + values against the schema without triggering a deploy:

$ paas validate
 paas.toml is valid
  - 2 processes (web, worker)
  - 1 addon (database)
  - 1 cron job (nightly)

See also