Docker学习之Dockerfile详解

Docker学习之Dockerfile详解

    上一篇学习了docker的基础,知道docker有三大概念,镜像,容器和仓库。使用第三方镜像不是学习docker的最终目的,最想要的还是要自己构建镜像。

    将自己的程序、文件、环境等构建成自己想要的应用镜像、方便后续部署、启动、维护。

    而Dockerfile就是做这件事情的,通过类似简单的编码形式,最终就可以构建出属于自己的镜像。

Dockerfile 是什么

Dockerfile 是用于构建Dokcer镜像的一种文本文件,该文件由一条条命令语句组成,记录着构建的每一个步骤。

    构建操作统一由Docker daemon进行,它会先对文件内容语法进行初步验证(语法不对就会返回错误信息),然后逐一运行指令。

    每次生成一个新的镜像层,直到执行完所有的指令,就构建出最终的镜像。

Docker学习之Dockerfile详解
架构

    通过架构图可以看出通过DockerFile可以直接构建镜像

Docker学习之Dockerfile详解
Docker执行Dockerfile大致流程

如何通过Dockerfile 构建镜像

    通过 docker build命令可以从文本、http、stdin等方式读取Dockerfile文件来构建镜像。

docker build -t phpfpm:1.0 -f ./Dockerfile .
-t    指定标签
-f    指定具体所使用的的Dockerfile
其中最后一个`.`,表示使用当前目录作为构建目录

    Tip: 不要使用根目录作为PATH构建上下文,因为它会导致构建将硬盘驱动器的全部内容传输到Docker

    构建完成后,可以使用docker images 进行查看。

Dockerfile 基本组成

    Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。

    一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

    指令一般格式为 INSTRUCTION arguments,指令包括 FROM

Dockerfile 关键字

FROM

    指定基础镜像,就是新镜像是基于哪一个镜像构建的。比如建房子,可以在一块空地,也可以在打好的基石基础上开始,也可以在建好的毛坯房上开始。也就是 FROM 空地,FROM 基石,FROM 毛坯房,最后把房子弄好就行。

格式:

FROM [--platform=<platform>] <image> [AS <name>]

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
  • 第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)。

  • AS name 表示为构建阶段命名,在后续 FROMCOPY --from= 说明中可以使用这个名词,引用此阶段构建的镜像。

  • tagdigest 值是可选的。如果忽略其中一个,构建器默认使用一个 latest 标签。如果找不到该 tag 值,构建器会返回错误。

  • --platform 标志可用于 FROM 引用多平台镜像的情况下指定平台。例如 linux/amd64、linux/arm64、windows/amd64

RUN

    将在当前镜像中执行任意合法的命令并提交执行结果,命令执行提交后,就会自动执行Dockerfile中的下一个指令。

    层级RUN指令和生成提交是符合Docker核心理念的做法。他允许像版本控制那样,在任意一个点,对image镜像进行定制化构建。

RUN有两种格式:

RUN <command>(shell形式,命令在 shell 中运行,默认/bin/sh -c在 Linux 或cmd /S /C Windows 上)
RUN ["executable""param1""param2"]

说明:

  • 在shell形式中,您可以使用(反斜杠)将单个 RUN 指令延续到下一行。例如,考虑以下两行:
RUN /bin/bash -c 'source $HOME/.bashrc; 
echo $HOME'
  

    它们连在一起相当于:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
  • RUN 在下一次构建期间,指令缓存不会自动失效。可以使用 –no-cache 标志使指令缓存无效。
  • Dockerfile 的指令每执行一次都会在 Docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大,可以使用 && 符号连接命令,这样执行后,只会创建 1 层镜像。

CMD

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

支持三种格式:
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2           在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"]             提供给 ENTRYPOINT 的默认参数。

    指定启动容器时要执行的命令,只有最后一个会生效;即根据镜像启动容器时,容器需要执行啥命令。

    主要目的是为正在执行的容器提供默认值,这些默认值可以包含可执行文件等其他指令。

LABEL

LABEL multi.label1="value1" 
      multi.label2="value2" 
      other="value3"

    该LABEL指令向图像添加元数据。ALABEL是键值对。要在LABEL值中包含空格,请像在命令行解析中一样使用引号和反斜杠。

EXPOSE

    指令通知 Docker 容器在运行时侦听指定的网络端口,可以指定端口是监听 TCP 还是 UDP,如果不指定协议,默认为 TCP。

EXPOSE <port> [<port>/<protocol>...]

EXPOSE 80/udp
EXPOSE 80/tcp

    该 EXPOSE 指令实际上并未发布端口。要在运行容器时实际发布端口,docker run -p 来发布和映射一个或多个端口。

ENV

 设置环境变量,值中包含空格,请像在命令行解析中一样使用引号和反斜杠。

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex The Dog
ENV MY_CAT=fluffy

ENV <key>=<value> ...

设置的环境变量将持续存在,您可以使用 docker inspect 来查看。使用docker run –env=来更改环境变量的值。

如果环境变量只在构建期间需要,请考虑为单个命令设置一个值:

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...

或者使用 ARG,它不会保留在最终镜像中:

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y ...

ADD

    复制新文件、目录或远程文件 URL,并将它们添加到中。

    可以指定多个资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源,也就是 WORKDIR。

    每个都可能包含通配符,匹配将使用 Go 的 filepath.Match 规则。例如:

添加所有以“hom”开头的文件:
ADD hom* /mydir/

? 被替换为任何单个字符,例如“home.txt”
ADD hom?.txt /mydir/

COPY

    语法和ADD一样,复制拷贝文件。

    COPY 和 ADD 的唯一区别在于是否支持从远程URL获取资源COPY 指令只能从执行 docker build 所在的主机上读取资源并复制到镜像中。而 ADD 指令还支持通过 URL 从远程服务器读取资源并复制到镜像中

    相同需求时,推荐使用 COPY 指令。ADD 指令更擅长读取本地tar文件并解压缩

VOLUME

    创建一个具有指定名称的挂载数据卷。

VOLUME ["/var/log/"]
VOLUME /var/log

它的主要作用是:

  • 避免重要的数据,因容器重启而丢失
  • 避免容器不断变大

WORKDIR

    工作目录,如果 WORKDIR 不存在,即使它没有在后续 Dockerfile 指令中使用,它也会被创建。

    docker build 构建镜像过程中,每一个 RUN 命令都会新建一层。只有通过 WORKDIR 创建的目录才会一直存在。

    可以设置多个 WORKDIR,如果提供了相对路径,它将相对于前一条 WORKDIR 指令的路径。例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

最终 pwd 命令的输出是 /a/b/c。

该 WORKDIR 指令可以解析先前使用 ENV,例如:

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

最终 pwd 命令的输出是 /path/$DIRNAME。

USER

    设置用户名(或 UID)和可选的用户组(或 GID)。

USER <user>[:<group>]
USER <UID>[:<GID>]

    详细的原理,在后续学习会做个整体的笔记记录,欢迎各位大佬评论留言讨论。

    如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我继续坚持下去,非常感谢!

    你还可以把我的公众号设为「星标」,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。

原文始发于微信公众号(白砂):Docker学习之Dockerfile详解

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19993.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!