docker环境变量动态覆盖分构建时和运行时两阶段:构建时用--build-arg覆盖arg(仅构建期生效、不进镜像),运行时用-e/--env覆盖env(可被容器启动时覆盖、写入镜像)。
docker 环境变量的动态覆盖分两个阶段:构建时(影响镜像生成)和运行时(影响容器启动),对应不同机制和命令,不能混用。
构建时覆盖:用 --build-arg 覆盖 ARG 变量
ARG 是仅在 docker build 阶段生效的构建参数,常用于版本号、构建环境等。它支持默认值,且可通过 --build-arg 覆盖。
- Dockerfile 中声明带默认值的 ARG:
ARG APP_VERSION=1.2.0
ARG BUILD_ENV=staging
RUN echo "Building ${APP_VERSION} for ${BUILD_ENV}"
- 构建时覆盖任意组合:
docker build --build-arg APP_VERSION=2.0.0 --build-arg BUILD_ENV=production -t myapp .
- 未传参的 ARG 仍使用默认值;未设默认值又没传参,该变量为空(可能引发构建失败,建议都设默认值)
- ARG 变量不会出现在最终镜像里,安全性高
运行时覆盖:用 -e 或 --env 覆盖 ENV 变量
ENV 是在镜像中写死或构建时设定的运行时环境变量,容器启动时可被 -e 或 --env 覆盖。
- Dockerfile 中预设 ENV(非必须,但常见):
ENV DATABASE_URL=sqlite:///dev.db
ENV LOG_LEVEL=info
- 启动容器时覆盖:
docker run -e DATABASE_URL=postgres://user:pass@db:5432/app -e LOG_LEVEL=debug myapp
- 也可以从宿主机继承环境变量:
docker run --env HOSTNAME --env USER myapp - 若 Dockerfile 中 ENV 和
-e同名,-e的值优先
Docker Compose 中的变量覆盖优先级
在 docker-compose.yml 中,环境变量来源有多个,覆盖顺序固定:
- 最高优先级:命令行传入的环境变量,如
DEPLOY_ENV=prod docker-compose up - 其次:compose 文件中
environment:下直接定义的键值对 - 再其次:通过
env_file:加载的文件(按列表顺序,后加载的覆盖先加载的) - 最低:项目根目录下的
.env文件(自动加载,仅用于默认值)
例如,docker-compose.yml 中写:
environment:
- ENVIRONMENT=${DEPLOY_ENV:-development}
env_file:
- .env.common
- .env.${DEPLOY_ENV}
此时 ${DEPLOY_ENV} 若未在命令行或系统环境里设置,就取默认值 development,再加载 .env.development 补充配置。
注意事项与避坑点
- ARG 和 ENV 用途不同:ARG 不进镜像,只管“怎么建”;ENV 进镜像,管“怎么跑”
- 敏感信息(密码、密钥)不要写死在 Dockerfile 的 ENV 里,应通过
-e或env_file外部注入,并确保文件不提交到 Git - 变量名大小写敏感,
--build-arg Version=1.0无法覆盖ARG version=0.9 - Compose 中的
${VAR:-default}语法只在 compose 解析时生效,不是 Shell 扩展,不支持嵌套











