Environment variables
The configuration your app reads from its environment, encrypted, layered and injected on deploy.
What it is
The configuration your app reads from its environment: API keys, database URLs, feature flags, NODE_ENV. Deplo stores them encrypted, injects them at build time and at run time, and never shows a secret back to anybody.
How it works
Four layers stack, and the deploy folds them together in this order, lowest priority first: instance-wide variables (set by an instance admin, every team, every app), then the app's own variables, then a shared variable the app has linked, then a preview override (previews only).
A name defined twice takes the value from the highest layer that defines it.
Every value carries a type, plain or secret, on every layer. The type is not decoration.
Stored and shown back to you. Can be edited freely, and can be promoted to secret at any time.
Promoting plain to secret is always allowed. The other direction is not.
Deplo says so when a name reads like a credential. A plain variable called PAYLOAD_SECRET, S3_ACCESS_KEY_ID or DB_PASSWORD carries a Looks like a secret badge in Environment, and adding one says the same thing in the dialog. It is a suggestion, not a refusal: the variable works either way, and the rule is Docker's own, so names holding PUBLIC, FILE or VERSION (NEXT_PUBLIC_API_KEY, TOKEN_FILE) are exempt.
Build time and run time are the same set. Every resolved variable is passed to the build as a build argument and declared in the generated Dockerfile, so build-time inlined configuration such as NEXT_PUBLIC_* or VITE_* works with no extra toggle.
A build argument stays in the image history
The built image does not keep the value in its environment, but Docker records every build argument in the image's build history, so docker history shows it in plaintext on the server that built it. Only someone with Docker access to that server can read it.
Set variables on one app
Open Environment
Open the app, then Environment.
Add a variable
Click Add variable.
Name it and set the type
Type the name and the value, and pick Plain or Secret. A name that reads like a credential is flagged here, so you can flip it before it is stored.
Save and redeploy
Save, then Redeploy. Variables apply on the next deploy.
To bring over a whole .env file, paste it into the add dialog: Deplo parses KEY=value lines in bulk instead of making you add twenty rows by hand.
Each row records who created it and who last changed it, with an avatar, so a surprising value has a name attached to it.
See everything at once
The Variables page in the sidebar has two tabs:
Prop
Type
Preview overrides
Settings -> Pull requests has a collapsed Preview overrides section where one variable can take a different value in previews only. It folds above everything else.
The normal use is pointing previews at a scratch database instead of the real one. Most apps never need it, which is why it is collapsed and empty by default.
Limits and gotchas
- Nothing applies until the next deploy. Setting a variable does not restart anything. Click Redeploy.
- A secret cannot be edited, only replaced. By design.
reveal_secretsdoes not reveal secret-typed variables. That capability unmasks plain-but-masked values, connection strings and passwords. Nothing unmasks a secret.- Names are not validated against your framework. A typo is a missing variable at run time, not an error at save time.
- Ticking a shared variable's scope does not inject it. Only the per-app link does, unless the variable covers more than one team - that one adds itself everywhere. See Shared variables.
- Compose apps get their variables injected into every service as pass-through entries, with the values riding in a
0600env file next to the stack.
If it does not work
- The app cannot see a variable it should have - it was added after the last deploy. Redeploy.
- The value is right in Deplo and wrong in the app - something above it in the precedence list defines the same name. Check the app's own variables first, then its linked shared variables.
- A build-time variable is empty in the browser bundle - the framework inlines only prefixed names (
NEXT_PUBLIC_,VITE_). The prefix is the framework's rule, not Deplo's.
More in Deploys and builds.
See also
Did this page help you?