ARG仅在构建阶段有效,用于传版本号等临时参数且不存入镜像;ENV作用于构建及运行阶段,变量持久化并可被容器应用读取,两者需按生命周期正确配合使用。

ARG 和 ENV 看似都能设变量,但用错地方会导致构建失败、镜像臃肿,甚至泄露敏感信息。关键不是“能不能用”,而是“该在哪个阶段起作用”。
ARG 专管构建时的事
它只活在 docker build 过程中,一建完就消失,镜像里查不到、容器里也读不到。
- 适合传版本号、编译开关、临时路径等一次性参数,比如
ARG NODE_VERSION=18配合FROM node:${NODE_VERSION}-alpine - 必须在
FROM之前声明,才能被基础镜像标签引用;若在多阶段构建中使用,每个阶段都要重新写ARG - 支持默认值(如
ARG BUILD_ENV=production),没传参也不会报错;不设默认值又没传参,变量就是空字符串
ENV 负责运行时的配置
它写进镜像层,容器启动后依然存在,应用能通过 os.Getenv() 或 process.env 直接读取。
MiniMax 图片理解 + 网络搜索 MCP 工具。适配 Docker 环境(极空间等),支持图片 OCR 识别、图像内容理解、网络搜索。API Key 安全存储在本地 credentials 文件,不暴露在代码中。
- 常用于设置
NODE_ENV=production、PORT=3000、PATH=/app/bin:$PATH这类影响程序行为的变量 - 值会保留在镜像元数据中,执行
docker inspect或进入容器后printenv都能看到 - 运行时可用
docker run -e DB_HOST=10.0.1.5动态覆盖,比改 Dockerfile 更灵活
两者配合才真正高效
单独用 ARG 或 ENV 都有局限,组合起来既能控制构建过程,又能传递运行配置。
- 用 ARG 接收外部输入,再赋给 ENV:
ARG APP_VERSION→ENV APP_VERSION=${APP_VERSION},既避免硬编码,又让版本号在容器里可用 - 敏感信息(如数据库密码)别直接写进 ENV;可先用 ARG 传入,再通过构建时挂载或 BuildKit 的 secret 机制注入,确保不落盘
- 不要用 ENV 去控制构建逻辑(比如
ENV BUILD_MODE=dev然后RUN if [ "$BUILD_MODE" = "dev" ]; then ...),这会让镜像不可复现——应该用 ARG 替代
容易踩的坑
很多问题其实就出在混淆了生命周期和可见范围。
-
FROM ubuntu:${VERSION}却把ARG VERSION写在FROM后面 → 构建时报错:unknown argument - 把密钥写成
ENV API_KEY=xxx→ 镜像一推到仓库,所有人都能docker inspect看到 - 在 Dockerfile 开头写
ENV BUILD_TIME=$(date)→ 实际不会执行命令,ENV 不支持运行时求值,只会字面量存为字符串

















