直接用envsubst是最轻量可靠的方式,但需规避nginx内置变量被误删、未定义变量变空、白名单维护困难三类问题:默认模式会清空未定义变量及$host等内置变量;白名单模式仅替换指定变量,保留其余内容;默认值应写为${var:-default}并确保环境存在该完整变量名。

直接用 envsubst 读取模板、替换环境变量、输出配置文件,是最轻量也最可靠的方式。关键不是“能不能用”,而是“怎么用才不出错”——尤其要避开 Nginx 变量被误删、未定义变量变空、白名单维护困难这三类高频问题。
基础替换:默认模式最简单,但有风险
不加参数时,envsubst 会扫描输入中所有 $VAR 和 ${VAR} 并尝试替换:
envsubst nginx.conf- 所有已定义的环境变量(如
PORT=8080)会被填入对应位置 - 未定义变量(如
${DB_PASSWORD})会被替换成空字符串——这会导致配置语法错误 -
特别注意:Nginx 配置里常见的
$host、$remote_addr等内置变量也会被当成环境变量清空,造成服务启动失败
安全替换:限定变量范围,避免误伤
用引号包裹需替换的变量名列表,只处理明确列出的项:
envsubst '${APP_HOST} ${APP_PORT} ${API_TIMEOUT}' nginx.conf- 变量名之间用空格或逗号分隔,支持
${VAR}和$VAR两种写法 - 未在列表中的内容(包括 Nginx 内置变量、未定义变量)原样保留,配置更健壮
- 适合变量数量固定、角色清晰的场景,比如 Docker 启动脚本中预设好几个关键参数
兜底处理:给未定义变量设默认值
模板里直接用 Bash 参数扩展语法,让缺失变量不为空:
- 写成
${APP_PORT:-8080},若APP_PORT未设置,就用8080 - 写成
${LOG_LEVEL:-info},避免日志级别丢失导致应用异常 - 这种写法不依赖
envsubst特性,所有 Shell 兼容,推荐作为模板编写规范 - 注意:原生
envsubst不解析:-逻辑,它只是把整个${APP_PORT:-8080}当作一个变量名去查——所以必须确保环境里真有这个完整名字,或改用增强版工具
工程化配合:和 .env 文件 + 启动脚本联动
把变量集中管理,避免散落在命令行或 CI 脚本里:
- 准备
.env文件:APP_HOST=prod.example.com、APP_PORT=3000 - 启动时先加载:
set -a; source .env; set +a(set -a让后续变量自动导出为环境变量) - 再执行替换:
envsubst /etc/nginx/nginx.conf - Docker 场景下,可把该流程写进容器
entrypoint.sh,实现镜像一次构建、多环境运行











