docker build
docker构建
描述
从Dockerfile生成图像
使用
docker build [OPTIONS] PATH | URL | -
备选方案
名字,简写 | 默认 | 描述 |
---|---|---|
--add-host | | 添加自定义的主机到IP映射(主机:IP) |
--build-arg | | 设置构建时间变量 |
--cache-from | | 要考虑作为缓存源的图像 |
--cgroup- parent | | 容器的可选父cgroup |
--compress | false | 使用gzip压缩构建上下文 |
--cpu-period | 0 | 限制CPU CFS(完全公平调度程序)期限 |
- --cpu-quota | 0 | 限制CPU CFS(完全公平调度程序)配额 |
--cpu-shares,-c | 0 | CPU份额(相对重量) |
--cpuset-CPU | | 允许执行的CPU(0-3,0,1) |
--cpuset-MEMS | | 允许执行的MEM(0-3,0,1) |
--disable-content-trust | true | 跳过图像验证 |
--file,-f | | Dockerfile的名称(默认为'PATH / Dockerfile') |
--force-RM | false | 始终删除中间容器 |
--iidfile | | 将图像ID写入文件 |
--isolation | | 容器隔离技术 |
--label | | 设置图像的元数据 |
--memory, -m | 0 | 内存限制 |
--memory-swap | 0 | 交换限制等于内存加交换:'-1'以启用无限交换 |
--network | 默认 | 在构建期间为RUN指令设置联网模式 |
--no-cache | false | 构建图像时不要使用缓存 |
--pull | false | 始终尝试拉取图像的较新版本 |
--quiet,-q | false | 取消构建输出并在成功时打印图像ID |
- R M | 真正 | 成功构建后移除中间容器 |
--security-OPT | | 安全选项 |
--shm-size | 0 | / dev / shm的大小 |
--squash | false | 将新建的图层压缩到单个新图层中 |
--tag, -t | | 以'名称:标记'格式命名和可选的标记 |
--target | | 设置要构建的目标构建阶段。 |
--ulimit | | Ulimit选项 |
父命令
命令 | 描述 |
---|---|
docker | The base command for the Docker CLI. |
扩展描述
docker build
命令从 Dockerfile 和“上下文”构建 Docker 镜像。构建的上下文是指定位置PATH
或位置中的一组文件URL
。构建过程可以引用上下文中的任何文件。例如,您的构建可以使用 COPY
指令来引用上下文中的文件。
URL
参数可以引用三种资源:Git 存储库,预打包的 tarball 环境和纯文本文件。
Git存储库
当URL
参数指向Git存储库的位置,存储库充当构建上下文。系统递归地获取存储库及其子模块。提交历史没有保存。首先将存储库拖到本地主机上的临时目录中。成功后,目录作为上下文发送到Docker守护进程。本地副本使您能够使用本地用户凭据、VPN等访问私有存储库。
注:
如果URL
参数包含一个片段,系统将使用git clone --recursive
命令。
Git URL接受片段中的上下文配置,用冒号分隔:
。第一部分代表Git将检出的引用,可以是分支,标记或远程引用。第二部分表示存储库内的子目录,将用作构建上下文。
例如,运行此命令以使用名为docker
(在分支container
*)
$ docker build https://github.com/docker/rootfs.git#container:docker
下表表示所有有效后缀及其构建上下文:
构建语法后缀 | 已用命令 | 构建已使用上下文 |
---|---|---|
myrepo.git | refs/heads/master | / |
myrepo.git#mytag | refs/tags/mytag | / |
myrepo.git#mybranch | refs/heads/mybranch | / |
myrepo.git#pull/42/head | refs/pull/42/head | / |
myrepo.git#:myfolder | refs/heads/master | /myfolder |
myrepo.git#master:myfolder | refs/heads/master | /myfolder |
myrepo.git#mytag:myfolder | refs/tags/mytag | /myfolder |
myrepo.git#mybranch:myfolder | refs/heads/mybranch | /myfolder |
tarball上下文
如果将URL传递给远程tarball,则将URL本身发送到守护进程:
$ docker build http://server/context.tar.gz
下载操作将在运行Docker守护进程的主机上执行,它不一定是发出构建命令的主机。Docker守护进程将获取context.tar.gz
并使用它作为构建上下文。Tarball上下文必须是符合标准tar
UNIX格式的tar
档案,并且可以使用'xz','bzip2','gzip'或'identity'(无压缩)格式中的任何一种进行压缩。
文本文件
而不是指定上下文,您可以传递一个Dockerfile
在URL
或者将文件导入VIASTDIN
Dockerfile
从STDIN
*
$ docker build - < Dockerfile
通过Windows上的Powershell,您可以运行:
Get-Content Dockerfile | docker build -
如果您使用STDIN
或指定一个URL
指向一个纯文本文件时,系统将内容放入一个名为Dockerfile
,任何-f
,--file
选项被忽略。在这种情况下,没有上下文。
默认情况下,该docker build
命令将查找Dockerfile
构建上下文的根。使用-f
,--file
,选项可以指定替代文件的路径。这在多个版本使用同一组文件的情况下很有用。路径必须是构建上下文中的文件。如果指定了相对路径,则它被解释为相对于上下文的根。
在大多数情况下,最好将每个Dockerfile放在一个空目录中。然后,只向该目录添加构建Dockerfile所需的文件。若要提高生成的性能,可以通过添加.dockerignore
文件也放在那个目录下。有关创建一个的信息,请参见.dockerignore
文件...
如果Docker客户端失去与守护进程的连接,则生成将被取消。如果您用CTRL-c
或者码头客户因任何原因被杀。如果生成启动了一个在构建被取消时仍在运行的拉,则该拉也被取消。
实例
用路径构建
$ docker build .
Uploading context 10240 bytes
Step 1/3 : FROM busybox
Pulling repository busybox
---> e9aa60c60128MB/2.284 MB (100%) endpoint: https://cdn-registry-1.docker.io/v1/
Step 2/3 : RUN ls -lh /
---> Running in 9c9e81692ae9
total 24
drwxr-xr-x 2 root root 4.0K Mar 12 2013 bin
drwxr-xr-x 5 root root 4.0K Oct 19 00:19 dev
drwxr-xr-x 2 root root 4.0K Oct 19 00:19 etc
drwxr-xr-x 2 root root 4.0K Nov 15 23:34 lib
lrwxrwxrwx 1 root root 3 Mar 12 2013 lib64 -> lib
dr-xr-xr-x 116 root root 0 Nov 15 23:34 proc
lrwxrwxrwx 1 root root 3 Mar 12 2013 sbin -> bin
dr-xr-xr-x 13 root root 0 Nov 15 23:34 sys
drwxr-xr-x 2 root root 4.0K Mar 12 2013 tmp
drwxr-xr-x 2 root root 4.0K Nov 15 23:34 usr
---> b35f4035db3f
Step 3/3 : CMD echo Hello world
---> Running in 02071fceb21b
---> f52f38b7823e
Successfully built f52f38b7823e
Removing intermediate container 9c9e81692ae9
Removing intermediate container 02071fceb21b
这个例子指定PATH
为 .
,则本地目录中的所有
文件都得到tar
并发送到Docker守护进程。该PATH
指定在哪里可以找到文件上的docker守护程序生成的“背景”。请记住守护进程可能在远程计算机上运行,并且在客户端(您正在运行的位置docker build
)不会解析Dockerfile 。这意味着发送的所有
文件PATH
,不仅仅是在Dockerfile中列出的ADD
文件。
将上下文从本地机器传输到Docker守护进程是docker
客户端意味着当您看到“发送构建上下文”消息时。
如果希望在构建完成后保留中间容器,则必须使用--rm=false
这不影响生成缓存。
用URL构建
$ docker build github.com/creack/docker-firefox
这将克隆GitHub存储库,并将克隆的存储库用作上下文。存储库根部的Dockerfile用作Dockerfile。可以使用git://
或git@
计划。
$ docker build -f ctx/Dockerfile http://server/ctx.tar.gz
Downloading context: http://server/ctx.tar.gz [===================>] 240 B/240 B
Step 1/3 : FROM busybox
---> 8c2e06607696
Step 2/3 : ADD ctx/container.cfg /
---> e7829950cee3
Removing intermediate container b35224abf821
Step 3/3 : CMD /bin/ls
---> Running in fbc63d321d73
---> 3286931702ad
Removing intermediate container fbc63d321d73
Successfully built 377c409b35e4
这会将URL http://server/ctx.tar.gz
发送到Docker守护进程,Docker守护进程会下载并提取引用的tarball。 -f ctx / Dockerfile
参数在ctx.tar.gz
中指定用于构建映像的Dockerfile
中的路径。 该Dockerfile
中引用本地路径的任何ADD
命令都必须与ctx.tar.gz
内的根目录相关。 在上面的示例中,tarball包含一个目录ctx /
,因此ADD ctx / container.cfg /
操作按预期工作。
用 - 进行建立
$ docker build - < Dockerfile
这将从STDIN
没有上下文的地方读取Dockerfile 。由于缺少上下文,任何本地目录的内容都不会发送到Docker守护进程。由于没有上下文,因此Dockerfile ADD
仅在引用远程URL时才有效。
$ docker build - < context.tar.gz
这将为从STDIN
支持的格式有:bzip 2、gzip和xz。
使用.dockerignore文件
$ docker build .
Uploading context 18.829 MB
Uploading context
Step 1/2 : FROM busybox
---> 769b9341d937
Step 2/2 : CMD echo Hello world
---> Using cache
---> 99cc1ad10469
Successfully built 99cc1ad10469
$ echo ".git" > .dockerignore
$ docker build .
Uploading context 6.76 MB
Uploading context
Step 1/2 : FROM busybox
---> 769b9341d937
Step 2/2 : CMD echo Hello world
---> Using cache
---> 99cc1ad10469
Successfully built 99cc1ad10469
此示例显示使用该.dockerignore
文件.git
从上下文中排除目录。其效果可以在上传的上下文的改变大小中看到。构建器参考包含有关创建.dockerignore
文件的详细信息
标记图像(-t)
$ docker build -t vieux/apache:2.0 .
这将像前面的示例一样构建,但它会标记生成的图像。存储库名称将是vieux/apache
,标签将会是2.0
。详细了解有效标签。
可以将多个标记应用于图像。例如,可以应用latest
标记到新构建的映像中,并添加引用特定版本的另一个标记。例如,将图像标记为whenry/fedora-jboss:latest
和whenry/fedora-jboss:v2.1
,使用以下方法:
$ docker build -t whenry/fedora-jboss:latest -t whenry/fedora-jboss:v2.1 .
指定一个Dockerfile(-f)
$ docker build -f Dockerfile.debug .
这将使用一个叫做Dockerfile.debug
构建指令的文件来代替Dockerfile
。
$ curl example.com/remote/Dockerfile | docker build -f - .
上面的命令将使用当前目录作为构建上下文,并从stdin读取一个Dockerfile。
$ docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .
$ docker build -f dockerfiles/Dockerfile.prod -t myapp_prod .
以上命令将.
使用调试版本的a Dockerfile
和使用生产版本一次两次构建当前构建上下文(由the指定)。
$ cd /home/me/myapp/some/dir/really/deep
$ docker build -f /home/me/myapp/dockerfiles/debug /home/me/myapp
$ docker build -f ../../../../dockerfiles/debug /home/me/myapp
这两个docker build
命令也会这样做。它们都使用debug
文件,而不是查找Dockerfile
并将使用/home/me/myapp
作为构建上下文的根。请注意debug
在构建上下文的目录结构中,而不管如何在命令行中引用它。
注意:
如果文件或目录不存在于上传的上下文中,docker build
将返回no such file or directory
错误。如果没有上下文,或者您指定的文件位于主机系统的其他位置,则可能会发生这种情况。由于安全原因,上下文仅限于当前目录(及其子目录),并确保远程Docker主机上的可重复构建。这也是ADD ../file
不能工作的原因。
使用自定义父级cgroup(-cgroup-parent)
当docker build
使用该--cgroup-parent
选项运行时,构建中使用的容器将与相应的docker run
标志一起运行。
在容器中设置ulimits(-ulimit)
使用该--ulimit
选项docker build
将使每个构建步骤的容器都使用这些--ulimit
标志值启动。
设置构建时间变量(-build-arg)
您可以使用ENV
Dockerfile中的指令来定义变量值。这些值坚持在建成的形象。但是,往往坚持的内容不是你想要的。用户想要根据他们在哪个主机上构建图像来指定不同的变量。
一个很好的例子是http_proxy
或提取中间文件的源版本。ARG
指令允许Dockerfile作者定义用户可以在构建时使用--build-arg标志
:
$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
此标志允许您传递像常规环境变量一样访问的构建时变量。RUN
Dockerfile的指令。而且,这些值不会在中间图像或最终映像中持久化,例如ENV
价值是可以的。
使用此标志不会改变当ARG
在构建过程中,来自Dockerfile的行将被回显。
有关使用ARG
和ENV
指令的详细信息,请参阅Dockerfile参考。
可选的安全选项(-security-opt)
该标志仅在Windows上运行的守护程序上受支持,并且只支持credentialspec
选项。在credentialspec
必须在格式file://spec.txt
或registry://keyname
。
指定容器的隔离技术(隔离)
在Windows上运行Docker容器的情况下,此选项很有用。--isolation=<value>选项设置容器的隔离技术。在Linux上,唯一支持的是default使用Linux命名空间的选项。在Microsoft Windows上,您可以指定这些值:
值 | 描述 |
---|---|
默认 | 使用Docker守护进程的--exec-opt指定的值。如果守护进程未指定隔离技术,则Microsoft Windows将使用进程作为其默认值。 |
处理 | 仅命名空间隔离。 |
hyperv | 基于Hyper-V管理程序分区的隔离。 |
指定--isolation
没有值的标志与设置--isolation="default"
相同。
将条目添加到容器主机文件(-add-host)
您可以/etc/hosts
使用一个或多个--add-host
标志将其他主机添加到容器的文件中。此示例为名为以下的主机添加一个静态地址docker
:
$ docker build --add-host=docker:10.180.0.1 .
指定目标构建阶段(-target)
当构建具有多个构建阶段的Dockerfile时,--target
可以根据名称指定中间构建阶段,作为结果映像的最后阶段。将跳过目标阶段之后的命令。
FROM debian AS build-env
...
FROM alpine AS production-env
...
$ docker build -t mybuildimage --target build-env .
压缩图像的图层(-squash)仅用于实验
概述
一旦图像被构建,将新的图层压缩成一个新的图层。压缩不会破坏任何现有的图像,而是创建一个新的图像与内容的挤压层。这实际上使它看起来像所有的Dockerfile
命令是用一个单层创建的。此方法将保留生成缓存。
注
使用此选项意味着新图像将无法利用与其他图像的层共享,并可能使用更多的空间。
注
使用此选项,您可能会看到由于存储两个映像副本,一个用于具有所有缓存层的构建缓存,另一个用于压缩版本。
先决条件
此页面上的示例是在Docker 1.13中使用试验模式。
可以通过使用--experimental
在启动Docker守护进程或设置experimental: true
在daemon.json
配置文件
默认情况下,实验模式被禁用。要查看当前配置,请使用docker version
命令。
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Go version: go1.7.5
Git commit: 092cba3
Built: Wed Feb 8 06:35:24 2017
OS/Arch: linux/amd64
Experimental: false
[...]
要启用实验模式,用户需要重启启用实验标志的docker守护进程。
启用码头试验
从版本1.13.0开始,标准Docker二进制文件现在包含实验性功能。为了启用实验性功能,您需要启动带有--experimental
标志的Docker守护进程。您也可以通过/etc/docker/daemon.json启用守护进程标志。例如
{
"experimental": true
}
然后确保启用了实验标志:
$ docker version -f '{{.Server.Experimental}}'
true
用--squash参数构建图像
以下是使用--squash
参数构建docker的示例
FROM busybox
RUN echo hello > /hello
RUN echo world >> /hello
RUN touch remove_me /remove_me
ENV HELLO world
RUN rm /remove_me
一个名为的图像test
是用--squash
参数构建的。
$ docker build --squash -t test .
[...]
如果一切都是正确的,那么历史将会是这样的:
$ 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
我们可以发现所有图层的名称都是<missing>,并且COMMENT有一个新图层merge。
测试图像,检查是否/remove_me
已经消失,确保hello\nworld
已进入/hello
,确保HELLO
envvar的值为world
。