Skip to content
PlatformAny language, native runtimes or Docker

Render environment variables and secret files

Render sets variables per service or through environment groups, adds secret files under /etc/secrets and passes values into Docker builds. Pitfalls and Crunu.

RenderAt a glance

Env files, highest priority first
No .env files: values come from the process environment or the platform.
Public prefix
None

No names are copied into browser code by a prefix.

Values applied
Build and runtime

Some values are fixed at build time, the rest are read when the app runs.

Built-in secret store
Environment variables, environment groups and secret files

render.com/docs/configure-environment-variables

Crunu command
crunu run --env web/production -- gunicorn app:appRecipeCrunu has no dedicated integration here: this is the general setup.

Common pitfalls

  1. A service's own variable beats a linked environment group, but between two groups that define the same name the winner is not guaranteed.
  2. Save only stores a change without deploying. The service keeps its old values until the next deploy.
  3. For Docker services, Render passes your variables as build arguments. Referencing a sensitive one in the Dockerfile can put it in the image.
  4. Secret files are copied into the root of the Docker build context. Without a .dockerignore entry they can end up in the image.
  5. All secret files of a service or environment group together may not exceed 1 MB.
On this page

Render gives each service environment variables that you set in the dashboard, import from a .env file, or share across services through environment groups. Values are always strings. Render also sets its own variables, such as RENDER and RENDER_SERVICE_ID, which are available at build time and at runtime unless noted. For files rather than variables, secret files appear under /etc/secrets at runtime. Changing a value doesn't touch a running service until you choose to deploy. For Docker services, Render also turns your variables into build arguments. These rules follow the Render documentation on environment variables and secrets, checked October 30, 2026.

Service variables and environment groups

SourceDefinedPrecedence
Service variableson the service's Environment pagebeat any linked group, guaranteed
Environment groupsonce, linked to any number of servicesbetween groups: not guaranteed
Render's defaultsset by Render for every servicenot documented; don't reuse their names

Groups are the natural place for values several services share, like a database URL used by a web service and a worker. A service can link several groups. When a service and a group define the same name, the service wins, and Render guarantees that. When two groups define the same name, Render currently uses the most recently created group and says the behavior may change without notice. Avoid overlapping names between groups instead of relying on today's order.

Render's list of default variables includes RENDER (always true), IS_PULL_REQUEST, RENDER_EXTERNAL_URL, RENDER_GIT_COMMIT and RENDER_SERVICE_ID. A few are runtime only, such as WEB_CONCURRENCY, and Node services get NODE_ENV=production at runtime only. PORT isn't set by Render. It's an optional variable you can set yourself, and the default port is 10000.

Saving and deploying

When you edit variables, Render offers three choices:

  • Save, rebuild, and deploy: a new build with the new values, then a deploy.
  • Save and deploy: the existing build deployed again with the new values.
  • Save only: nothing is deployed, and the service uses the new values at its next deploy.

The third option is convenient for preparing changes and a common reason a rotated key "didn't work". Editing or deleting an environment group starts a deploy for every linked service that has autodeploy enabled, and linking a group or adding a secret file starts one too.

Secret files

Some programs want a file, such as a service account JSON or a TLS key. Secret files hold those:

  • At runtime they're at /etc/secrets/NAME. Non-Docker services also find them in the service's root directory.
  • All secret files of a service or group together are limited to 1 MB.
  • For Docker builds, Render copies them into the root of the build context, as described on the Docker page. Add them to .dockerignore so they aren't copied into the image by a broad COPY.

Docker builds and build arguments

For a Docker service, Render translates your environment variables into Docker build arguments available during the build, and sets them as normal environment variables at runtime. Render's own warning is direct: don't reference build arguments that contain sensitive values, such as passwords or API keys, in your Dockerfile, or those values might be included in the generated image. If a build step needs a secret, use a secret file instead.

That makes the Dockerfile the place to review. Any ARG that names a secret is a candidate for a leak, whether or not the value seems to be used.

Blueprints and .env imports

In a render.yaml Blueprint, don't commit secret values. Declare placeholder variables and fill them in the dashboard. For a quick start, Add from .env bulk-imports a file into a service. Render's docs add a reminder that's worth repeating: don't commit that .env file to source control.

A short review of a Render service

Most of the problems above are visible in a few minutes of looking, before they cause an incident:

  • Overlapping names. List the variables of every linked group and look for names that appear twice. Rename or remove the duplicates rather than relying on which group was created last.
  • Pending changes. If someone chose Save only, the dashboard shows values the service isn't using yet. Deploy them on purpose or revert them.
  • The Dockerfile. Every ARG should be something you'd be comfortable seeing in docker history. Secrets belong in secret files.
  • .dockerignore. Secret files and any local .env should be listed, so a COPY . . can't pick them up.
  • The Blueprint. render.yaml should contain names and placeholders only, never values.

Where crunu run fits on Render

Crunu doesn't sync into Render's variables or groups. The recommended setup keeps production values in Render and uses Crunu where people work. Starting the service under crunu run is a fallback.

Recommended: use Crunu where people work. Developers run the app locally with crunu run --env web/development -- flask --app app run, and production values are entered into Render once by whoever is allowed to. Nobody needs production values on a laptop, and Crunu's per-environment keys make sure a developer with access to development never holds the production key.

Fallback: let Render hold only a token. For a service you'd rather configure entirely from Crunu, Render stores one secret and the start command decrypts the rest.

  1. Create a service token limited to web/production, without a network rule, and add it to the service as CRUNU_TOKEN. Add CRUNU_SERVER, your Crunu server address, next to it.
  2. In the build command, install crunu with the install script's --user-install mode and a --bin-dir inside the project.
  3. Set the start command to crunu run --env web/production --restart on-change -- gunicorn app:app, using the binary from that directory.
  4. Choose Save and deploy. Later changes in Crunu restart Gunicorn inside the running service instead of waiting for a Render deploy.

Crunu documents service tokens for CI and short-lived environments, and recommends the agent on a machine you control for long-running servers. Before you use a token this way, accept three limits:

  • Render can decrypt this environment. Render stores the token and passes it to the build and the running service, and the token decrypts the environment it was granted. For this environment, the promise that the server can't read your values no longer holds: the platform holding the token can.
  • An expired lease stops the service from starting. The token's lease is a window of inactivity from 1 hour to 30 days, and every sign-in extends it. If the service doesn't start for longer than the lease, for example while it's suspended, the token is refused at the next start, crunu run exits before Gunicorn starts, and the service stays down until an owner or admin resumes the token. Choose a lease longer than the longest time the service may stay stopped.
  • One token per environment, with the smallest grant and no network rule. Give each service and environment its own token that reads only that environment. Don't bind it to networks: the addresses Render connects from can change, and a network rule would then lock the service out.

On Docker services the token becomes a build argument like any other variable, so never name it in an ARG. crunu run keeps CRUNU_TOKEN away from the program it starts, and a process that is already running keeps the values it has until it restarts.

Frequently asked questions

Something else? Write to support@crunu.com

Are Render environment variables available during the build?

Render's default variables are available at build time and runtime unless noted. For Docker services, Render passes your variables to the build as build arguments and also sets them at runtime.

Where do Render secret files end up?

At runtime in /etc/secrets with their file name, and for non-Docker services also in the service's root directory. For Docker builds, Render copies them into the root of the build context.

Which value wins when a service and an environment group set the same variable?

The service's own value always wins, and Render guarantees that. When two linked groups set the same name, Render currently uses the most recently created group but says this may change without notice.

Can Crunu sync into Render environment groups?

No, there's no built-in sync. Use Crunu for development and as the place values are edited. As a fallback, start the service under crunu run with a service token so Render stores only that token, accepting that Render can then decrypt that environment.

Sources

Every source this page relies on, with the date we last checked it.

  1. Render Docs: Environment variables and secrets · checked October 30, 2026
  2. Render Docs: Default environment variables · checked October 30, 2026
  3. Render Docs: Docker on Render · checked October 30, 2026

Keep your .env values in one place

Free during early access. Values are encrypted on your devices, each environment has its own key, and crunu run hands them to your app without writing a file.