Environment variables
velixir injects environment variables into your app's pod at start-up. You set them per app from the dashboard, the CLI or the API, and they're applied on the next deploy.
Setting a variable
From the app's Environment tab:
- Enter a key (
DATABASE_URL,STRIPE_API_KEY, anything matching^[A-Za-z_][A-Za-z0-9_]*$). - Enter a value.
- Tick Treat as secret if it's something you don't want shown back in the UI.
- Click Save.
Setting a key that already exists replaces its value. No separate "edit" step.
Importing a .env file
Moving an app from another host, or from your laptop? Paste the whole file into Import from a .env file on the Environment tab. It reads KEY=value lines, an optional export prefix, comments, blank lines, and quoted values, including double-quoted values that run over several lines (PEM keys). That covers a local .env, the output of heroku config -s, and variables copied from a Render service.
- It's all or nothing: if a line can't be read, nothing is saved and you're told which line.
- Keys that already exist are replaced. An existing secret stays secret.
PORTand the other variables velixir sets itself (listed below) are skipped, because aPORTcopied from another host would stop your app receiving traffic.
From the CLI
velixir env # list (secrets are masked)
velixir env set API_URL=https://api.example.com
velixir env set STRIPE_KEY=sk_live_... --secret
velixir env unset OLD_FLAG
velixir env import .env --secret # or pipe: heroku config -s -a my-app | velixir env import -
Add --redeploy to any of these to redeploy the app afterwards. The same operations are on the API under /api/v1/apps/{id}/env (see the API reference).
Secrets vs plain values
- Plain values are stored as you typed them and shown back in the UI. Use these for non-sensitive config: feature flags, hostnames, environment names.
- Secrets are encrypted at rest with ASP.NET Core DataProtection (the same key infrastructure that signs cookies and antiforgery tokens). The UI shows
••••••••instead of the value; to change a secret you set the key again with a new value.
Both kinds reach your pod as ordinary environment variables, so your code reads them however your language normally does. Nothing velixir-specific is required.
Reading them from your code
Environment variables are read the standard way in every language, no velixir SDK required:
// Node.js
const dbUrl = process.env.DATABASE_URL;
const port = process.env.PORT;
// .NET
var dbUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
var port = Environment.GetEnvironmentVariable("PORT");
We also set some platform-managed vars automatically:
PORT- the port your app must listen on. This is the one variable every app has to honour, whatever language it's written in: bind your web server to it on0.0.0.0. It's 8080 unless you change it under Scaling → Runtime.VELIXIR_APP_ID,VELIXIR_APP_SLUG- identifiers your app can log or report.VELIXIR_VOLUME_PATH- where the app's volume is mounted, on apps that have one. See Volumes.
We also set the ASP.NET Core equivalents on every app, so a lift-and-shift .NET app runs with no code changes:
ASPNETCORE_URLS- bound to the same port asPORT.ASPNETCORE_HTTP_PORTS- the same port.ASPNETCORE_ENVIRONMENT-Production.
If you provision a managed database or cache inside the same project and link it to your app, we also inject a connection string for it automatically (see Postgres databases / Valkey caches).
Applying changes
Setting or deleting an env var doesn't auto-redeploy. The Environment tab shows a banner reminding you to redeploy - running pods keep their original values until they're rolled over. Hit Deploy on the latest release (or push a new one) to apply changes, or pass --redeploy from the CLI.
Environment variables reach your app when it runs, not while it's built. If your build step needs a value (a NEXT_PUBLIC_* variable baked into a frontend bundle, for example), commit it to the build config or read it at runtime instead.
Limits
- Keys: max 200 characters, must match
^[A-Za-z_][A-Za-z0-9_]*$. - Values: max 4000 characters, line breaks included. Secrets grow when encrypted, so keep a secret under about 2,600 characters. For larger blobs (big JSON config), put the blob in object storage and store the URL here.
- An import can hold up to 500 variables.