Config Basics
This section covers the hands-on mechanics of injecting configuration into containers: creating ConfigMaps and Secrets, wiring them into Pods as environment variables or files, and setting sane defaults.
Search across all documentation pages
This section covers the hands-on mechanics of injecting configuration into containers: creating ConfigMaps and Secrets, wiring them into Pods as environment variables or files, and setting sane defaults.
kubectl configured against a namespace you can write to.# Confirm your context and namespace before you start
kubectl config current-context
kubectl get nsThe fastest way to hold non-secret config.
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
--from-literal=FEATURE_BETA=false--from-literal is fine for a few keys; use files for many.kubectl get configmap app-config -o yaml.Good for config files that the app reads whole.
kubectl create configmap nginx-conf \
--from-file=nginx.conf=./nginx.conf--from-env-file=app.env to load many KEY=value lines at once.Reference one key explicitly.
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVELLOG_LEVEL in its process environment.optional: true.Project every key at once.
envFrom:
- configMapRef:
name: app-configapp-config becomes an env var with the same name.prefix: APP_ to namespace the variables and avoid collisions.Secrets use the same shape as ConfigMaps but signal sensitivity.
kubectl create secret generic app-db \
--from-literal=username=app \
--from-literal=password='s3cr3t-rotate-me'secretKeyRef, mirroring configMapKeyRef.Files, not env vars, when you need live updates.
volumes:
- name: config
configMap:
name: nginx-conf
containers:
- name: web
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
readOnly: truemountPath.readOnly: true so the container cannot alter its own config.Ship a sane default in the image, override at run time.
# A non-secret default baked into the image
ENV LOG_LEVEL=infoENV value is the fallback if nothing else is set.env or envFrom overrides it per environment.ENV - they persist in image layers.Force a rolling update when config changes.
spec:
template:
metadata:
annotations:
checksum/config: "REPLACE_WITH_SHA_OF_CONFIGMAP"{{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}.Lock a Secret so it cannot be edited in place.
apiVersion: v1
kind: Secret
metadata:
name: app-db
immutable: true
type: Opaque
data:
password: czNjcjN0LXJvdGF0ZS1tZQ==immutable: true blocks updates, preventing accidental edits.Match the injection model in local development.
services:
api:
image: app:dev
environment:
LOG_LEVEL: debug
env_file:
- ./local.envenvironment mirrors explicit env vars; env_file mirrors envFrom.local.env in .gitignore so local secrets never get committed.Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026