Skip to content

duploy.toml ​

The file lives at the root of the repository (or at the config path set on the project). Unknown keys are errors. Every error is reported with its key path and line, and an invalid file is not applied at all.

toml
version = 1

[services.<name>]
# …

[databases.<name>]
# …
KeyTypeRequiredNotes
versionintegeryesAlways 1
servicestablenoService name → service
databasestablenoDatabase name → database

Names of services and databases share one namespace and must match ^[a-z][a-z0-9-]{0,31}$.

Service ​

KeyTypeDefaultNotes
type"web" | "worker" | "cron""web"
sourcetable—Required. See source.
portinteger—Required for web; not allowed for worker and cron
replicasinteger ≥ 11Not for cron; 1 when the service has a volume
commandarray of stringsimage CMD
domainsarray of tables[]web only. See domains.
healthtableby typeNot for cron. See health.
schedulestring—cron only, required there. Five fields, UTC.
timeoutdurationplatform limitcron only
resourcestableplan defaultsSee resources.
inherit_envstring—Service whose resolved env this one starts from
nodestring—Pin to a named node
envtable{}See env.
volumestable{}See volumes.
filestable{}See files.
networktable—See network.

Durations are written 30s, 5m, 1h.

source ​

Exactly one of path, repo, image, image_of.

KeyTypeDefaultNotes
pathstring"."Build context, relative to the repository root
repostring—owner/name; build from another repository
branchstringdefault branchOnly with repo
dockerfilestring"Dockerfile"Relative path
build_argstable{}path/repo only. KEY = "value" or KEY = { secret = true }. Names match ^[A-Za-z_][A-Za-z0-9_]*$.
imagestring—Image reference; no build
image_ofstring—Another service's image; not itself, no chains

path and repo sources need a project with a linked repository.

domains ​

KeyTypeDefaultNotes
hoststring—Required
pathstring"/"Must start with /
strip_prefixbooleanfalse
portintegerservice portContainer port for this domain
protocol"http1" | "h2c""http1"h2c for gRPC backends

The same host + path may appear only once across the project.

health ​

KeyTypeDefaultNotes
httpstring—Path for an HTTP GET; 2xx and 3xx pass
cmdarray of strings—Command run in the container; exit 0 passes
intervalduration10s
timeoutduration5s
retriesinteger3Consecutive failures before unhealthy

Exactly one of http and cmd. Without health, a web service is probed with a TCP connect to port and a worker is healthy after 5 seconds up.

resources ​

Also used by databases.

KeyTypeNotes
cpunumberCores
memorystring512M, 2G, 256Mi, 1GB
pidsintegerProcess limit
diskstringRoot filesystem quota; for databases, the data volume
nofileintegerOpen file limit
read_onlybooleanRead-only root filesystem, writable /tmp
runtime"runc" | "sysbox-runc" | "kata-clh"

Missing keys come from the plan defaults. Values above the plan maximum are errors.

env ​

ValueMeaning
"text"Literal
{ secret = true }Value set with duploy secret set
{ from_database = "db", property = "url" }url (default), host, port, user, password, database
{ from_service = "api", key = "TOKEN" }Variable of another service; key required

volumes ​

ValueMeaning
"/data"Mount path
{ path = "/data", size = "10G", backup = { schedule = "0 4 * * *", retain = 7 } }With quota and snapshots

Paths are absolute, not /, and unique per service. retain is at least 1.

files ​

ValueMeaning
"content"Inline content
{ content = "…", mode = "0640" }Inline content with a mode
{ from = "config/app.yml" }Repository file at the deployed commit

Keys are absolute file paths in the container, outside every volume path. ${VAR} is resolved from the service env and platform variables; $${ escapes. Limits: 64 KiB per file, 16 files, 256 KiB in total.

network ​

KeyTypeNotes
egressarray of stringsHosts, *.wildcards, IPs and CIDRs this service may reach; at most 64. Absent means unrestricted.

Database ​

KeyTypeDefaultNotes
engine"postgres" | "mysql" | "redis"—Required
versionstring—Required. "18" or "18.2". Minimum: Postgres 18, MySQL 8, Redis 7.
extensionsarray of strings[]Postgres only: pgvector, postgis, pg_cron, timescaledb
backuptable—schedule (five fields, UTC) and retain
resourcestableplan defaultsSee resources.
nodestring—Pin to a named node

A complete example ​

toml
version = 1

[services.web]
source = { path = ".", dockerfile = "Dockerfile" }
port = 8080
replicas = 2
domains = [{ host = "shop.example.com" }]
health = { http = "/healthz", interval = "10s", retries = 6 }
resources = { cpu = 1.0, memory = "1G" }

[services.web.env]
DATABASE_URL = { from_database = "db" }
REDIS_URL = { from_database = "cache" }
SESSION_KEY = { secret = true }

[services.worker]
type = "worker"
source = { image_of = "web" }
inherit_env = "web"
command = ["bin/worker"]

[services.nightly]
type = "cron"
source = { image_of = "web" }
inherit_env = "web"
command = ["bin/report"]
schedule = "0 2 * * *"
timeout = "30m"

[databases.db]
engine = "postgres"
version = "18"
extensions = ["pgvector"]
backup = { schedule = "0 3 * * *", retain = 7 }

[databases.cache]
engine = "redis"
version = "7"

Duploy — our nodes, your file.