Dockerfile中的ARG指令详解

Dockerfile中的ARG指令用以定义构建时需要的参数,使用格式如下:

[html]  view plain  copy
  1. ARG a_name  
  2. ARG a_nother_name=a_default_value  

ARG指令定义的参数,在docker build命令中以--build-arg a_name=a_value形式赋值。

如果docker build命令传递的参数,在Dockerfile中没有对应的参数,将抛出如下警告:

[html]  view plain  copy
  1. [Warning] One or more build-args [foo] were not consumed.  

如果在Dockerfile中,ARG指令定义参数之前,就有其他指令引用了参数,则参数值为空字符串。
不建议在构建的过程中,以参数的形式传递保密信息,如key, password等。


Docker自带的如下ARG参数,可以在其他指令中直接引用:

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • FTP_PROXY
  • ftp_proxy
  • NO_PROXY
  • no_proxy

参考链接:

https://docs.docker.com/engine/reference/builder/

<think>我们正在讨论Dockerfile中的ARG和CMD指令,它们的作用和区别。 根据用户提供的引用和之前的上下文,我们来分析: 1. ARG指令: - 用于定义构建时的变量,这些变量仅在构建阶段有效。 - 可以在构建时通过`--build-arg`参数覆盖默认值。 - 一旦镜像构建完成,容器运行时这些变量将不再存在。 - 示例:在Dockerfile中定义`ARG HTTP_VERSION=2.4.58`,然后在构建时可以通过`docker build --build-arg HTTP_VERSION=1.18.0 ...`来覆盖。 2. CMD指令: - 用于指定容器启动时默认执行的命令及其参数。 - 每个Dockerfile中只能有一个CMD指令(如果有多个,则只有最后一个生效)。 - 主要目的是为容器提供默认的执行命令,可以在运行容器时被覆盖。 - 有三种形式: - CMD ["executable","param1","param2"] (exec形式,推荐) - CMD ["param1","param2"] (作为ENTRYPOINT的默认参数) - CMD command param1 param2 (shell形式) - 示例:`CMD nginx -g "daemon off;"` 或 `CMD ["nginx", "-g", "daemon off;"]` 区别总结: - 作用阶段:ARG在构建阶段使用,CMD在容器运行时使用。 - 生命周期:ARG只在构建期间有效,构建完成后在容器中不可用;CMD在容器启动时执行,并成为容器的主进程(除非被覆盖)。 - 覆盖方式:ARG通过构建命令`docker build --build-arg`覆盖;CMD通过运行命令`docker run [image] [command]`覆盖。 另外,用户提供的引用[2]中提到了ENTRYPOINT和CMD,虽然问题只问了CMD,但可以简单提一下ENTRYPOINT与CMD的关系:CMD可以为ENTRYPOINT提供默认参数,两者结合使用。 下面我们按照要求,用清晰的结构回答用户问题,并生成相关问题。</think>### Dockerfile 中 `ARG` 和 `CMD` 指令的区别详解 #### 1. **作用阶段不同** - **`ARG`**:仅在**构建阶段**生效 用于定义构建时的变量,这些变量在镜像构建完成后即消失。例如: ```dockerfile ARG HTTP_VERSION=2.4.58 # 定义构建变量 FROM nginx:${HTTP_VERSION} # 构建时使用 ``` 构建时可通过 `docker build --build-arg HTTP_VERSION=1.18.0` 覆盖默认值[^1]。 - **`CMD`**:仅在**容器运行时**生效 定义容器启动时的默认执行命令,例如: ```dockerfile CMD ["nginx", "-g", "daemon off;"] # 容器启动时执行 ``` 运行时可被 `docker run [image] [自定义命令]` 覆盖[^2]。 #### 2. **生命周期不同** | 指令 | 生效阶段 | 容器中是否可见 | 是否可被覆盖 | |-------|----------------|----------------|--------------------| | `ARG` | 镜像构建过程 | ❌ 不可见 | ✅ 通过 `--build-arg` | | `CMD` | 容器启动时 | ✅ 可见 | ✅ 通过 `docker run` | #### 3. **用途差异** - **`ARG` 的典型场景**: - 动态指定软件版本(如 `FROM nginx:${VERSION}`) - 参数化安装命令(如 `RUN apt-get install ${PACKAGE}`) - 减少重复构建不同配置的镜像 - **`CMD` 的典型场景**: - 定义容器主进程(如 Web 服务器、数据库) - 提供默认启动参数(如 `CMD ["python", "app.py"]`) - 与 `ENTRYPOINT` 配合使用(`CMD` 作参数) #### 4. **执行示例对比** 假设 Dockerfile 包含: ```dockerfile ARG APP_PORT=8080 CMD ["python", "app.py", "--port=${APP_PORT}"] ``` - **构建阶段**:`APP_PORT` 被解析(默认 8080),但 `${APP_PORT}` 在 `CMD` 中**不会替换**(因为 `ARG` 在构建后消失) - **运行阶段**:直接执行 `python app.py --port=${APP_PORT}`,导致 `${APP_PORT}` 作为字面字符串传递(可能报错) > 💡 正确做法:若需运行时使用变量,应改用 `ENV` 指令定义环境变量。 #### 5. **综合对比表** | 特性 | `ARG` | `CMD` | |--------------|--------------------------------|--------------------------------| | 作用域 | Dockerfile 构建阶段 | 容器运行时 | | 持久性 | 构建后消失 | 持续到容器停止 | | 覆盖方式 | `docker build --build-arg` | `docker run [自定义命令]` | | 多指令处理 | 可定义多个 | 仅最后一个生效 | | 典型用途 | 参数化构建过程 | 定义容器主进程 | ### 关键总结 - **`ARG` 是构建期的“临时工”**:负责在创建镜像时传递动态值,任务完成即退出舞台[^1]。 - **`CMD` 是运行时的“导演”**:指挥容器启动后的主进程,但允许现场改剧本(覆盖命令)[^2]。 - **永远不相交**:`ARG` 变量在运行时不可用,`CMD` 命令在构建时不执行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值