envsubst: Substitute Env Vars Into Templates
envsubst reads text on stdin and replaces $VAR and ${VAR} references with their environment values.
envsubst (from GNU gettext) is the smallest possible config templater. It is everywhere, but its willingness to expand every $-looking token is also its main foot-gun.
What it does
envsubst copies stdin to stdout, replacing shell-style variable references with values from the environment. Given a list of variable names, it only substitutes those and leaves every other $token untouched.
Common usage
export IMAGE=nginx:1.27 REPLICAS=3
envsubst < deploy.tmpl.yaml > deploy.yaml
# only expand the two variables you mean, leave the rest literal
envsubst '$IMAGE $REPLICAS' < deploy.tmpl.yaml > deploy.yamlOptions
| Argument | What it does |
|---|---|
| SHELL-FORMAT | A string listing $VARs to expand; all other $tokens are left as-is |
| -v, --variables | Print the variables referenced in SHELL-FORMAT, one per line |
| (stdin) | Template is read from standard input; output goes to stdout |
In CI
Always pass an explicit variable list like envsubst '$IMAGE $TAG'. Without it, envsubst expands every $-prefixed token in the file, so a Bash-style ${HOME} inside a script block or a $1 in an nginx config gets clobbered. Render before apply and diff the output.
Common errors in CI
The classic failure is silent: a $something you did not mean to expand becomes an empty string because that variable is unset, leaving image: with no value and a later "mapping values are not allowed" YAML error downstream. envsubst never errors on an unset variable; it substitutes empty. Restrict the variable list and grep the rendered file for stray $ before applying.