上一篇学习了docker的基础,知道docker有三大概念,镜像,容器和仓库。使用第三方镜像不是学习docker的最终目的,最想要的还是要自己构建镜像。
将自己的程序、文件、环境等构建成自己想要的应用镜像、方便后续部署、启动、维护。
而Dockerfile
就是做这件事情的,通过类似简单的编码形式,最终就可以构建出属于自己的镜像。
Dockerfile 是什么
“
Dockerfile 是用于构建Dokcer镜像的一种文本文件,该文件由一条条命令语句组成,记录着构建的每一个步骤。
”
构建操作统一由Docker daemon
进行,它会先对文件内容语法进行初步验证(语法不对就会返回错误信息),然后逐一运行指令。
每次生成一个新的镜像层,直到执行完所有的指令,就构建出最终的镜像。
通过架构图可以看出通过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 表示为构建阶段命名,在后续
FROM
和COPY --from=
说明中可以使用这个名词,引用此阶段构建的镜像。 -
tag
或digest
值是可选的。如果忽略其中一个,构建器默认使用一个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