Dockerfile 配置文件变量替换(两种常用方案)

日常容器内配置文件动态替换变量,主流分 构建时替换运行时替换,按需选择即可。

一、前置说明

假设场景:

容器内配置文件 /app/config.ini,内容如下,需要动态替换 ${APP_PORT}${APP_NAME}

[server]
name = ${APP_NAME}
port = ${APP_PORT}

方案 1:构建阶段替换(ENV + sed,构建时固定值)

适合:变量值打包进镜像,启动后不再修改

完整 Dockerfile

# 基础镜像
FROM centos:7

# 1. 定义构建/环境变量
ENV APP_NAME="demo-app" \
    APP_PORT="8080"

# 2. 复制原始配置文件到容器
COPY config.ini /app/config.ini

# 3. 使用 sed 全局替换变量(核心)
RUN sed -i "s/\${APP_NAME}/${APP_NAME}/g" /app/config.ini \
    && sed -i "s/\${APP_PORT}/${APP_PORT}/g" /app/config.ini

# 启动命令
CMD ["cat", "/app/config.ini"]

关键语法解释

  • sed -i:原地修改文件
  • s/原字符串/新字符串/g:全局匹配替换
  • 外层用双引号:才能解析 Docker ENV 变量(单引号不会解析变量)

构建 & 测试

# 构建镜像
docker build -t config-demo .

# 运行容器查看结果
docker run --rm config-demo

方案 2:运行阶段替换(ENTRYPOINT 脚本,启动时动态传参)

适合:同一镜像,不同容器用不同配置(推荐生产使用)

步骤 1:编写启动脚本 start.sh

和 Dockerfile、config.ini 放在同一目录

#!/bin/bash
# 启动前替换配置文件变量
sed -i "s/\${APP_NAME}/${APP_NAME}/g" /app/config.ini
sed -i "s/\${APP_PORT}/${APP_PORT}/g" /app/config.ini

# 执行容器真正的启动命令(示例:前台查看配置,替换为你的业务启动命令)
exec "$@"

步骤 2:Dockerfile

FROM centos:7

# 复制配置、启动脚本
COPY config.ini /app/config.ini
COPY start.sh /start.sh

# 赋予执行权限
RUN chmod +x /start.sh

# 入口脚本
ENTRYPOINT ["/start.sh"]

# 默认执行命令
CMD ["cat", "/app/config.ini"]

步骤 3:运行容器(动态传变量)

方式 1:docker run -e 传环境变量(最常用)

# 构建镜像
docker build -t config-runtime-demo .

# 动态指定变量启动
docker run --rm \
  -e APP_NAME="order-service" \
  -e APP_PORT="9090" \
  config-runtime-demo

方式 2:docker-compose 传变量(编排场景)

version: '3'
services:
  app:
    image: config-runtime-demo
    environment:
      APP_NAME: "user-service"
      APP_PORT: "8090"

进阶:通用模板(支持大量变量)

如果配置文件变量很多,统一写法:

  1. 配置文件统一用 ${变量名} 占位
  2. 启动脚本批量 sed 替换,或使用 envsubst(专门变量替换工具)

使用 envsubst(极简方案,推荐)

envsubst自动替换文件中所有 ${xxx} 环境变量,无需逐个写 sed。

改造 start.sh

#!/bin/bash
# envsubst 替换所有变量,输出到新文件覆盖原文件
envsubst < /app/config.ini.tpl > /app/config.ini

exec "$@"

Dockerfile 改动

把配置文件后缀改为 .tpl 模板:

FROM centos:7
# 安装 envsubst(centos 需装 gettext,alpine 需装 gettext-dev)
RUN yum install -y gettext && yum clean all

COPY config.ini.tpl /app/config.ini.tpl
COPY start.sh /start.sh
RUN chmod +x /start.sh

ENTRYPOINT ["/start.sh"]
CMD ["cat", "/app/config.ini"]

优点:新增变量不用改脚本,只需要在模板里加 ${变量} 即可。

选型总结

  1. 构建时替换(sed + ENV):变量固定、镜像单一,适合静态配置
  2. 运行时 sed 替换:灵活、兼容性强,所有基础镜像都能用
  3. 运行时 envsubst:变量多、模板复杂场景,代码最简洁(需预装工具)

Categories: docker与kubernetes