# Environments and variables

> Give production, previews and development their own variables, share them across deployments with env groups, and import or export a .env file.

Source: https://www.coritan.com/docs/managed-containers/environments-and-variables/

In the dashboard:

- /dashboard/deployments/…/environment: https://www.coritan.com/dashboard/deployments

A web service, a static site or a hybrid site reads its settings from variables, such as a database address or an API key. Each deployment keeps its variables per *environment*, so production and previews can use different values, and *env groups* share one set of variables across several deployments. You set them on the deployment's **Environment** tab. A game server or a database keeps its settings as startup variables instead ([Server settings](/docs/managed-containers/settings/)).

## How a release finds its values {#how-a-release-finds-its-values}

A deployment has four environments:

`production`
: What production releases read.

`preview`
: What previews read ([Turn on previews](/docs/managed-containers/deploy-from-git/#turn-on-previews)). A preview variable can also name a branch, and then only that branch's previews read it.

`development`
: What you run on your own computer. `coritan env pull` writes these values to `.env.local` ([The Coritan CLI](/docs/managed-containers/cli/)).

`all`
: Every environment, unless it has a value of its own.

When a key has several values, a release takes the first of these that exists: the value for its branch, then the value for its environment, then the `all` value, then the env groups linked to the deployment, in the order they were linked, and last the [bindings](#bindings).

Each variable also says where it is read: by the build, by the running instances, or by both. A variable the build reads, such as a public API address that a static site bakes into its pages, needs the build to run again before it changes anything.

## Add or change a variable {#add-a-variable}

1. Open the deployment and select the **Environment** tab.
2. Choose the environment, and for a preview variable the branch, if it is for one branch only.
3. Add the key and its value, and say whether the build, the running instances or both read it. A new variable is secret unless you say it is not.
4. Save. The deployment shows **Your changes apply with the next release**. Select **Redeploy…** to start one now. When a build-time variable changed, keep **Build it again** ticked.

A key uses upper-case letters, digits and underscores, starts with a letter or an underscore, and has up to 128 characters. A value can be up to 32 KiB. The platform sets some keys itself, so you cannot: `PORT`, `TZ`, `STARTUP`, `SERVER_MEMORY`, `SERVER_IP`, `SERVER_PORT`, and any key that starts with `CORITAN_` or `P_SERVER_`. Your app reads the port to listen on from `PORT`.

Secret values are sealed when you save them, and nobody can read one back afterwards, you included. Only the last four characters of a value of eight or more are shown, to tell values apart. To change a secret, enter a new value.

## Import or export a .env file {#import-a-env-file}

To bring many variables at once, import a `.env` file into one environment (and branch) from the **Environment** tab. The file holds `KEY=value` lines, and may use `export` before a key, `#` comments, single quotes and double quotes, including values over several lines. It can be up to 256 KiB with up to 200 variables. If any line is wrong, nothing is saved and the error names the line, such as `Line 3: not KEY=value`.

Owners and admins can export the `.env` that a release of an environment would read, env groups included. Secret values are never exported: their keys are listed at the top of the file, so you can fill them in by hand.

## Share variables with env groups {#env-groups}

An env group is a set of variables that several deployments of your account, or of one organization, read, such as the address of a shared database. Change a value in the group, and every linked deployment reads it from its next release.

- A group has its own `production`, `preview`, `development` and `all` values, without branches.
- A deployment can link up to 10 groups, and the group linked first wins when two hold the same key. The deployment's own variables win over every group.
- An account, or an organization, can have up to 50 groups.
- Deleting a group unlinks it, and its deployments lose its values with their next release.

An organization's groups can be linked only to that organization's deployments, and an account's only to its own.

## Variables from Coritan services {#bindings}

A *binding* connects a deployment to another service you have with us and sets the variables that reach it, so no key or password is copied by hand:

Object Storage
: A bucket, new or one you have, and an access key made for this deployment alone that reaches only that bucket, to read and write or only to read. It sets `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY` and `S3_REGION`.

A database
: One of your database deployments. It sets `DATABASE_URL`, `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_USER`, `DATABASE_PASSWORD` and `DATABASE_NAME`, or `REDIS_URL`, `REDIS_HOST`, `REDIS_PORT` and `REDIS_PASSWORD` for Redis. They are read from the database for each release, so a changed password reaches the next one.

SMTP Relay
: A sending login made for this deployment. It sets `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER` and `SMTP_PASSWORD`.

DNS
: The CNAME and TXT records of each of the deployment's custom domains that is in one of your Coritan DNS zones ([Add a custom domain](/docs/managed-containers/domains-and-protection/#add-a-custom-domain)).

DDoS Shield
: The floating IPs of a game server or a database, put under one of your Shield profiles.

Bindings are made with the API ([With the API](#with-the-api)). Their variables reach the next release, and any variable you set yourself wins over them. Removing a binding deletes the key, the login or the records it made, while a bucket and its files stay. A deployment can have up to 20 bindings, with one for DNS and one for Shield at most.

## Result

The next release reads the new values. The release that is serving keeps the values it started with until a new release replaces it.

## Troubleshooting

The app still reads the old value
: Variables apply with the next release. Select **Redeploy…**, and tick **Build it again** when the build reads the variable.

`PORT is set by the platform and cannot be changed`
: The platform sets that key. Read it in your app instead of setting it, or rename your variable.

`API_TOKEN needs a value`
: A new variable needs a value. An existing one keeps its saved value when you leave the value out.

`Only a preview variable can be limited to one branch`
: Only the `preview` environment has values for one branch. Choose `preview`, or leave the branch out.

`The production environment can have at most 200 variables`
: One environment (and branch) holds up to 200 variables and 256 KiB. Move shared values to an env group, or remove ones you no longer use. A deployment holds up to 1,000 values across all its environments and branches.

`A deployment can link at most 10 env groups`
: Unlink a group, or merge two groups into one.

## Related

- [Deploy from a git repository](/docs/managed-containers/deploy-from-git/) explains production and previews.
- [The Coritan CLI](/docs/managed-containers/cli/) pulls variables into `.env.local` with `coritan env pull`.

## With the API

The routes are under `/api/v1/client/deployments/{uuid}` for your own deployment and `/api/v1/orgs/{org_slug}/deployments/{uuid}` for an organization's. Any member of an organization reads them; owners and admins change them. No answer carries a value once it is saved: `value` is always `null`, and `hint` holds the last four characters.

`PUT /variables` sets several variables of one environment and branch. A variable listed without `value` keeps its saved one, and `"replace": true` deletes the ones you did not list:

```bash
curl -X PUT https://api.coritan.com/api/v1/client/deployments/$DEPLOYMENT/variables \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"environment": "production", "vars": [{"key": "DATABASE_URL", "value": "postgres://shop@db.example.com/shop", "secret": true, "target": "runtime"}]}'
```

The answer lists what was `created`, `updated` and `deleted`, and `redeploy_required`. `GET /variables` lists every variable by environment and branch, `PUT /variables/{key}?environment=preview&branch=feature-login` sets one, and `DELETE /variables/{key}?environment=production` deletes one.

`POST /variables/import` takes the file's text in `content`, with `environment`, `branch`, `secret`, `target` and `replace`. `GET /variables/export?environment=development` answers the file in `content` and the secret keys it left out in `withheld`. `GET /variables/resolved?environment=production` names where each key a release would read comes from, without values.

Env groups are under `/api/v1/client/env-groups` for your account and `/api/v1/orgs/{org_slug}/env-groups` for an organization. `POST /` with `{"name": "Shared database"}` creates one, and `PUT /{group}/variables` sets its variables as on a deployment. `POST /env-groups` on a deployment, with `{"group": "<uuid>"}`, links a group, and `DELETE /env-groups/{group}` unlinks it.

`GET /bindings/options` on a deployment says which kinds of binding it can take and lists the resources you could name. `POST /bindings` makes one, with `kind` (`object_storage`, `database`, `smtp`, `dns` or `shield`) and, where the kind needs it, `ref`: a bucket, the database deployment's UUID, a sending domain or a Shield profile. `env_prefix` puts a prefix and `_` before each key it sets, so two buckets can be bound side by side:

```bash
curl -X POST https://api.coritan.com/api/v1/client/deployments/$DEPLOYMENT/bindings \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"kind": "object_storage", "ref": "new", "env_prefix": "UPLOADS"}'
```

`service_id` picks the Object Storage or SMTP Relay service when you have several, `"mode": "read"` gives a bucket's key read access only, and `"target": "both"` lets builds read the variables too. `GET /bindings` lists the bindings with the keys each sets, never the values, and `DELETE /bindings/{id}` removes one. Two bindings that would set the same key answer `409` with `variable_conflict`.

## API

- `GET /api/v1/client/deployments/{deployment_uuid}/variables`: List variables (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-get-api-v1-client-deployments-deployment-uuid-variables)
- `PUT /api/v1/client/deployments/{deployment_uuid}/variables`: Set or replace variables (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-put-api-v1-client-deployments-deployment-uuid-variables)
- `GET /api/v1/client/deployments/{deployment_uuid}/variables/export`: Export variables (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-get-api-v1-client-deployments-deployment-uuid-variables-export)
- `POST /api/v1/client/deployments/{deployment_uuid}/variables/import`: Import a .env file into one environment (and branch) (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-post-api-v1-client-deployments-deployment-uuid-variables-import)
- `GET /api/v1/client/deployments/{deployment_uuid}/variables/resolved`: Resolved variables (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-get-api-v1-client-deployments-deployment-uuid-variables-resolved)
- `PUT /api/v1/client/deployments/{deployment_uuid}/variables/{key}`: Set a variable (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-put-api-v1-client-deployments-deployment-uuid-variables-key)
- `DELETE /api/v1/client/deployments/{deployment_uuid}/variables/{key}`: Delete one variable of one environment (https://www.coritan.com/docs/api/reference/client/deployments/deployments-variables/#op-delete-api-v1-client-deployments-deployment-uuid-variables-key)
- `GET /api/v1/client/deployments/{deployment_uuid}/env-groups`: List linked environment groups (https://www.coritan.com/docs/api/reference/client/deployments/deployments-env-groups/#op-get-api-v1-client-deployments-deployment-uuid-env-groups)
- `POST /api/v1/client/deployments/{deployment_uuid}/env-groups`: Link an environment group (https://www.coritan.com/docs/api/reference/client/deployments/deployments-env-groups/#op-post-api-v1-client-deployments-deployment-uuid-env-groups)
- `DELETE /api/v1/client/deployments/{deployment_uuid}/env-groups/{group_uuid}`: Unlink an environment group (https://www.coritan.com/docs/api/reference/client/deployments/deployments-env-groups/#op-delete-api-v1-client-deployments-deployment-uuid-env-groups-group-uuid)
- `GET /api/v1/client/deployments/{deployment_uuid}/bindings`: List bindings (https://www.coritan.com/docs/api/reference/client/deployments/deployments-bindings/#op-get-api-v1-client-deployments-deployment-uuid-bindings)
- `POST /api/v1/client/deployments/{deployment_uuid}/bindings`: Bind a resource (https://www.coritan.com/docs/api/reference/client/deployments/deployments-bindings/#op-post-api-v1-client-deployments-deployment-uuid-bindings)
- `GET /api/v1/client/deployments/{deployment_uuid}/bindings/options`: Binding options (https://www.coritan.com/docs/api/reference/client/deployments/deployments-bindings/#op-get-api-v1-client-deployments-deployment-uuid-bindings-options)
- `DELETE /api/v1/client/deployments/{deployment_uuid}/bindings/{binding_id}`: Remove binding (https://www.coritan.com/docs/api/reference/client/deployments/deployments-bindings/#op-delete-api-v1-client-deployments-deployment-uuid-bindings-binding-id)
- `GET /api/v1/client/env-groups`: List groups (https://www.coritan.com/docs/api/reference/client/deployments/env-groups/#op-get-api-v1-client-env-groups)
- `POST /api/v1/client/env-groups`: Create an env group (https://www.coritan.com/docs/api/reference/client/deployments/env-groups/#op-post-api-v1-client-env-groups)
- `GET /api/v1/client/env-groups/{group_uuid}`: One env group, its variables without values, and the deployments it is linked to (https://www.coritan.com/docs/api/reference/client/deployments/env-groups/#op-get-api-v1-client-env-groups-group-uuid)
- `PATCH /api/v1/client/env-groups/{group_uuid}`: Rename an env group (https://www.coritan.com/docs/api/reference/client/deployments/env-groups/#op-patch-api-v1-client-env-groups-group-uuid)
- `DELETE /api/v1/client/env-groups/{group_uuid}`: Delete an env group and its variables (https://www.coritan.com/docs/api/reference/client/deployments/env-groups/#op-delete-api-v1-client-env-groups-group-uuid)
- `PUT /api/v1/client/env-groups/{group_uuid}/variables`: Set or replace a group's variables (https://www.coritan.com/docs/api/reference/client/deployments/env-groups-variables/#op-put-api-v1-client-env-groups-group-uuid-variables)
- `PUT /api/v1/client/env-groups/{group_uuid}/variables/{key}`: Set a group variable (https://www.coritan.com/docs/api/reference/client/deployments/env-groups-variables/#op-put-api-v1-client-env-groups-group-uuid-variables-key)
- `DELETE /api/v1/client/env-groups/{group_uuid}/variables/{key}`: Delete one variable of one environment of a group; 404 when it has none (https://www.coritan.com/docs/api/reference/client/deployments/env-groups-variables/#op-delete-api-v1-client-env-groups-group-uuid-variables-key)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables`: List variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-variables)
- `PUT /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables`: Set or replace variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-put-api-v1-orgs-org-slug-deployments-deployment-uuid-variables)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables/export`: Export variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-variables-export)
- `POST /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables/import`: Import a .env file into one environment (and branch) (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-post-api-v1-orgs-org-slug-deployments-deployment-uuid-variables-import)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables/resolved`: Resolved variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-variables-resolved)
- `PUT /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables/{key}`: Set a variable (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-put-api-v1-orgs-org-slug-deployments-deployment-uuid-variables-key)
- `DELETE /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/variables/{key}`: Delete one variable of one environment (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-variables/#op-delete-api-v1-orgs-org-slug-deployments-deployment-uuid-variables-key)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/env-groups`: List linked environment groups (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-env-groups/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-env-groups)
- `POST /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/env-groups`: Link an environment group (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-env-groups/#op-post-api-v1-orgs-org-slug-deployments-deployment-uuid-env-groups)
- `DELETE /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/env-groups/{group_uuid}`: Unlink an environment group (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-env-groups/#op-delete-api-v1-orgs-org-slug-deployments-deployment-uuid-env-groups-group-uuid)
- `GET /api/v1/orgs/{org_slug}/env-groups`: List groups (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups/#op-get-api-v1-orgs-org-slug-env-groups)
- `POST /api/v1/orgs/{org_slug}/env-groups`: Create an env group (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups/#op-post-api-v1-orgs-org-slug-env-groups)
- `GET /api/v1/orgs/{org_slug}/env-groups/{group_uuid}`: One env group, its variables without values, and the deployments it is linked to (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups/#op-get-api-v1-orgs-org-slug-env-groups-group-uuid)
- `PATCH /api/v1/orgs/{org_slug}/env-groups/{group_uuid}`: Rename an env group (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups/#op-patch-api-v1-orgs-org-slug-env-groups-group-uuid)
- `DELETE /api/v1/orgs/{org_slug}/env-groups/{group_uuid}`: Delete an env group and its variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups/#op-delete-api-v1-orgs-org-slug-env-groups-group-uuid)
- `PUT /api/v1/orgs/{org_slug}/env-groups/{group_uuid}/variables`: Set or replace a group's variables (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups-variables/#op-put-api-v1-orgs-org-slug-env-groups-group-uuid-variables)
- `PUT /api/v1/orgs/{org_slug}/env-groups/{group_uuid}/variables/{key}`: Set a group variable (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups-variables/#op-put-api-v1-orgs-org-slug-env-groups-group-uuid-variables-key)
- `DELETE /api/v1/orgs/{org_slug}/env-groups/{group_uuid}/variables/{key}`: Delete one variable of one environment of a group; 404 when it has none (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/env-groups-variables/#op-delete-api-v1-orgs-org-slug-env-groups-group-uuid-variables-key)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/bindings`: List bindings (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-bindings/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-bindings)
- `POST /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/bindings`: Bind a resource (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-bindings/#op-post-api-v1-orgs-org-slug-deployments-deployment-uuid-bindings)
- `GET /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/bindings/options`: Binding options (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-bindings/#op-get-api-v1-orgs-org-slug-deployments-deployment-uuid-bindings-options)
- `DELETE /api/v1/orgs/{org_slug}/deployments/{deployment_uuid}/bindings/{binding_id}`: Remove binding (https://www.coritan.com/docs/api/reference/organizations/organization-deployments/deployments-bindings/#op-delete-api-v1-orgs-org-slug-deployments-deployment-uuid-bindings-binding-id)
