Environments: per-environment deploys
Ship the same project to several places (production, a staging copy, a throwaway dev slice). Each
environments entry is a partial override that deep-merges onto the base;
drift file apply <env> selects one and deploys it into that environment's own
slice.
Each environment needs its own slice, and you make them yourself.
prod and production apply to the bare
slice, and every other environment applies to <slice>-<env>. That
slice has to already exist — create each one in
the slice's shape before deploying to it, because applying against a
slice that is not there is refused. An override cannot set slice.
So a project with prod and staging is two slices,
links and links-staging, each shaped and priced on its own. They are
separate in every sense: their own data, their own URL, their own bill.
slice: links # prod → the slice "links"
atomic:
functions:
- route: shorten
method: post
handler: PostShorten
backbone:
nosql:
- slot: links
environments:
prod: {} # inherits the base unchanged
staging: # → the slice "links-staging"
backbone:
nosql: # re-declaring REPLACES the base list
- slot: links
seed: ./backbone/demo.jsonl # staging gets demo rows
dev: {} # → the slice "links-dev"
An override accepts the same sections as the base (atomic, backbone,
canvas, domains), and it may not set slice.
The capacity keys it also still accepts are ignored wherever they appear, base or override, so an
environment can no longer differ in a limit — that difference lives in the two slices' own
shapes.
How the merge works
The overlay is a deep merge of the document, and it has exactly two rules:
- Maps recurse. Setting
atomic.egressleaves the rest ofatomicalone. - Everything else replaces, lists included. A list in an override is the whole list; there is no element-wise merge.
Presence is the signal, not truthiness, and that is what lets an environment express
wildcard: false on a domain and have it stick.
A resource list is shared only while an environment stays silent about it.
staging exactly one collection entry, the seeded one: re-declaring
backbone.nosql replaced the base list wholesale. Leave a list out to inherit it; write it
out and you own all of it. Run drift file explain --env staging to see the result before
you deploy.
- The slice is derived, and has to exist:
sliceforprod/production,slice-<env>otherwise. Each is separately shaped, separately priced, and made withdrift slice createbefore its first deploy. - Config lives here; secrets that differ per environment live in
.env.<env>.${ENV}binds to the selected environment. - An environment name takes the same identifier shape as a slice name.
This is not a CI pipeline: there is no “deploy staging, test, promote prod” orchestration in the Driftfile. Drift gives the verb; your CI chains it.