Environment Variables
Environment variables configure a single Resource — one app in one Environment. The same app in production and staging keeps separate sets, so you can point each at different services without touching code.
Settings that many apps share don’t have to be repeated on each one: set them once on the Organization or the Environment and every app there inherits them — see Organization and environment variables.
Keys must start with an uppercase letter and contain only uppercase letters, digits, and underscores (DATABASE_URL, NODE_ENV). The dashboard normalizes what you type automatically; the CLI and API reject invalid keys.
Setting, changing, or deleting a variable requires the manage capability on the project (see Access Control) and triggers a new deployment of the app so running instances pick up the change.
In the dashboard
Open your app’s Config tab and find the Environment Variables section, then click Add Variable. Each variable takes one of three value sources:
- Plain value — stored and displayed as-is. Good for non-sensitive settings like
NODE_ENV. - Secret value (hidden) — the value is stored as an encrypted secret in this Environment, named after the variable’s key, and linked to it. Your app receives it like any other variable; nobody can read it back afterwards. Because it creates or replaces a secret, it needs the Manage secrets capability on the Environment, not just permission to manage the app. A name that’s already a secret here is refused: another app’s linked secret, one made on the Secrets page, or a Project secret (and, for organization owners and admins, an Organization secret). Writing it would change or override that secret for every app here, so link the variable to it instead, or pick another name.
- Link to secret — the variable takes its value from a platform-managed secret you pick from a list. If no secret is available to link, the form links you to create one.
Existing variables can be edited or deleted inline. Deleting asks for confirmation, since it also redeploys the app. A hidden variable stays hidden: saving a plain value over it is refused, so delete it first if you want to store a plain one.
The section also lists the variables the app inherits from its Organization and Environment, showing where each one comes from and whether the app overrides it.
With the CLI
paas config manages variables for the app selected with -a, scoped by -o/--org, -p/--project, and -e/--env.
List the current variables:
paas config list -o acme -p shop -e production -a web
Set one or more variables. Pairs are applied in order, and the command stops at the first failure:
paas config set NODE_ENV=production LOG_LEVEL=info -o acme -p shop -e production -a web
Store a hidden value with --hidden: the CLI’s version of Secret value (hidden), with the same rules and capability. KEY=- reads the value from stdin, so it stays out of your shell history:
printf %s "$API_TOKEN" | paas config set --hidden API_TOKEN=- -o acme -p shop -e production -a web
Remove a variable (one key per command):
paas config unset LOG_LEVEL -o acme -p shop -e production -a web
paas config list also shows the variables the app inherits; --json prints the raw API response for the app’s own variables only.
Linking a variable to a secret
Select Link to secret for a sensitive value. A variable key can differ from the secret name; the referenced secret must already exist in a visible scope. Follow Binding a secret to an app for the dashboard and CLI commands.
Organization and environment variables
Besides its own variables, every Web Application and Background Worker inherits plain variables set on its Organization and on its Environment. Use them for settings that many apps share — a log level for the whole staging Environment, a region or company-wide feature flag for every app in the Organization — instead of copying the same value onto each app.
The app overrides its Environment, which overrides its Organization. There is no Project-level plain-variable scope. See configuration precedence for the complete rules and an example.
A few things to know:
- Plain values only. Organization and Environment variables are stored and shown as-is, and can’t link to a secret. Anyone who can view the Organization or Environment can read them, so keep passwords and API keys in secrets and link them from the app.
- Automatic and attachment variables win. Variables the platform sets for an app —
PAAS_PUBLIC_URL,PAAS_PUBLIC_HOST, and the variables an attached database or bucket injects — are never replaced by an inherited variable. An inherited variable with one of those keys is skipped for that app and shown as overridden. - Referencing inherited values. An app’s own variables can use an inherited one, just as they can use the automatic variables — for example
API_URLset to$(API_BASE)/v2. - Changes roll out on their own. Setting or removing an Organization or Environment variable redeploys every app it applies to, so their instances pick up the new value. There is nothing to restart by hand.
Keys follow the same rules as app variables, and a value can be up to 10,000 characters.
Who can change them
| Level | Who can read | Who can set or remove |
|---|---|---|
| Organization | Any Organization member (project guests can’t) | Organization Owners and Admins |
| Environment | Anyone with View on the Environment | Anyone with Manage environments on the Environment |
An Environment’s capabilities come from the Project unless a per-environment override changes them. See Access Control.
In the dashboard
- Organization variables — open the Organization, go to Settings, then Variables.
- Environment variables — open the Environment, go to Settings, then Variables.
Add, edit, or remove variables there. The app’s own Environment Variables section shows what it inherits from both levels.
With the CLI
paas config takes --scope org|env|app (default app). With --scope org it needs only the Organization (-o); with --scope env it needs the Organization, Project, and Environment (-o, -p, -e); the default app scope also needs -a.
# Every app in the Organization
paas config set --scope org LOG_LEVEL=warn -o acme
# Every app in the staging Environment
paas config set --scope env LOG_LEVEL=debug -o acme -p shop -e staging
paas config list --scope env -o acme -p shop -e staging
# Remove an inherited variable
paas config unset --scope org LOG_LEVEL -o acme
--secret-ref works with the app scope only, since Organization and Environment variables are plain values.
Automatic variables
Apps with a public hostname (Web Applications) get two variables injected automatically:
PAAS_PUBLIC_URL— the app’s full public URL, e.g.https://dzijyc9c.cx.<your-platform-domain>— an eight-character random label under the app domain your platform’s operators configuredPAAS_PUBLIC_HOST— the hostname alone
Because public hostnames are randomly generated, your app cannot guess its own address at build time; use these wherever the app needs to name itself — an OAuth redirect URL, absolute links in email, a webhook it registers. Other variables you define can reference them, for example CALLBACK_URL set to $(PAAS_PUBLIC_URL)/oauth/callback.
If you define your own PAAS_PUBLIC_URL or PAAS_PUBLIC_HOST on the app — say, behind a proxy or on a custom domain — your value wins and the platform’s is not injected. (An Organization or Environment variable with one of these keys does not; see above.) Background Workers and Databases have no public hostname, and Object Storage buckets don’t run your code, so none of them receive these variables.
Every Web Application and Background Worker also gets PORT, set to the app’s port: 3000 unless you chose another, and 8080 for a worker without one. Bind your server to it.
When a restart is needed
Variable changes and secret rotation roll out automatically. The delete-and-recreate exception and its restart command are documented in When changes reach your app. Configuration rollouts are not numbered code deploys and do not provide automatic rollback; try changes in staging first.
Next steps
- Managing Secrets — create and update the secrets your variables link to
- Attaching a Database — connection details injected as an environment variable
- Secrets & Configuration — how configuration flows through the platform
- Deployments, Health Checks & Rollback — the deployments your changes trigger