1、镜像的定制实际上就是 定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作 的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复 的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile

2、Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令 构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

3、以nginx镜像为例:(我们要在nginx这个镜像的基础上,修改nginx的index.html文件,然后写成一个dockerfile。然后运行该dockerfile并构建为一个新的镜像)
创建了一个dockerfile文件,并在其中写入里两行。
图片说明

FROM 指定基础镜像。因此一个 Dockerfile 中 FROM 是必备的指令,并 且必须是第一条指令。除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch 。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。

RUN 指令是用来执行命令行命令的。,Dockerfile 中每一个指令都会建立一层, RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行 这些命令,执行结束后, commit 这一层的修改,构成新的镜像。Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是 不得超过 127 层。

在撰写 Dockerfile 的时候,要经常提醒自 己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。 并且,这里为了格式化还进行了换行。Dockerfile 支持 Shell 类的行尾添加 \ 的 命令换行方式,以及行首 # 进行注释的格式。良好的格式,比如换行、缩进、注 释等,会让维护、排障更为容易,这是一个比较好的习惯

构建镜像:
在 Dockerfile 文件所在目录执行:
docker build -t nginx:wuyonghu-v1 .
这样就构建了一个名为nginx:wuyonghu-v1的镜像。
图片说明

现在运行nginx:wuyonghu-v1的镜像
图片说明

然后使用浏览器,打开82端口,如果正常,则说明使用dockerfile构建新的镜像并启动成功。
图片说明

4、镜像构建上下文
图片说明
如果注意,会看到 docker build 命令最后有一个 . 。 . 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为这个路径是在指定 Dockerfile 所在路径,这么理解其实是不准确的。如果对应上面的命令格式, 你可能会发现,这是在指定上下文路径。那么什么是上下文呢?

Docker 在运行时分为 Docker 引擎 (也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API, 被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这63
使用 Dockerfile 定制镜像 组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在 本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端 (Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引 擎变得轻而易举。

docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎 中构建的。

当构建的时候,用户会指定构建镜像上下文的路径, docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上 传给 Docker 引擎。

一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果 该目录下没有所需文件,那么应该把所需文件复制一份过来。如果目录下有些东西 确实不希望构建时传给 Docker 引擎,那么可以用 .gitignore 一样的语法写一 个 .dockerignore ,该文件是用于剔除不需要作为上下文传递给 Docker 引擎 的。