Environment variables hold configuration that changes between environments and secrets that must stay out of your repository: API keys, database URLs, feature flags. You set them for each app on the Environment page, and dply passes them to your build and, depending on the app type, to your running code. Changes take effect on the next deploy.
Set variables
- In your app, open Environment. The page opens with a sentence such as "Your app gets 14 variables on its next deploy: 9 you set, 2 org secrets and 3 from its resources."
- Click the row for the variables you set. A dialog opens with one
KEY=valueper line, like a.envfile. - Edit it and choose Save and redeploy, or Save to deploy later.
APP_ENV=production
STRIPE_SECRET="sk_live_..."
# Comments are allowed while you edit
export FEATURE_NEW_CHECKOUT=true
The field works like a whole file, not a list of separate entries:
- Saving replaces the full set. A line you delete removes that variable.
- Wrap values containing spaces,
#, or quotes in double quotes. Anexportprefix is accepted and removed. - Comments are not stored. After saving, the field shows only your variables.
- Keys are converted to uppercase, must start with a letter, and may contain only
A–Z,0–9, and_, up to 128 characters. - The discard control in the bottom bar restores the last saved values.
Members who can update the app see the field with values in plain text. Other members see only the list of keys. Values are encrypted at rest.
Important
Saving does not change the running app. Variables apply on the next deploy. Save and redeploy does both. If you save without deploying, open Deploys and choose Redeploy the latest. Rolling back or deploying an earlier commit that was already built does not pick up new values, because it reuses that build as it was.
Reserved names
These names are used by the platform and cannot be set: HOST_MAP, ASSETS, ARTIFACTS, DEPLOYMENT_ID, SITE_ID, STORAGE_PREFIX, EDGE_ANALYTICS, LOG_INGEST_BASE_URL, LOG_INGEST_KEY, ENVIRONMENT.
Where variables are available
When a variable reaches your code depends on how the app runs:
| App type | Build | Runtime |
|---|---|---|
| Static | Yes | No server code runs. Only edge middleware, if you have it, receives the variables. |
| Server-rendered (Worker SSR) | Yes | Yes, as secret bindings on the Worker, read from env in your handler. |
| Hybrid | Yes | Only edge middleware receives them. Server-rendered routes run on your own origin, which dply sends nothing: configure its variables where it runs. |
| Container | Only VITE_* variables reach the image's asset build. |
Yes, in the container's process environment. |
In a Worker, read variables from the env argument, not process.env:
export default {
async fetch(request, env) {
const stripe = new Stripe(env.STRIPE_SECRET);
// ...
},
};
Variables inlined at build time
Frameworks such as Vite, Next.js, and Astro copy some variables into the JavaScript they ship to browsers, for example VITE_*, NEXT_PUBLIC_*, and PUBLIC_*. For static, server-rendered, and hybrid apps, dply passes every variable to the build, so these work as they do locally. Container apps pass only VITE_* variables to the asset build.
Warning
Anything your framework inlines into client code is public: anyone can read it in the browser. Only give browser-exposed prefixes to values that are safe to publish, and keep secrets on unprefixed names that only server code reads.
Variables dply adds for you
Some resources add variables to the next deploy. Click added from resources on the Environment page to see them, with secret values masked.
- Realtime. A Realtime resource adds
REVERB_APP_ID,REVERB_APP_KEY,REVERB_APP_SECRET,REVERB_HOST,REVERB_PORT, andREVERB_SCHEME, the same set with aPUSHER_prefix,PUSHER_APP_CLUSTER, andVITE_REVERB_*andVITE_PUSHER_*for the browser. Laravel apps also getBROADCAST_CONNECTION=reverb. TheVITE_*values reach the build; the rest reach server-rendered and container apps at runtime. - Redis. A Redis connection adds
REDIS_URL,REDIS_HOST,REDIS_PORT,REDIS_USERNAME, andREDIS_PASSWORD. dply manages these: they are hidden from your variables and cannot be overridden there. They are left out while the Redis resource is asleep. See Valkey (Redis). - Databases (container apps). Attaching a dply Postgres or MySQL database writes
DB_CONNECTION,DB_HOST,DB_PORT,DB_DATABASE,DB_USERNAME,DB_PASSWORD,DB_SSLMODE, andDATABASE_URLinto your variables, where you can see and edit them. A container app with no database gets SQLite at/tmp/database.sqliteunless you setDB_CONNECTION,DB_URL, orDATABASE_URL. See Postgres, MySQL & MongoDB. - Container app defaults. Container apps get
APP_URLandASSET_URLset to the app's URL, and generated defaults when first deployed:APP_KEYfor Laravel,SECRET_KEY_BASEfor Rails,NODE_ENVfor Node. Generated defaults are saved into your variables, so you can change them.
A line in your own variables with the same key replaces a value from resources, and the resources dialog marks it replaced by your value. Two exceptions: the Redis keys above, and DPLY_APP_URL and DPLY_MIGRATE_ON_BOOT on container apps, which the platform always sets.
Linked secrets
Organization secrets let you store a value once and link it onto several apps. Click the org secrets row on the Environment page to see and unlink them, or choose Link a secret from the org vault. They are added to the next deploy. If the app's own variables define the same key, that value wins. See Secrets.
Declare variables in dply.yaml
You can declare non-secret values and the names of required secrets in your repository:
env:
public:
APP_ENV: "production"
secret:
- "DATABASE_URL"
- "APP_KEY"
env.publicvalues are added to the build. A value set on the Environment page wins over the file.env.secretlists names only. The build log warns about any name with no value set, and the Environment page names them in its sentence and gives each missing one its own row. Click it to open the editor with a line ready for its value. A missing secret does not fail the build.build.env_filesloads.env-style files from the repository into the build. Values from the dashboard win.
dply.yaml values reach the build, and for container apps the container too. Server-rendered Workers do not receive them at runtime. See Configuration files.
Preview deployments
Preview deployments build and run with this app's environment variables and linked secrets, read at each preview build. Edit them here, on the production app: the Environment page of a preview shows Environment variables are managed on the parent Edge site. To give one preview a different value, set it on the preview through the API; the preview's value wins for that key.
Warning
Previews share production's values except database and Redis connection settings (DATABASE_URL, DB_URL, DB_*, REDIS_URL, REDIS_*, MONGODB_URI, MONGO_URL), which previews never inherit. Set them on the preview if it needs a database.
See Preview deployments.
Manage variables from the CLI or API
The CLI manages the same production variables:
dply-edge edge env list # keys and last update, no values
dply-edge edge env set STRIPE_SECRET=sk_live_... # set one or more
dply-edge edge env rm OLD_KEY # remove one or more
dply-edge edge env push --file .env.production # replace the full set from a file
Warning
dply-edge edge env push replaces the whole set: any key not in the file is deleted, including database variables dply wrote for you. dply-edge edge env pull prints key names with empty values, so pushing its output back erases every value.
The HTTP API has the same operations under /api/v1/edge/sites/{site}/env. The API never returns values. Reading keys needs a token with edge.env.read, and changing them needs edge.env.write.