Dockerfile命令详解之 ARG

        许多同学不知道Dockerfile应该如何写,不清楚Dockerfile中的指令分别有什么意义,能达到什么样的目的,接下来我将在容器化专栏中详细的为大家解释每一个指令的含义以及用法。
专栏订阅传送门https://blog.csdn.net/qq_38220908/category_11989778.html

        指令不区分大小写。但是,按照惯例,它们应该是大写的,以便更容易地将它们与参数区分开来。(引用至官方文档>>>

        

        【开发云】年年都是折扣价,不用四处薅羊毛


语法

ARG <name>[=<default value>]

        ARG指令用于定义一个变量,用户可以在构建Docker镜像的时候,使用 --build-arg 定义变量的值。比如:

        我们新建一个Dockerfile文件,使用ARG定义参数username,这里我们没有赋予默认值

FROM ubuntu
ARG username
RUN echo $username

        然后我们使用以下命令构建镜像,我们可以看到RUN echo $username被替换成了RUN echo 清风怎不知意

docker build --build-arg username=清风怎不知意 -t myapp:tag-v0.0.1 .

来自Docker官方的警告:

        不建议在构建时使用ARG传递密钥、用户凭证等信息,因为构建时的信息是任何用户都可以通过docker history看到的!!!!!!!!!

         我们也可以使用 ARG username=默认姓名 赋予变量默认值。

        我们还可以利用ARG指令,声明基础镜像的版本,使其在构建的时候可以通过--build-arg选项对镜像版本进行修改,比如:

        Dockerfile

ARG BASE_VERSION=latest
FROM openjdk:$BASE_VERSION
RUN echo $BASE_VERSION

         当我们运行命令 docker build . 的时候,没有使用--build-arg 定义BASE_VERSION的值,所以BASE_VERSION取默认值latest,实际拉取的基础镜像版本是 openjdk:latest

         当我们运行命令docker build --build-arg BASE_VERSION=11 . 的时候,BASE_VERSION的值为11,所以实际拉取的镜像版本是 openjdk:11

 注意:

        在FROM指令前使用ARG指令定义的变量,只能用于FROM指令。所以,Dockerfile第三行的 RUN echo $BASE_VERSION指令,并未取到值!!!

作用域

        上面的例子我们可以看到,ARG声明的变量是有作用域限制的。接下来我们说说ARG指令定义变量的作用域。

1、与常规变量的定义一样,变量的生效时间,都是在被定义之后。

比如:

Dockerfile

FROM ubuntu

# 定义环境变量
ENV MYENV=test
RUN echo $MYENV

# 覆盖定义的环境变量
ARG MYENV
RUN echo $MYENV

使用以下命令构建镜像文件

docker build --build-arg MYENV=pre -t myapp:tag-v0.0.2 .

运行的结果为:

         第一次RUN 指令 echo 的值是test,第二次RUN指令 echo 的值是pre,我们可以看到ARG指令只影响到了其后面的变量值。

        如果我们构建镜像的时候,不指定参数值,那么ARG指令声明的MYENV变量的值,会以上面EVN指令定义的值为默认值

docker build -t myapp:tag-v0.0.2 .

        可以看到,两次RUN指令echo的值都是与ENV指令定义的值一样的

 2、 ARG指令声明的变量在当前构建阶段完成后失效

        相当于在函数内声明的变量,只能在该函数内生效。所以在进行多阶段构建时,每个阶段都必须重新使用ARG指令声明变量。

  • 错误使用方式

        多阶段构建Dockerfile

FROM ubuntu
ARG SETTINGS=12
RUN echo $SETTINGS

FROM ubuntu
RUN echo $SETTINGS

        使用以下命令构建镜像

docker build  --no-cache .

        我们可以看到,我们在第一阶段声明的SETTINGS参数,在第二阶段构建的时候,SETTINGS未取值

  • 正确使用方式        

         当我们为第二阶段使用ARG声明参数后,再次构建,可以看到,此时变量SETTINGS的值变为了22

        多阶段构建Dockerfile

FROM ubuntu
ARG SETTINGS=12
RUN echo $SETTINGS

FROM ubuntu
ARG SETTINGS=22
RUN echo $SETTINGS

        我们可以使用ARG或者ENV指令指定RUN指令可用的变量,但是ENV指令定义的环境变量,会覆盖ARG定义的同名变量

预定义变量

        Docker提供以下预定义变量

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

        针对以上预定义的变量,我们同样可以使用--build-arg给他们赋值,并且,这些预定义变量不会被docker history所记录,能够相对安全的保护这部分敏感信息。 

        如果我们需要改变预定义变量的行为,我们可以在Dockerfile中声明同名变量,比如我们在Dockerfile中使用指令 ARG HTTP_PROXY重新声明了预定义变量,这时候,我们在构建镜像的时候,docker history就会记录下它的值,失去对此信息的保护,并且,更改HTTP_PROXY的值会使构建的缓存失效。

[1]  感谢大佬 @kenllf 的斧正

Dockerfile 是用于构建 Docker 镜像的一种文本格式,包含了一系列指令来描述如何构建镜像。Dockerfile 的编写需要遵循一定的规范,包括指令、注释、变量和环境变量等。下面是 Dockerfile 进阶详解: 1. 使用 ARG 指令定义变量 使用 ARG 指令可以定义一个变量,可以在后续指令中使用。例如: ``` ARG VERSION=latest FROM ubuntu:${VERSION} ``` 在构建镜像时可以使用 --build-arg 参数来指定变量的值,例如: ``` docker build --build-arg VERSION=18.04 . ``` 2. 使用 ENV 指令定义环境变量 使用 ENV 指令可以定义环境变量,可以在容器运行时使用。例如: ``` ENV TZ=Asia/Shanghai ``` 3. 使用 WORKDIR 指令定义工作目录 使用 WORKDIR 指令可以定义工作目录,可以在容器运行时使用。例如: ``` WORKDIR /app ``` 4. 使用 COPY 和 ADD 指令复制文件 使用 COPY 和 ADD 指令可以复制本地文件到镜像中。COPY 只能复制本地文件,ADD 还支持 URL 和 tar 包的复制。例如: ``` COPY index.html /var/www/html/ ADD http://example.com/file.tar.gz /tmp/ ``` 5. 使用 CMD 和 ENTRYPOINT 指令定义容器启动命令 使用 CMD 和 ENTRYPOINT 指令可以定义容器启动命令,其中 ENTRYPOINT 可以和 CMD 配合使用。例如: ``` ENTRYPOINT ["/bin/sh", "-c"] CMD ["echo", "Hello World"] ``` 6. 使用 EXPOSE 指令定义端口 使用 EXPOSE 指令可以定义容器监听的端口,但并不会自动映射到主机。例如: ``` EXPOSE 80 ``` 7. 使用 FROM 指令选择基础镜像 使用 FROM 指令可以选择基础镜像,可以使用特定的版本或者 latest。例如: ``` FROM ubuntu:18.04 ``` 8. 使用 RUN 指令执行命令 使用 RUN 指令可以在镜像中执行命令。例如: ``` RUN apt-get update && apt-get install -y nginx ``` 9. 使用 LABEL 指令定义元数据 使用 LABEL 指令可以定义镜像的元数据,可以用于查询和过滤镜像。例如: ``` LABEL maintainer="John Doe <john.doe@example.com>" ``` 以上是 Dockerfile 进阶的一些指令和用法,可以帮助你更好地构建镜像。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值