不用重新构建镜像就能改写配置,核心是通过环境变量解耦配置与镜像:启动脚本替换模板、.env文件批量注入、中间件模板渲染、框架原生支持四种方式实现配置动态化。

不用重新构建镜像就能改写配置,核心是把“配置内容”和“镜像本身”解耦——环境变量就是这个解耦的关键桥梁。只要应用或启动脚本能读取环境变量,并在容器启动时动态生成或替换配置文件,就能做到配置随启随变。
用启动脚本做变量替换(最通用)
适用于任意语言的应用(Java/Python/Node.js等),原理简单:容器启动时执行一个 shell 脚本,读取环境变量,填充模板文件,再启动主进程。
- 准备一个配置模板,比如
app.conf.template,里面用${DB_HOST}、${LOG_LEVEL}这类占位符 - 编写
entrypoint.sh:用envsubst或sed把占位符替换成真实值,输出为最终的app.conf - Dockerfile 中设好
ENTRYPOINT ["./entrypoint.sh"],并确保模板和脚本都 COPY 进镜像 - 运行时只需
docker run -e DB_HOST=prod-db -e LOG_LEVEL=error myapp,配置就自动生效
用 .env 文件批量注入(适合多变量场景)
避免命令行写一长串 -e,把所有变量集中管理,既清晰又方便切换环境。
- 创建
dev.env和prod.env,内容格式为KEY=VALUE(支持注释和空行) - 启动时用
--env-file ./prod.env加载,Docker 会自动把文件里所有变量注入容器 - 搭配 docker-compose 更方便:
env_file: ./prod.env写进服务配置即可 - 注意:.env 文件别提交到 Git,加进
.gitignore,敏感值建议进一步用 secrets 替代
让 Nginx / Apache 等中间件支持变量(反向代理类服务)
原生 Nginx 不解析环境变量,但可以通过模板 + 启动时渲染来绕过限制。
- 把
nginx.conf改成nginx.conf.template,把proxy_pass http://${BACKEND_URL}这类写法保留 - 镜像内安装
envsubst(Debian/Ubuntu 用apt-get install gettext-base) - entrypoint 脚本中执行:
envsubst /etc/nginx/conf.d/default.conf && exec nginx -g "daemon off;" - 这样每次容器启动,Nginx 配置都是根据当前环境变量实时生成的
Spring Boot / Node.js 等框架直接读环境变量(零改造前提)
如果应用本身已支持外部化配置(如 Spring Boot 的 @Value("${db.url}") 或 Node.js 的 process.env.DB_URL),那就更简单了。
- 无需改代码、无需模板、无需脚本——只要确保环境变量名和代码里引用的一致
- 启动时传
-e DB_URL=jdbc:mysql://prod:3306/app,应用启动时自动加载 - 推荐配合
application.yml中使用${DB_URL:localhost:3306}设置默认值,增强容错性 - 注意优先级:系统环境变量 > application.yml 中的 ${} 占位符 > yml 文件里的硬编码值











