envsubst: Usage, Options & Common CI Errors
envsubst replaces ${VAR} references in text with the values from the environment.
envsubst renders config templates (k8s manifests, nginx configs, .env files) by filling in environment variables. Its surprise is that, by default, it replaces every ${VAR} it sees - including ones you wanted left alone.
What it does
envsubst (from GNU gettext) reads stdin, replaces $VAR and ${VAR} references with their environment values, and writes the result to stdout. It is the lightweight templating step for rendering config files in CI.
Common usage
envsubst < template.conf > rendered.conf
export HOST=api.example.com PORT=443
envsubst < nginx.conf.tpl > nginx.conf
# only substitute specific variables (leave others literal):
envsubst '${HOST} ${PORT}' < template > out
cat deploy.tpl.yaml | envsubst | kubectl apply -f -Options
| Item | What it does |
|---|---|
| (default) | Substitute every $VAR / ${VAR} found |
| '${A} ${B}' | Restrict substitution to listed variables |
| -v / --variables | List the variables a template references |
| < in > out | Read template from stdin, write to stdout |
Common errors in CI
envsubst with no argument replaces ALL ${...} tokens, so a $HOME or a shell-style ${PRICE} you meant to keep gets blanked when the variable is unset - restrict it by passing the exact list: envsubst '${HOST} ${PORT}'. Unset variables substitute to empty strings silently (no error), which can produce invalid YAML - set -u in the surrounding script does NOT catch this. "envsubst: command not found" means gettext is not installed (common on Alpine: apk add gettext).