docker build (旧版构建器)
描述 | 从 Dockerfile 构建镜像 |
---|---|
用法 | docker image build [OPTIONS] PATH | URL | - |
别名 | docker image build docker build docker builder build |
描述
重要
此页面指的是
docker build
的**旧版实现**,使用旧版(BuildKit之前的)构建后端。此配置仅在构建Windows容器时才相关。有关使用Buildx的默认
docker build
的信息,请参见docker buildx build
。
使用旧版构建器进行构建时,通过运行一系列提交来从Dockerfile创建镜像。与使用BuildKit相比,此过程效率低下且速度慢,这就是此构建策略已弃用所有用例(除了构建Windows容器)的原因。它对于构建Windows容器仍然有用,因为BuildKit尚未完全支持Windows的功能。
使用docker build
调用的构建默认情况下使用Buildx(和BuildKit),除非
- 您在Windows容器模式下运行Docker Engine
- 您通过设置环境变量
DOCKER_BUILDKIT=0
明确选择不使用BuildKit。
此页面上的描述仅涵盖旧版构建器独有的信息以及旧版构建器与BuildKit行为不同的情况。有关旧版构建器和BuildKit之间共有的功能和标志(例如--tag
和--target
)的信息,请参阅docker buildx build
的文档。
旧版构建器的构建上下文
构建上下文是在调用构建命令时传递的位置参数。在以下示例中,上下文为.
,表示当前工作目录。
$ docker build .
使用旧版构建器时,构建上下文将完整地发送到守护进程。使用BuildKit时,只会传输构建中使用的文件。旧版构建器不会预先计算它需要哪些文件。这意味着对于上下文较大的构建,即使您仅使用上下文中包含的文件的一个子集,上下文传输也可能需要很长时间。
使用旧版构建器时,因此务必仔细考虑您在指定的上下文中包含哪些文件。使用.dockerignore
文件排除构建中不需要的文件和目录作为构建上下文的一部分发送。
访问构建上下文之外的路径
如果您尝试在Dockerfile中使用相对路径访问构建上下文之外的文件,旧版构建器将出错。
FROM alpine
COPY ../../some-dir .
$ docker build .
...
Step 2/2 : COPY ../../some-dir .
COPY failed: forbidden path outside the build context: ../../some-dir ()
另一方面,BuildKit会去除超出构建上下文范围的领先相对路径。重新使用前面的示例,路径COPY ../../some-dir .
在BuildKit中评估为COPY some-dir .
。
选项
选项 | 默认值 | 描述 |
---|---|---|
--add-host | 添加自定义主机到IP映射(host:ip ) | |
--build-arg | 设置构建时变量 | |
--cache-from | 视为缓存源的镜像 | |
--cgroup-parent | 设置构建期间RUN 指令的父cgroup | |
--compress | 使用gzip压缩构建上下文 | |
--cpu-period | 限制CPU CFS(完全公平调度器)周期 | |
--cpu-quota | 限制CPU CFS(完全公平调度器)配额 | |
-c, --cpu-shares | CPU份额(相对权重) | |
--cpuset-cpus | 允许执行的CPU(0-3, 0,1) | |
--cpuset-mems | 允许执行的MEM(0-3, 0,1) | |
--disable-content-trust | true | 跳过镜像验证 |
-f, --file | Dockerfile 的名称(默认值为PATH/Dockerfile ) | |
--force-rm | 始终删除中间容器 | |
--iidfile | 将镜像ID写入文件 | |
--isolation | 容器隔离技术 | |
--label | 设置镜像的元数据 | |
-m, --memory | 内存限制 | |
--memory-swap | 交换空间限制等于内存加交换空间:-1启用无限交换空间 | |
--network | API 1.25+ 设置构建期间RUN 指令的网络模式 | |
--no-cache | 构建镜像时不使用缓存 | |
--platform | API 1.38+ 如果服务器支持多平台,则设置平台 | |
--pull | 始终尝试拉取较新版本的镜像 | |
-q, --quiet | 抑制构建输出并在成功时打印镜像ID | |
--rm | true | 在成功构建后删除中间容器 |
--security-opt | 安全选项 | |
--shm-size | /dev/shm 的大小 | |
--squash | API 1.25+ 实验性(守护进程) 将新构建的层压缩到单个新层中 | |
-t, --tag | 名称和可选标签,格式为name:tag | |
--target | 设置要构建的目标构建阶段。 | |
--ulimit | ulimit选项 |
示例
指定容器的隔离技术(--isolation)
此选项在您在Windows上运行Docker容器的情况下很有用。--isolation=<value>
选项设置容器的隔离技术。在Linux上,唯一支持的选项是default
选项,它使用Linux命名空间。在Microsoft Windows上,您可以指定以下值
值 | 描述 |
---|---|
default | 使用Docker守护进程的--exec-opt 指定的值。如果守护进程 未指定隔离技术,则Microsoft Windows使用process 作为其默认值。 |
process | 仅命名空间隔离。 |
hyperv | 基于Hyper-V虚拟机的分区隔离。 |
不带值地指定--isolation
标志与设置--isolation="default"
相同。
可选安全选项(--security-opt)
此标志仅在Windows上运行的守护进程上受支持,并且仅支持credentialspec
选项。credentialspec
必须采用file://spec.txt
或registry://keyname
格式。
压缩镜像的层(--squash)(实验性)
概述
注意
--squash
选项是一个实验性功能,不应视为稳定功能。
构建镜像后,此标志会将新层压缩到具有单个新层的新镜像中。压缩不会破坏任何现有镜像,而是创建一个包含压缩层内容的新镜像。这实际上使其看起来像所有Dockerfile
命令都是用单个层创建的。--squash
标志保留构建缓存。
如果您的Dockerfile生成多个修改相同文件的层,则压缩层可能会有益。例如,在一个步骤中创建的文件在另一个步骤中被删除。对于其他用例,压缩镜像实际上可能会对性能产生负面影响。拉取包含多个层的镜像时,守护进程可以并行拉取层,并允许在镜像之间共享层(节省空间)。
对于大多数用例,多阶段构建是更好的替代方案,因为它可以更精细地控制构建,并可以利用构建器未来的优化。有关更多信息,请参阅多阶段构建部分。
已知限制
--squash
选项有一些已知的限制
- 压缩层后,生成的镜像无法利用与其他镜像的层共享,可能会占用更多空间。仍然支持共享基础镜像。
- 使用此选项时,由于存储了镜像的两个副本(一个用于构建缓存,包含所有缓存层;另一个是压缩版本),您可能会看到显着增加的空间使用量。
- 虽然压缩层可能会生成较小的镜像,但它可能会对性能产生负面影响,因为单个层的提取时间更长,并且无法并行下载单个层。
- 尝试压缩未对文件系统进行更改的镜像(例如,Dockerfile 只包含
ENV
指令)时,压缩步骤将失败(参见问题 #33823)。
前提条件
本页面的示例使用 Docker 23.03 中的实验模式。
您可以使用--experimental
标志启动 Docker 守护程序或在daemon.json
配置文件中设置experimental: true
来启用实验模式。
默认情况下,实验模式处于禁用状态。要查看 Docker 守护程序的当前配置,请使用docker version
命令并检查Engine
部分中的Experimental
行。
Client: Docker Engine - Community
Version: 23.0.3
API version: 1.42
Go version: go1.19.7
Git commit: 3e7cbfd
Built: Tue Apr 4 22:05:41 2023
OS/Arch: darwin/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.3
API version: 1.42 (minimum version 1.12)
Go version: go1.19.7
Git commit: 59118bf
Built: Tue Apr 4 22:05:41 2023
OS/Arch: linux/amd64
Experimental: true
[...]
使用--squash
标志构建镜像
以下是使用--squash
标志进行构建的示例。以下是Dockerfile
FROM busybox
RUN echo hello > /hello
RUN echo world >> /hello
RUN touch remove_me /remove_me
ENV HELLO=world
RUN rm /remove_me
接下来,使用--squash
标志构建名为test
的镜像。
$ docker build --squash -t test .
构建完成后,历史记录如下所示。历史记录可能显示层的名称为<missing>
,并且存在一个带有注释merge
的新层。
$ docker history test
IMAGE CREATED CREATED BY SIZE COMMENT
4e10cb5b4cac 3 seconds ago 12 B merge sha256:88a7b0112a41826885df0e7072698006ee8f621c6ab99fca7fe9151d7b599702 to sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
<missing> 5 minutes ago /bin/sh -c rm /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c #(nop) ENV HELLO=world 0 B
<missing> 5 minutes ago /bin/sh -c touch remove_me /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c echo world >> /hello 0 B
<missing> 6 minutes ago /bin/sh -c echo hello > /hello 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff 1.113 MB
测试镜像,检查/remove_me
是否已消失,确保hello\nworld
位于/hello
中,确保HELLO
环境变量的值为world
。