Configuration
Everything gantry.toml can describe: services, build settings, environment variables and profiles for CI.
GuidesUpdated 24 Sep 20267 min read
The gantry.toml file
Gantry looks for gantry.toml in the current folder, then in each parent up to the repository root, so commands work from anywhere in the project. One file describes every service. Here is a complete one for a web app with a background worker and a database.
[project]name = "acme-web"pass_env = ["PAYMENTS_API_KEY"] # read from your shell, never stored [build]platforms = ["linux/amd64", "linux/arm64"] [service.web]build = "lockfile"command = ["pnpm", "dev"]ports = ["3000"]depends_on = ["db"]watch = ["src/**", "public/**"] [service.web.env]DATABASE_URL = "postgres://app:${DB_PASSWORD}@db:5432/app" [service.worker]build = "lockfile"command = ["pnpm", "worker"]depends_on = ["db"] [service.db]image = "postgres:17"ports = ["5432"]volumes = ["db-data:/var/lib/postgresql/data"]Services
Each [service.name] table is one container. The name is what you pass to --service, and what other services use to reach it on the project network: web connects to the database at db:5432.
| Key | Type | Description |
|---|---|---|
| build | string | A Dockerfile path, or "lockfile" to build from the nearest lockfile. |
| image | string | Run a prebuilt image instead. Can't be combined with build. |
| command | string[] | Replaces the image's default command. |
| ports | string[] | Published ports as host:container. A bare number uses the same port on both sides. |
| depends_on | string[] | Services that must be healthy before this one starts. |
| volumes | string[] | name:/path for named volumes, ./dir:/path to mount a project folder. |
| watch | string[] | Globs that trigger a rebuild on save. Defaults to the whole build context. |
Health checks
A service counts as started when its health check passes, not when its process launches. Without one, Gantry waits for the first published port to accept a connection, which is usually close enough for databases and rarely for web apps.
[service.web.health]http = "/api/health" # any 2xx countsinterval = "2s"timeout = "60s"Build settings
The [build] table applies to every service that builds. Anything set under [service.name.build] wins for that service.
| Key | Default | Description |
|---|---|---|
| platforms | host | Targets for gantry build, e.g. linux/arm64. |
| cache | ~/.gantry/layers | Where layers are kept between builds. |
| args | {} | Build arguments, available as ARG in Dockerfiles. |
| sync | "safe" | "fast" keeps the project on the VM's disk on macOS. Faster for node_modules. |
Environment variables
Set variables per service in an env table, or load them from files. Values can use ${NAME} to reference other variables, including ones from your shell listed in pass_env.
[service.web.env]DATABASE_URL = "postgres://app:${DB_PASSWORD}@db:5432/app"NODE_ENV = "development"Precedence
When the same variable is set in more than one place, the first match in this list wins:
--env KEY=valueon the command line.- Your shell's environment, for names listed in
pass_env. .env.local, then.env, in the project root.- The
envtable in gantry.toml.
.env.local, which gantry init adds to your .gitignore, or pass them through from your shell with pass_env.Profiles
A profile overrides parts of the file for one context. CI usually wants no file watching and a database that trades durability for speed.
[profile.ci]watch = false [profile.ci.service.db]image = "postgres:17-alpine"command = ["postgres", "-c", "fsync=off"]$ gantry up --profile ci -dProfiles also choose where gantry ship sends a release, so one file can describe local, CI and production.