Environment variables
Most configuration lives in the environment. Deploys.app lets you set it per-deployment, share it across deployments with env groups, and update slices of it without re-stating the rest.
Per-deployment env#
The simplest case — a map on the deployment itself.
{
"name": "web",
"image": "registry.deploys.app/acme/web:v2.4.1",
"env": {
"NODE_ENV": "production",
"PORT": "8080",
"DATABASE_URL": "postgres://…"
}
}
Whatever you pass in env replaces the entire env map on the new revision.
If you only want to nudge a couple of values, use the partial fields below.
Reusable env groups#
An env group is a named bag of variables you can attach to multiple deployments. Change the group, redeploy the deployments that use it, and they all pick up the new values.
# create or update a group (replaces its contents)
curl https://api.deploys.app/envGroup.create \
-H "Authorization: Bearer $DEPLOYS_TOKEN" \
-d '{ "project": "acme", "name": "shared",
"env": { "LOG_LEVEL": "info", "REGION": "apac" } }'
In a deployment, reference the group by name:
{
"name": "api",
"envGroups": ["shared", "secrets-staging"],
"env": { "PORT": "8080" }
}
When the container starts, the platform merges the groups (in the order
listed) and then the deployment’s own env on top. Last write wins, so the
deployment’s own env always overrides what came from a group.
Partial updates — addEnv, removeEnv#
The deployment.deploy API has four partial-update fields that operate on the
previous revision’s env instead of replacing it. Use them when you just want
to rotate a secret or add one new variable.
| Field | Effect |
|---|---|
addEnv | Map: keys added (or overwritten) on top of the previous revision’s env. |
removeEnv | List of keys: removed from the previous revision’s env. |
addEnvGroups | List of group names: appended to the previous revision’s envGroups. |
removeEnvGroups | List of group names: removed from the previous revision’s envGroups. |
# rotate one secret on web without re-stating everything else
curl https://api.deploys.app/deployment.deploy \
-H "Authorization: Bearer $DEPLOYS_TOKEN" \
-d '{
"project": "acme",
"location": "gke.cluster-rcf2",
"name": "web",
"addEnv": { "API_KEY": "new-value" }
}'
If you pass both a partial field (addEnv) and the full one (env), the
full one wins — env is treated as a complete replacement.
What ends up in the container#
At rollout time the platform computes the final env like this:
- Start with the previous revision's envOnly if you used a partial field (
addEnv/removeEnv/addEnvGroups/removeEnvGroups). Otherwise start empty. - Apply the env groupsFor each group in
envGroups, merge its current contents in order. - Apply the deployment's own env on topThe deployment’s
envmap wins over anything a group set with the same key.
The result becomes part of the new revision and is what container processes see in their environment.
Sensitive values#
Values are stored as-is, encrypted at rest, and never appear in the audit log
or in metrics. They are visible to anyone with read access to the
deployment, so make sure your roles limit who can call
deployment.get on projects that hold production secrets.
A common pattern: keep secrets in a dedicated env group per environment
(secrets-staging, secrets-prod), and grant read on those groups only to
operators and CI.