Overview
Environment variables are key-value pairs that configure your applications at runtime and during the build. Qovery provides comprehensive variable management with support for secrets, multiple scopes, interpolation, file-based variables, and Dockerfile build arguments and secrets.Variable Types
Qovery supports two types of environment variables:Key/Value Variables
Standard environment variables accessible in your application:
Variable as File
Store configuration files that are written to the filesystem at a specific path. The value is stored at the specified file path and accessible for applications or frameworks requiring file-based configuration. Configuration:- Key: Variable name
- Value: File content
- Path: Absolute path where file will be created (e.g.,
/etc/config/app.yaml)

Secrets
Secrets are encrypted variables for sensitive data. They are encrypted at rest and in transit, and cannot be retrieved through the API. When to Use Secrets:- Database passwords
- API keys and tokens
- OAuth credentials
- Private keys and certificates
- Any sensitive authentication data
External Secrets
External secrets let you inject values stored in a third-party secrets manager directly into your services as environment variables, without copying them into Qovery. The secret value is fetched from your provider at deployment time. Supported providers:- AWS Secrets Manager
- AWS Parameter Store
- GCP Secret Manager
- Your secrets are already managed centrally in a secrets manager
- You need fine-grained access control at the secrets manager level
- You want a single source of truth across multiple tools and teams
Configure Secret Manager Integration
Set up ESO and connect your cluster to AWS or GCP secrets providers
Build-Time Variables
Variables are also available while your Dockerfile is being built, not just at runtime. Which variables reach the build, and how, is decided by your Dockerfile — not by whether a variable is marked as a secret in Qovery. A variable reaches the build only if the Dockerfile declares its name in one of two ways:
Variables the Dockerfile declares neither way are never sent to the build. They remain available at runtime as usual.
Passing a Value as a Build Argument
Declare theARG in your Dockerfile and create a variable with the same name:
Mounting a Value as a Build Secret
Declare a secret mount on theRUN step that needs the value, and create a variable with the same name as the mount id:
/run/secrets/<id> by default, or at the path given by target=. Because the value is mounted for that step only, it is not written to an image layer.
Use build secrets for credentials the build needs but the image must not carry: a private registry token, a package manager credential, an SSH key used to fetch a private dependency.
This is different from a Variable as File. A variable as file is written into the running container at the path you configure. A build secret exists only while the build step runs, and is not present at runtime.
Rules and Limits
id= is required. Qovery rejects a Dockerfile that declares RUN --mount=type=secret without a literal id=, and the deployment fails with an error asking you to add one. Plain docker build would guess the name from the mount target; Qovery does not guess, because a guessed name is rarely the variable name you meant.
id= is not an error. If no variable matches the mount id, BuildKit does not mount anything: the secret’s path does not exist inside the step. The build itself is not failed, but a command that reads that path will fail on its own. Add required=true to the mount to fail the build up front instead, with secret <ID>: not found:
ARG or as a secret mount id — is part of the image tag Qovery computes. Changing a value produces a new tag, so the image is rebuilt instead of being reused.
Build logs are obfuscated only for secrets. Qovery masks the values of variables marked as secrets in deployment logs. Mounting a plain key/value variable as a build secret does not mask it — mark it as a secret in Qovery if the value must not appear in logs.
Supported Services
Build-time variables apply to every service Qovery builds from a Dockerfile: applications, cronjobs, lifecycle jobs, and Terraform services using a Dockerfile fragment. Services deployed from an existing container image have no build step and are unaffected.Variable Scopes
Environment variables can be defined at three different scopes:Project Scope
Available to: All environments and services within the project Use Cases: Organization-wide settings, shared API keys, common configurationEnvironment Scope
Available to: All services within a specific environment Use Cases: Environment-specific configuration, shared database credentials, feature flagsService Scope
Available to: One specific service (application, job, database, etc.) Use Cases: Service-specific configuration, application-unique settingsScope Hierarchy
Variables defined at narrower scopes override those at broader scopes:Built-in Variables
Qovery automatically injects built-in variables for service interconnection and system information.System Variables
Database Connection Variables
For each database, Qovery creates connection variables using the pattern:QOVERY_{DATABASE_TYPE}_{DATABASE_ID}_{PROPERTY}
Example - PostgreSQL Database “main-db”:
Application Connection Variables
Connect to other applications using the pattern:QOVERY_APPLICATION_{APP_ID}_{PROPERTY}
Built-in variables are read-only and automatically managed by Qovery. Variable names are generated from service names with underscores replacing hyphens and converted to uppercase.
Creating Variables
1
Navigate to Service
Select your application, job, or container from the environment
2
Open Variables Section
Click on Variables in the service menu

3
Add Variable
Click Add Variable and configure:
- Scope: Project, Environment, or Service level
- Key: Variable name
- Value: Variable value or file content
- Type: Variable or Secret
-
Variable Type: Standard or File (specify path if file)

4
Save and Redeploy
Save the variable and redeploy services to apply changes
Variable Naming Rules
Allowed:- Alphanumeric characters (A-Z, 0-9)
- Underscores (_)
- Must start with a letter
- Uppercase recommended
- Cannot start with
QOVERY_(reserved for built-in variables) - Cannot start with
__(double underscore) - No hyphens or special characters
- No spaces
Editing and Deleting Variables
Editing
- Locate variable in the Variables section
- Click edit icon
- Update value or settings
- Save and redeploy

For secrets, you cannot view the current value. You can only set a new value for security reasons.
Deleting
- Select variable to remove
- Click delete icon and confirm
- Redeploy services

Variable Interpolation
Reference other variables within variable values using{{VARIABLE_NAME}} syntax.
Basic Interpolation
With Built-in Variables
Aliases
An alias exposes an existing variable under a different name, without duplicating its value. Use one when your application expects a specific variable name but the value is produced by Qovery (a built-in variable, a Terraform output, a Blueprint output) or defined elsewhere in your environment. An alias always has a single target: the variable it points to. Resolving the alias at deployment time returns the target’s current value.Creating an alias
An alias is created from its target, not from scratch. In the Console, open the Variables section, find the variable you want to expose, and select Create alias. Then enter the name your application expects.

Pick the variable your application can actually reach.
..._DATABASE_URL and ..._HOST are the external endpoints and only resolve when the database visibility is set to PUBLIC. For a service running inside the cluster, target ..._DATABASE_URL_INTERNAL or ..._HOST_INTERNAL, as in the examples above.Alias rules
- The alias inherits the target’s type. An alias on a secret is a secret; an alias on a plain variable is a plain variable. You do not choose this, and it cannot be changed afterwards. Re-pointing a secret alias to a plain variable (or the reverse) is rejected with
400 Variable tries to alias between secret and env. - An alias cannot target another alias. This would allow circular references that never resolve.
- An alias cannot target an external secret.
- An alias cannot target a variable defined at a narrower scope. An environment-scoped alias cannot point to a service-scoped variable.
- Two variables cannot share a name in the same scope. Creating or renaming a variable to a name already in use returns
409 Variable already exists. - Changes take effect on the next deployment. Creating, renaming, re-pointing, or deleting a variable does not alter the environment of pods that are already running. Redeploy the service to apply it.
Changing the target of an alias
The Console does not allow changing an alias target: the target field is read-only once the alias exists. The API does, with a single call that keeps the alias name, its ID, and its history:key is the alias name and must be sent unchanged. value is the name of the new target variable, not a value. The new target must satisfy every rule above, in particular matching secret or plain type.
This is the recommended way to move an alias from one backing resource to another, for example when migrating a service from a legacy database to a new one.
Swapping aliases from the Console
If you cannot use the API, you can reach the same result by renaming, which the Console does allow. The order matters: a name can only be taken once it has been freed.1
Create the new alias under a temporary name
Create an alias on the new target, named
REDIS_URL_NEW. The existing REDIS_URL is untouched and still resolves to the old target.2
Free the production name
Rename
REDIS_URL to REDIS_URL_LEGACY. Renaming before this step fails with 409 Variable already exists.3
Take the production name
Rename
REDIS_URL_NEW to REDIS_URL.4
Deploy
Redeploy the service. It now reads the new target. Keep
REDIS_URL_LEGACY until the migration is confirmed, then delete it.Converting a plain variable into an alias
A variable’s type cannot be changed after creation, and neither can its secret flag. Turning an existing plain variable into an alias means deleting it and creating the alias in its place, since both would otherwise share the same name in the same scope. Perform both operations before triggering a deployment. Running pods keep their current environment, so the intermediate state is not visible to your application as long as no deployment happens in between. The order cannot be reversed: creating the alias first returns409 Variable already exists.
GET /variable?parent_id=<ENVIRONMENT_ID>&scope=ENVIRONMENT.
This is the correct fix when a connection string has been pasted in as a plain value: delete the plain variable, then create an alias on the built-in variable that produces the same URL. The credential then stays in the built-in secret instead of being stored, displayed, and exported as text.
Deleting an alias or its target
- Deleting an alias removes only that alias. The target variable and its value are preserved.
- Deleting a target also deletes every alias pointing to it, along with any override defined at a narrower scope. Check which aliases depend on a variable before deleting it.
Overrides
When variables are defined at multiple scopes, narrower scopes override broader ones:Import and Export
Import and export variables in bulk using.env file format.
Exporting
- Open the Variables section
- Click Export to download as
.envfile - Secret values are exported as
***for security
Importing
1
Prepare .env File
Create a
.env file with key-value pairs:2
Import File
Click Import and select your
.env file3
Review Import
Qovery shows which variables will be:
- Created (new)
- Updated (existing)
- Skipped (conflicts)
4
Confirm
Review and confirm the import
- Cannot import built-in variables (starting with
QOVERY_) - Cannot overwrite existing secrets (must delete first)
- Cannot import variables with invalid names
Service Interconnection
Use environment variables to connect services within your environment.Database Connection
Application-to-Application Communication
Best Practices
- Security: Always mark sensitive data as secrets
- Naming: Use UPPER_CASE_WITH_UNDERSCORES and descriptive names
- Organization: Use appropriate scopes (Project for shared, Environment for env-specific, Service for unique)
- Rotation: Periodically rotate sensitive credentials
- Documentation: Document variable purposes and expected values
- Cleanup: Remove unused variables regularly
Related Resources
Applications
Configure applications with environment variables
Databases
Connect databases using built-in variables
Deploy Application
Deploy with configured variables
Connect Database
Use environment variables for database connections