Environment variables

Add and edit encrypted variables, and wire a database into your service.

Environment variables configure your service without code changes. Every value is encrypted at rest, masked in the UI, and never shown again after saving.

Add or edit a variable#

  1. 1

    Open the Environment tab

    On the service page, go to the Environment tab.

  2. 2

    Enter a key and value

    Type the variable name (auto-uppercased, e.g. NODE_ENV) and its value, then click “Add”. Reusing a key overwrites it.

  3. 3

    Redeploy to apply

    Changes take effect on the next deploy — hit “Deploy” when you’re ready.

All values are treated as secrets. The list shows a masked preview, not the plaintext, and the API never returns stored values.

Connect a database#

Open a database’s Connect tab to reveal a ready-to-paste block of connection variables — for example DATABASE_URL for Postgres/MySQL, MONGODB_URI for MongoDB, or REDIS_URL for Redis. Copy them into your service’s environment.

Limits & rules#

  • Keys are uppercased automatically (e.g. node_env becomes NODE_ENV).
  • Values can be up to 32,768 characters.
  • Changes take effect on the next deploy.
  • The API and CLI return only the keys — never the stored values.

Env groups (shared config)#

Create a reusable env group under Env groups, add variables (or import a .env), and attach it to multiple services. On deploy, a group’s variables are injected into every attached service — a service’s own variables override the group. Handy for shared secrets and config across a fleet.

Build-time variables#

Variables are normally injected when the container starts, so nothing secret ends up inside your image. Some builds need values earlier — a Next.js app that pre-renders pages from its database, or NEXT_PUBLIC_/VITE_ values inlined into the browser bundle. Mark those keys with the hammer toggle in the Environment tab, or add them under “Build-time variables”.

  • Only the keys you mark are exposed — everything else stays runtime-only.
  • Values are mounted as build secrets for the step that reads them, never written into an image layer.
  • Keys resolve like they do at runtime, so a linked database’s DATABASE_URL works by listing that one key.
  • Whatever your build writes out of a value does persist — an inlined NEXT_PUBLIC_ value lives in the bundle because your framework put it there.

Your service reads configuration and database credentials from the environment, kept encrypted and out of your codebase.