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.

NoteEnv groups are scoped to the project. The same group name in a different project is a different 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.

FieldEffect
addEnvMap: keys added (or overwritten) on top of the previous revision’s env.
removeEnvList of keys: removed from the previous revision’s env.
addEnvGroupsList of group names: appended to the previous revision’s envGroups.
removeEnvGroupsList 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:

  1. Start with the previous revision's envOnly if you used a partial field (addEnv / removeEnv / addEnvGroups / removeEnvGroups). Otherwise start empty.
  2. Apply the env groupsFor each group in envGroups, merge its current contents in order.
  3. Apply the deployment's own env on topThe deployment’s env map 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.