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.
Prerequisites
- Kubernetes 1.36.2 cluster access with
kubectlconfigured against a namespace you can write to. - Docker Engine 29.6.1 with BuildKit for local build and Compose testing.
- Helm 3 if you template config into charts (optional for these examples).
- Basic familiarity with Pods and Deployments.
# Confirm your context and namespace before you start
kubectl config current-context
kubectl get nsBasic Examples
1. Create a ConfigMap from literals
The fastest way to hold non-secret config.
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
--from-literal=FEATURE_BETA=false- Stores plain key-value pairs in a namespaced object.
- Values are visible to anyone with read access - never put secrets here.
--from-literalis fine for a few keys; use files for many.- View it with
kubectl get configmap app-config -o yaml.
2. Create a ConfigMap from a file
Good for config files that the app reads whole.
kubectl create configmap nginx-conf \
--from-file=nginx.conf=./nginx.conf- The key becomes the filename when mounted as a volume.
- Keeps the original file structure intact.
- Use
--from-env-file=app.envto load manyKEY=valuelines at once. - Ideal for reverse-proxy configs, app settings files, and templates.
3. Inject a single ConfigMap key as an env var
Reference one key explicitly.
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL- The container sees
LOG_LEVELin its process environment. - Captured once at container start; a later ConfigMap edit is not reflected until restart.
- Explicit mapping keeps the container contract clear and reviewable.
- Missing keys fail the Pod unless you mark them
optional: true.
4. Load an entire ConfigMap with envFrom
Project every key at once.
envFrom:
- configMapRef:
name: app-config- Every key in
app-configbecomes an env var with the same name. - Add
prefix: APP_to namespace the variables and avoid collisions. - Convenient, but less explicit than per-key references.
- Invalid environment-variable names are skipped and logged as events.
5. Create a Secret for sensitive values
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'- Stored base64-encoded in etcd - encoding, not encryption.
- Enable encryption at rest and RBAC to actually protect them.
- Consume with
secretKeyRef, mirroringconfigMapKeyRef. - Do not commit the generated YAML to Git.
6. Mount config as files via a volume
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: true- Each ConfigMap key appears as a file under
mountPath. - The kubelet updates mounted files in place after the ConfigMap changes.
- Mount
readOnly: trueso the container cannot alter its own config. - Env vars cannot do live updates; files can.
7. Provide defaults you can override
Ship a sane default in the image, override at run time.
# A non-secret default baked into the image
ENV LOG_LEVEL=info- The
ENVvalue is the fallback if nothing else is set. - A Pod-level
envorenvFromoverrides it per environment. - Never place secrets in
ENV- they persist in image layers. - This keeps one image usable across every environment.
Intermediate Examples
8. Mark a Deployment config-aware with a checksum annotation
Force a rolling update when config changes.
spec:
template:
metadata:
annotations:
checksum/config: "REPLACE_WITH_SHA_OF_CONFIGMAP"- The annotation is computed from the ConfigMap contents at render time.
- When config changes, the checksum changes, and Kubernetes rolls the Pods.
- Helm users generate it with
{{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}. - This bridges env-var config, which otherwise never reloads, to config changes.
9. Make a Secret immutable
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: trueblocks updates, preventing accidental edits.- Immutable Secrets reduce kube-apiserver watch load at scale.
- To change the value, create a new Secret and update references.
- The same field works for ConfigMaps.
10. Local parity with Compose
Match the injection model in local development.
services:
api:
image: app:dev
environment:
LOG_LEVEL: debug
env_file:
- ./local.envenvironmentmirrors explicit env vars;env_filemirrorsenvFrom.- Keeps local and cluster config-injection patterns aligned.
- Keep
local.envin.gitignoreso local secrets never get committed. - Test config wiring here before it reaches the cluster.
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).