Environment variables
Prerequisites: Container configuration
Environment variables are the primary mechanism for configuring containers in Clouve. The platform extends the standard concept with a type system that controls how each variable is stored, presented, and managed at deployment time.
Why types matter
A standard Docker Compose file treats every environment variable the same way. Clouve's type system is what lets the platform:
- Store sensitive values in Kubernetes Secrets, encrypted at rest
- Store non-sensitive values in Kubernetes ConfigMaps
- Prompt business users to fill in values at deployment time
- Resolve inter-container hostnames and generate application credentials automatically
- Fill in URLs based on the deployment's DNS configuration
The eight variable types
static
A fixed configuration value that never changes at deployment time. Stored in a Kubernetes ConfigMap.
Use it for:
- Application mode (
production,debug) - Feature flags (
true,false) - Non-sensitive configuration values
- Database names and usernames that are not secrets
environment:
NODE_ENV: production
DEBUG: "false"
DB_NAME: wordpress
TABLE_PREFIX: wp_
x-clouve-environment-types:
NODE_ENV: static
DEBUG: static
DB_NAME: static
TABLE_PREFIX: static
secret
A sensitive value that must be stored encrypted. Stored in a Kubernetes Secret (base64-encoded and access-controlled).
Use it for:
- Database passwords
- API keys and tokens
- JWT signing secrets
- OAuth client secrets
- Any credential or private key
environment:
DB_PASSWORD: changeme
JWT_SECRET: changeme
STRIPE_API_KEY: changeme
x-clouve-environment-types:
DB_PASSWORD: secret
JWT_SECRET: secret
STRIPE_API_KEY: secret
The values in the manifest are only defaults, and business users can override them at deployment time. Put placeholders in your manifest, never real secrets.
userConfigurable
A value the business user is expected to customize when deploying the application. Once the user fills it in, it is stored in a Kubernetes ConfigMap.
Use it for:
- Admin email address
- Site name or title
- Application theme
- Custom domain
- Configuration that varies per organization
environment:
SITE_TITLE: My WordPress Site
ADMIN_EMAIL: admin@example.com
APP_THEME: light
MAX_UPLOAD_SIZE: "64M"
x-clouve-environment-types:
SITE_TITLE: userConfigurable
ADMIN_EMAIL: userConfigurable
APP_THEME: userConfigurable
MAX_UPLOAD_SIZE: userConfigurable
The value you provide is the default shown to the user in the deployment form.
containerReference
A reference to another container in the same application; the value is that container's name. Stored in a Kubernetes ConfigMap and automatically prefixed with the ticket ID at deployment time.
Use it for:
- Database hostnames (
DB_HOST,REDIS_HOST,DATABASE_URL) - Any variable whose value is another container's internal DNS name
# In the wordpress container:
environment:
WORDPRESS_DB_HOST: wordpress-mariadb
REDIS_HOST: wordpress-redis
x-clouve-environment-types:
WORDPRESS_DB_HOST: containerReference
REDIS_HOST: containerReference
The platform resolves the container name to the correct internal hostname in the Kubernetes namespace. Never hardcode IP addresses.
The value must exactly match the container name of the target service. If the target container is named postgres-db, the variable value must be postgres-db.
applicationUsername
A username field for the application's admin credentials. The business user fills it in on the deployment form and the platform injects it as a variable.
Use it for:
- The admin username of a CMS (WordPress, Moodle)
- The primary user account's username
environment:
ADMIN_USER: admin
x-clouve-environment-types:
ADMIN_USER: applicationUsername
The value you provide is a suggested default; the deploying user can change it.
applicationPassword
A password field for the application's admin credentials, shown to the deploying user as a masked input. Like applicationUsername, it is collected on the deployment form and injected as a variable.
Use it for:
- The admin password of a CMS or application
- Any credential the deploying user should set themselves
environment:
ADMIN_PASSWORD: changeme
x-clouve-environment-types:
ADMIN_PASSWORD: applicationPassword
applicationUrl
The full HTTPS URL at which the application will be accessible. The platform generates it from the deployment's DNS configuration and stores it in a Kubernetes ConfigMap at deployment time.
Use it when:
- The application needs to know its own public URL, for generating links, redirects, API callbacks, or OAuth redirect URIs
- Setting WordPress
SITE_URL/HOME_URL - Filling any
BASE_URLorAPP_URLvariable
environment:
WORDPRESS_SITE_URL: ""
APP_PUBLIC_URL: ""
x-clouve-environment-types:
WORDPRESS_SITE_URL: applicationUrl
APP_PUBLIC_URL: applicationUrl
The platform ignores the value you provide and replaces it with the actual deployment URL at runtime, for example https://myworkspace.clouve.dev.
applicationHost
The hostname (without protocol) at which the application will be accessible, also generated by the platform and stored in a Kubernetes ConfigMap at deployment time.
Use it when:
- Your application needs just the hostname portion, for CORS configuration or a TLS cert subject
- You need the hostname separately from the URL
environment:
APP_HOST: ""
CORS_ORIGIN: ""
x-clouve-environment-types:
APP_HOST: applicationHost
CORS_ORIGIN: applicationHost
Type reference
| Type | Storage | User Fills In? | Platform Generates? | Use For |
|---|---|---|---|---|
static | ConfigMap | No | No | Fixed config |
secret | Secret | At deploy (optional) | No | Passwords, keys |
userConfigurable | ConfigMap | Yes | No | Per-org settings |
containerReference | ConfigMap | No | Resolved | Inter-container hostnames |
applicationUsername | Form | Yes | No | Admin username |
applicationPassword | Secret | Yes | No | Admin password |
applicationUrl | ConfigMap | No | Yes | App's own URL |
applicationHost | ConfigMap | No | Yes | App's own hostname |
A note on
applicationPasswordstorage: the user fills it in on the deploy form, but the value is written into the Kubernetes Secret (not the ConfigMap) alongsidesecret-typed variables. Tropo'sGetSecretVarsincludes both types. Treat it as a credential at rest.
UI labels and manifest values
The manifest and API use the canonical type strings above. The container-configuration UI shows friendlier labels:
| UI label | Manifest / API value |
|---|---|
Static | static |
Secret | secret |
User Input | userConfigurable |
Container Reference | containerReference |
Application Username | applicationUsername |
Application Password | applicationPassword |
Application URL | applicationUrl |
Application Host | applicationHost |
Either form is valid in the YAML upload. The downloader always normalizes to the lowercase manifest value, so the file is round-trip stable.
Naming conventions
Environment variable names must be valid shell variable names. UPPERCASE_SNAKE_CASE is both the convention and a requirement: use only alphanumeric characters and underscores, start with a letter or underscore, and avoid spaces, hyphens, and dots.
✅ DATABASE_URL
✅ JWT_SECRET
✅ ADMIN_EMAIL_ADDRESS
✅ MAX_CONNECTIONS
❌ database-url
❌ jwt.secret
❌ 1_INVALID
Security best practices
-
Never use
staticfor sensitive data. If a value is a credential, store it assecret, even when it looks innocuous. -
Use placeholder values for secrets in your manifest. The manifest may sit in version control or be reviewed by others, so write
changemeor<replace-me>instead of a real secret. -
Mark every password as
secretorapplicationPasswordso it is stored in a Kubernetes Secret and not exposed in a ConfigMap. -
Use
applicationUrlfor self-referencing URLs. Deployments use dynamically assigned subdomains, so never hardcode a domain. -
Fill in the
descriptionfield for every variable. Business users see this description when deploying.
Complete example: Node.js backend
environment:
# Database connection
DB_HOST: postgres-db
DB_PORT: "5432"
DB_NAME: appdb
DB_USER: appuser
DB_PASSWORD: changeme
# Application config
NODE_ENV: production
PORT: "3000"
LOG_LEVEL: info
# Auth
JWT_SECRET: changeme
JWT_EXPIRES_IN: 7d
# External service
STRIPE_SECRET_KEY: changeme
SENDGRID_API_KEY: changeme
# Self-reference
API_BASE_URL: ""
# User-customizable
MAX_CONNECTIONS: "100"
ALLOWED_ORIGINS: ""
x-clouve-environment-types:
DB_HOST: containerReference
DB_PORT: static
DB_NAME: static
DB_USER: static
DB_PASSWORD: secret
NODE_ENV: static
PORT: static
LOG_LEVEL: static
JWT_SECRET: secret
JWT_EXPIRES_IN: static
STRIPE_SECRET_KEY: secret
SENDGRID_API_KEY: secret
API_BASE_URL: applicationUrl
MAX_CONNECTIONS: userConfigurable
ALLOWED_ORIGINS: userConfigurable
Troubleshooting
Container can't connect to the database. Check that DB_HOST (or its equivalent) is typed as containerReference and that its value exactly matches the database container's name.
Application uses the wrong URL in generated links. Add an applicationUrl-typed variable and inject it into your application as the base URL. Do not hardcode a domain.
Secrets are visible in logs. Make sure your application does not log secret-typed variables; add filtering to your logging middleware.
A user-configurable variable shows the wrong default. The value field in your manifest is the default shown to users. Set it to a sensible default, or an empty string if there is no good one.
Next steps
- Health checks →
- Volumes and storage →
- Container configuration → (back to the full UI workflow)