构建镜像的方式:
- 通过 docker commit 命令将修改的容器固化成镜像
- 利用Dockerfile 和 docker build 命令自动化的构建镜像
Dockerfile的官网描述
Docker can build images automatically by reading the instructions from a Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Using docker build users can create an automated build that executes several command-line instructions in succession.
这是官网对Dockerfile的概述,简言之:Dockerfile就是包含了所有用来组织镜像的指令集合的文本文件,Docker会在构建镜像时读取这个文件并自动执行里面的指令,完成镜像的构建。
Dockerfile的使用说明
The docker build command builds an image from a Dockerfile and a context.
docker build 命令从Dockerfile和context上下文构建一个镜像。
# Dockerfile 在当前context上下文目录中
docker build {context}
# -f 选项可以指定Dockerfile的路径,依照传统Dockerfile命名为Dockerfile,-f 可以指定任意名称
docker build -f {Dockerfile Path} {context}
# -t 选项可以指定构建完成的镜像的名称和tag,如果要打多个标签可以用多个 -t 选项
docker build -f {Dockerfile Path} -t {name:tag} {context}
context (上下文)
The build’s context is the set of files at a specified location PATH or URL. The PATH is a directory on your local filesystem. The URL is a Git repository location.
The build context is processed recursively. So, a PATH includes any subdirectories and the URL includes the repository and its submodules.:
context可以是本地路径(Path),也可以是Git仓库(Url)。context会被递归的处理,也就是指定目录的子目录或者是Git仓库中的所有子模块都会被处理。
The build is run by the Docker daemon, not by the CLI. The first thing a build process does is send the entire context (recursively) to the daemon.
构建工作是由 Docker 守护进程(服务端)完成,构建的第一件事就是 docker 客户端进程把上下文递归的发送给守护进程。
根据Dockerfile构建镜像的原理,官方给出了一个警告和一个建议:
- 警告:为了效率不要使用根目录(/)作为构建镜像的context,如果这样做,会导致Docker客户端把设备上的所有目录都发送到Docker守护进程,这显然会浪费很多资源,因为在构建镜像时用到的文件其实并没有那么多。
- 建议:在大多数情况下,最好以空目录作为上下文,并将Dockerfile保留在该目录中。 仅添加构建Dockerfile所需的文件。
docker build .
.dockerignore file
在Docker CLI(客户端)发送 context 上下文之前,Docker CLI (客户端)会在context上下文的根目录中寻找 .dockerignore 文件。通过解析 .dockerignore 文件来过滤向守护进程发送的内容。
文件内容语法格式:
- 以换行符为分割
- 忽略非换行符的空格
- # 注释,构建时会被忽略
- * 可以匹配任意字符串
- ? 可以匹配一个任意字符
- . 表示当前目录,可以神略
- ! 表示排除
Finally, you may want to specify which files to include in the context, rather than which to exclude. To achieve this, specify * as the first pattern, followed by one or more ! exception patterns
可以借助 ! 和 * 配合,达到只指定哪些文件需要包含在context中发送给守护进程的目的。
Dockerfile 的规则
1. 格式
# Comment
INSTRUCTION arguments
- # 为注释
- 不区分大小写,但是习惯上把指令(INSTRUCTION)大写,参数(arguments)小写
- 指令可以在 parser directives(解析器指令) 或者 注释之后
- 行首空格不敏感
- 续行符在注释中不支持
- 在指令中可以使用续行符号
- 注释行会在指令执行之前被移除
续行符示例: RUN echo "\ hello\ world"
2. 执行顺序:
Docker runs instructions in a Dockerfile in order.
Note that each instruction is run independently, and causes a new image to be created - so RUN cd /tmp will not have any effect on the next instructions.
Docker 按照Dockerfile中指令从上到下的顺序执行。并且指令的执行是独立的,上一条指令的执行结果不会影响下一条指令的执行。
3. Dockerfile的第一条非注释指令必须是 FROM 指令
FROM 指令用于在镜像共建过程中,指定基础镜像,后续指令都运行在次基础镜像提供的运行环境中。
基础镜像可以是任何镜像文件,默认docker回再本地查找,如果没有回去远端查找拉取。