Table of Contents
Role of Environment Variables in OpenShift
In OpenShift, environment variables are a primary mechanism to inject configuration into running containers without rebuilding images. They are evaluated inside the container process, just like environment variables in a regular Linux process, but are defined and managed through Kubernetes/OpenShift resources.
Environment variables are especially useful for:
- Passing non-sensitive configuration (URLs, feature flags, log levels)
- Wiring applications to services (hostnames, ports, credentials references)
- Switching behavior between environments (dev, test, prod)
- Overriding container defaults at deployment time
They complement (and often reference) ConfigMap and Secret objects, but this chapter focuses specifically on how environment variables are defined, prioritized, and used.
Ways to Define Environment Variables in OpenShift
Environment variables can be set at several resource levels and through several mechanisms.
In Deployment/Pod specifications
The most direct way is to define variables under env in pod specs (for example in a Deployment, DeploymentConfig, Job, or CronJob):
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
spec:
template:
spec:
containers:
- name: app
image: quay.io/org/app:latest
env:
- name: APP_MODE
value: "production"
- name: LOG_LEVEL
value: "info"This sets static, literal values in the pod. Changes require updating the workload resource and usually a rollout.
From ConfigMaps
To keep configuration separate from workload definitions and make it easier to update, environment variables are often populated from ConfigMap keys:
env:
- name: APP_CONFIG
valueFrom:
configMapKeyRef:
name: app-config
key: app-config.yaml
Or bulk-import an entire ConfigMap as environment variables:
envFrom:
- configMapRef:
name: app-config
In the bulk approach, each key in the ConfigMap becomes an environment variable with the same name.
From Secrets
Environment variables can also be populated from Secret objects (appropriate for sensitive values, discussed more in the Secrets chapter):
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Or all keys from a Secret:
envFrom:
- secretRef:
name: db-credentialsNote that once a secret is in an environment variable, it is visible to processes and can appear in logs or crash dumps; treat such pods carefully.
Using `oc` CLI shortcuts
The oc CLI provides helpers for adding environment variables to existing resources without manually editing YAML:
- Add/modify environment variables:
oc set env deployment/example-app APP_MODE=staging LOG_LEVEL=debug- Load from a
ConfigMaporSecret:
oc set env deployment/example-app --from=configmap/app-config
oc set env deployment/example-app --from=secret/db-credentials- Remove environment variables:
oc set env deployment/example-app APP_MODE- LOG_LEVEL-
These commands update the resource spec and typically trigger a rollout for controllers like Deployment.
Types and Sources of Values
Literal values
Values given directly in the spec using value. These are static strings:
env:
- name: FEATURE_FLAG_NEW_UI
value: "true"Environment variables are always strings from the container’s perspective; any typing or conversion is handled by the application.
Values from fields (`fieldRef`)
You can dynamically set environment variables from pod or container fields, such as pod name, namespace, or node name:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeNameThis is useful for logging, metrics, and behavior that depends on runtime placement.
Values from resource fields (`resourceFieldRef`)
You can expose pod resource limits/requests to the container, often for tuning runtimes (e.g., JVM):
env:
- name: JVM_MAX_HEAP
valueFrom:
resourceFieldRef:
containerName: app
resource: limits.memory
divisor: 1MiThis lets the container adapt its behavior based on configured resources.
Precedence, Overrides, and Merging
When environment variables are defined from multiple sources, certain rules apply:
- Within a single pod spec:
enventries have explicit names and cannot conflict with each other; the last definition in the list wins if the same name is repeated.envFromimports may create variables that collide:- If multiple
envFromsources define the same key, one will win but the order is not something to rely on in complex setups. - Any explicitly defined variable in
envoverrides matching names coming fromenvFromsources.
Example:
envFrom:
- configMapRef:
name: defaults-config # defines LOG_LEVEL=info
env:
- name: LOG_LEVEL
value: "debug" # overrides defaults-config- Updates to referenced
ConfigMap/Secret: - In standard workloads, changes in the
ConfigMaporSecretdo not automatically restart pods. - Environment variables are evaluated when the pod starts; pods must be restarted (or rolled out) to see new values.
- Some Operators or advanced controllers may watch for changes and trigger rollouts; this is not automatic for generic workloads.
Environment Variables versus Files and Volumes
Configuration can be injected via:
- Environment variables
- Files mounted from
ConfigMaporSecretvolumes - External services / service discovery mechanisms
Environment variables are best when:
- Values are small (short strings)
- You need easy substitution into existing applications (many frameworks read directly from env)
- You want fast overrides without changing code
Mounted files are better when:
- Values are large or structured (config files, certificates, keys)
- Applications natively read from configuration files
- You want to support runtime reloads without restarting the pod (some apps watch files)
You can combine both:
- Use volumes for full configuration files
- Use environment variables as pointers or flags controlling which configuration profile to use
Pattern: Environment-Specific Configuration
A common OpenShift pattern is to differentiate configuration across environments (dev, test, prod) via environment variables, while keeping the image the same.
Examples:
- Connection endpoints:
DATABASE_HOST,REDIS_URL,API_BASE_URL - Feature toggles:
FEATURE_X_ENABLED - Logging and debugging:
LOG_LEVEL,TRACE_ENABLED - Mode selection:
RUN_MODE,SPRING_PROFILES_ACTIVE
Typical setup:
- Use a single container image across environments.
- Maintain environment-specific
ConfigMaps andSecrets. - Workloads in each environment reference the appropriate config via
envFromorenv.
This supports the “build once, deploy many times” model central to cloud-native and OpenShift workflows.
Environment Variables in OpenShift Templates and Pipelines
Environment variables are frequently used with OpenShift templates and CI/CD logic:
- Templates:
- Parameters in templates often map to environment variables inside the resulting workloads.
- At instantiation time, users supply parameter values, which become env vars.
- Pipelines:
- CI/CD pipelines (e.g., OpenShift Pipelines/Tekton) frequently set environment variables to pass build metadata, version numbers, or configuration into build or deploy tasks.
- These variables can propagate into application deployments to embed build info (like
GIT_COMMIT,IMAGE_TAG).
Using environment variables this way keeps deployments flexible and automatable without manual edits to application code.
Observability and Debugging of Environment Variables
To troubleshoot issues related to configuration:
- Inspect environment variables defined in the resource:
oc describe deployment/example-app
Look under Environment: in the output.
- Inspect the running pod environment:
- By exec’ing into a pod:
oc rsh pod/example-app-abc123
env | sort- Or by using a one-off diagnostic container with the same configuration (for example, using
oc debugon a pod or workload).
When debugging:
- Confirm that variables are present and have the expected values.
- Verify that changes to
ConfigMap/Secretare reflected only after pod restart/rollout. - Ensure that values are correctly typed or parsed by the application (since all env vars are strings).
For sensitive variables, be cautious: commands like oc describe and shell env output will show the values in plain text.
Best Practices Specific to Environment Variables
- Prefer environment variables for small, scalar values; use mounted files for complex config.
- Separate application configuration from code: use
ConfigMap/Secret+ env, not hard-coded values. - Avoid putting large or binary data into environment variables.
- Be deliberate about names:
- Use clear, consistent naming conventions (
APP_,DB_,SVC_prefixes). - Avoid overly generic names that may conflict with language/runtime defaults.
- Limit exposure of secrets in environment variables; if you must use them:
- Restrict access to
oc describeoutput (RBAC). - Limit where pods can run and who can
oc rshinto them. - Document required environment variables for each application so deployments across clusters and environments remain consistent.
- Use explicit
enventries to override or protect critical variables, even when usingenvFrom.
Environment variables are a central, flexible mechanism in OpenShift for connecting applications to their runtime environment. Used properly, they enable consistent deployments, safe configuration separation, and straightforward operational control across clusters and environments.