云计算-8-Dockerfile深度解析


  • ARG和ENV

  • ARG

  • ENV

  • **RUN 和 ENTRYPOINT**区别

  • **使用 RUN 指令安装应用和软件包,构建镜像**

  • **ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 `docker run`时指定了其他命令)**

  • **ADD和COPY**

  • COPY

  • ADD

  • **EXPOSE**


ARG和ENV

ARG

ARG用于设置环境变量,只在build期间生效,run期无效

  • 例子:构建arg_1的Dockerfile,我们还是以nginx为例,
FROM nginx
ARG arg1=22222
RUN echo 'echo "<h1>$1, Docker!</h1>" > /usr/share/nginx/html/index.html' > ./entrypoint.sh \
&& chmod +rwx ./entrypoint.sh \
&& ./entrypoint.sh $arg1
  • 以上例子,我们构建镜像
docker build -t mynginx:v1  -f /root/arg_1 .
  • 运行镜像
docker run -it --name mynginx_arg1 -p 8881:80 -d mynginx:v1
  • 看出运行结果:

云计算-8-Dockerfile深度解析全_html

ARG指定的变量,在构建镜像的时候使用​​--build-arg <参数名> =值​​进行传递,会覆盖Dockerfile 中指定的同名参数

Dockerfile脚本还是上面的脚本,不过就是我们在构建的时候进行传递参数

  • 使用--build-arg传递ARG设置的参数
docker build -t mynginx:v2 --build-arg arg1=hahahah -f /root/arg_1 .
  • 运行 mynginx:v2镜像
docker run -it --name mynginx_arg2 -p 8882:80 -d mynginx:v2

云计算-8-Dockerfile深度解析全_docker_02

灵活使用​​ARG​​指令,可以在不修改Dockerfile的情况下,构建不同镜像

就像上面展示的,我们可以在构建镜像的时候,给参数传递不同的值,构建出不同的镜像

ENV

存在两种格式

  • ENV
  • ENV==...

ENV指令和ARG指令特别相似,ARG在build的时候生效,ENV在 run的时候生效,都可以直接使用这里定义的环境变量。

docker run --env 可以修改这些值

  • 构建env_1的Dockerfile,我们还是以nginx为例
FROM nginx
ARG arg1=1111
ENV arg2=2222
RUN echo 'echo "<h1>$1,$2, Docker!</h1>" > /usr/share/nginx/html/index.html' > ./entrypoint.sh \
&& chmod +rwx ./entrypoint.sh \
&& ./entrypoint.sh $arg1 $arg2
  • 构建镜像
docker build -t mynginx:v3 --build-arg arg1=envtest -f /root/env_1 .
  • 运行mynginx:v3镜像
docker run -it --name mynginx_env1 -p 8883:80 --env arg2=envtest2 -d mynginx:v3
  • 查看结果

云计算-8-Dockerfile深度解析全_docker_03

我们发现我们在​​docker run​​的时候​使用--env​​的时候修改了arg2参数,但是没有生效

云计算-8-Dockerfile深度解析全_docker_04

为什么我们在docker run使用--env指令的时候没有生效呢?​这是因为Dockerfile中​RUN 和 ENTRYPOINT​存在区别

RUN 和 ENTRYPOINT​区别

使用 RUN 指令安装应用和软件包,构建镜像

从上面 的ENV和ARG构建镜像的例子我们可以看出来,RUN是在构建镜像的时候生效的,生效以后文件​已经​生效,在docker run的时候,指令就不能再修改参数了

ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 ​​docker run​​时指定了其他命令)

  • 修改Dockerfile文件env_1为env_2脚本如下
FROM nginx
ENV arg2=2222
ENTRYPOINT echo 'echo "<h1>$1, Docker!</h1>" > /usr/share/nginx/html/index.html' > ./entrypoint.sh \
&& chmod +rwx ./entrypoint.sh \
&& ./entrypoint.sh $arg2 \
&& exec nginx -g 'daemon off;'
  • 构建镜像
docker build -t mynginx:v4 --build-arg  -f /root/env_2 .
  • 运行mynginx:v4
docker run -it --name mynginx_env4 -p 8884:80 --env arg2=envtest2 -d mynginx:v4

云计算-8-Dockerfile深度解析全_html_05

ADD和COPY

COPY

格式:

  • COPY [--chown=:] <源路径>... <目标路径>

  • COPY [--chown=:] ["<源路径1>",... "<目标路径>"]

它和RUN一样,有两种格式,一种类似命令,一种类似函数调用,​​COPY​​​指令将从构建上下文目录​​源路径​​的文件、目录复制到新的一层

镜像内的 ​​<目标路径>​​ 位置。

  • 构建镜像文件copy_1
FROM nginx
COPY index.html /usr/share/nginx/html/index.html
  • 创建index.html
vi index.html

index.html内容

<h1>copy test, Docker!</h1>
  • 构建镜像
docker build -t mynginx:v5  -f /root/add/copy_1 .
  • 运行镜像
docker run -it --name mynginx_copy -p 8885:80 -d mynginx:v5

查看运行结果

云计算-8-Dockerfile深度解析全_docker_06

ADD

同COPY用法,不过 ADD拥有自动下载远程文件和解压的功能。

  • src 路径必须在构建的上下文中;不能使用 ../something /something 这种方式,因为docker

  • 构建的第一步是将上下文目录(和子目录)发送到docker守护程序。

  • 如果 src 是URL,并且 dest 不以斜杠结尾,则从URL下载文件并将其复制到 dest 。

  • 如果 dest 以斜杠结尾,将自动推断出url的名字(保留最后一部分),保存到 dest

  • 如果 src 是目录,则将复制目录的整个内容,包括文件系统元数据。

EXPOSE

格式为 ​​EXPOSE <端口1> [<端口2>...]​​。

  • EXPOSE指令通知Docker容器在运行时在指定的网络端口上进行侦听。可以指定端口是侦听TCP还

是UDP,如果未指定协议,则默认值为TCP。

  • EXPOSE指令实际上不会发布端口。它充当构建映像的人员和运行容器的人员之间的一种文档,即

有关打算发布哪些端口的信息。要在运行容器时实际发布端口,请在docker run上使用-p标志发布

并映射一个或多个端口,或使用-P标志发布所有公开的端口并将其映射到高阶端口

如果您觉得本文不错,​欢迎关注,点赞,收藏支持​,您的关注是我坚持的动力!

​​ 公众号 springboot葵花宝典 ​ 主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术,以及Github开源项目

原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!