1、docker build 简介
docker build是从Dockerfile构建一个映像。Dockerfile是一个用来构建镜像的文本文件。
2、docker build 语法
docker build [OPTIONS] PATH | URL | -
docker build命令从Dockerfile和 “context” 构建docker映像。构建的上下文是位于指定PATH或URL中的一组文件。构建过程可以引用上下文中的任何文件。例如,构建可以使用COPY指令来引用上下文中的文件。
URL参数可以引用三种资源:Git存储库、预打包的tarball上下文和纯文本文件。当URL参数指向Git存储库的位置时,存储库就充当构建上下文。系统递归地获取存储库及其子模块。提交历史没有保存。存储库首先被拉入本地主机上的临时目录。成功之后,该目录将作为上下文发送给Docker守护进程。本地副本使能够使用本地用户凭据、VPN等访问私有存储库。
注意:如果URL参数包含一个片段,系统将使用git clone --recursive命令递归地克隆存储库及其子模块。
参考文档:https://docs.docker.com/engine/reference/commandline/build/
3、docker build 命令
1)在分支container中使用名为docker的目录
Git URL在它们的片段部分接受上下文配置,由冒号(:)分隔。第一部分表示Git将检出的引用,可以是分支、标记或远程引用。第二部分表示存储库中的子目录,该子目录将用作构建上下文。
docker build https://github.com/docker/rootfs.git#container:docker
下表表示所有有效后缀及其构建上下文:
Build 语法后缀  | 使用的Commit  | 使用的Build Context  | 
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  | 
注意:当使用BuildKit作为构建器(DOCKER_BUILDKIT=1)时,不能指定构建上下文目录(上面示例中的myfolder)。在buildkit#1684中跟踪了对该特性的支持。
2)Tarball context
如果将URL传递给远程tarball, URL本身会被发送给守护进程。
docker build http://server/context.tar.gz
下载操作将在运行Docker守护进程的主机上执行,这不一定是发出构建命令的同一台主机。Docker守护进程将获取context.tar.gz并将其用作构建上下文。Tarball上下文必须是符合标准tar UNIX格式的tar档案,并且可以使用' xz '、' bzip2 '、' gzip '或' identity '(不压缩)格式中的任何一种进行压缩。
3)用文本文件构建镜像
不需要指定上下文,可以在URL中传递一个Dockerfile,或者通过STDIN管道传入文件。从STDIN管道一个Dockerfile。
docker build - < Dockerfile
Windows上使用Powershell:
Get-Content Dockerfile | docker build -
4)用路径构建镜像
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为.,因此本地目录中的所有文件都将被tard并发送到Docker守护进程。PATH指定在Docker守护进程上为构建的 “context” 查找文件的位置。请记住,守护进程可以在远程机器上运行,并且在客户端(在那里运行docker构建)不会发生Dockerfile的解析。这意味着PATH中的所有文件都会被发送,而不仅仅是Dockerfile中列出的要添加的文件。
当看到“发送构建上下文”消息时,Docker客户机的意思就是将上下文从本地机器传输到Docker守护进程。
如果希望在构建完成后保留中间容器,则必须使用--rm=false。这不会影响构建缓存。
5)用URL构建镜像
docker build github.com/creack/docker-firefox
注意:这将clone GitHub仓库,并使用clone的仓库作为上下文。仓库根目录下的Dockerfile被用作Dockerfile。可以使用git://或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守护进程,该守护进程将下载并提取引用的tarball。-f ctx/Dockerfile参数在ctx.tar.gz中指定了用于构建镜像的Dockerfile的路径。Dockerfile中任何指向本地路径的ADD命令都必须相对于ctx.tar.gz中的根目录。在上面的例子中,压缩包包含一个目录ctx/,所以添加ctx/container.cfg/的操作按预期工作。
6)用 - 构建镜像
docker build - < Dockerfile
注意:这将在没有上下文的情况下从STDIN读取Dockerfile。由于缺少上下文,任何本地目录的内容都不会被发送到Docker守护进程。由于没有上下文,Dockerfile ADD仅在引用远程URL时有效。
docker build - < context.tar.gz
注意:这将为从STDIN读取的压缩上下文构建一个镜像。支持的格式有:bzip2, gzip和xz。
7)使用.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注意:当使用BuildKit后端时,docker build会根据Dockerfile名称搜索一个.dockerignore文件。如运行docker build -f myapp.Dockerfile。首先查找一个名为myapp.Dockerfile.dockerignore的忽略文件。如果没有找到这样的文件,则使用存在的.dockerignore文件。如果项目包含多个Dockerfile,它们希望忽略不同的文件集,那么使用基于.dockerignore的Dockerfile就很有用。
8)定义标签标记镜像(-t)
docker build -t vieux/apache:2.0 .
9)指定Dockerfile (-f)
docker build -f Dockerfile.debug .
10)设置构建时变量(--build-arg)
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 --build-arg FTP_PROXY=http://40.50.60.5:4567 .
或者
export HTTP_PROXY=http://10.20.30.2:1234 docker build --build-arg HTTP_PROXY .
11)在容器主机文件中添加条目(--add-host)
docker build --add-host=docker:10.180.0.1 .
12)指定目标构建阶段(--target)
在构建包含多个构建阶段的Dockerfile时,--target可以指定一个中间构建阶段的名称,作为生成镜像的最后阶段。目标阶段之后的命令将被跳过。
$ cat Dockerfile
FROM debian AS build-env
# ...
FROM alpine AS production-env
# ...
$ docker build -t mybuildimage --target build-env .13)使用tar类型将文件导出为.tar文件
docker build --output type=tar,dest=out.tar .
或
docker build -o - . > out.tar
注意:--output选项导出目标阶段的所有文件。只导出特定文件的一种常见模式是进行多阶段构建,并使用COPY --from将所需文件复制到一个新的scratch阶段。
14)使用--cache-from指定缓存源
推送镜像后,该镜像可以将作为另一台机器上的缓存源。BuildKit在需要时自动从注册表中提取镜像。
docker build --cache-from myname/myapp .
注意:此功能需要BuildKit后端。可以启用BuildKit或使用buildx插件。之前的构建器对重用预拉取镜像的缓存支持有限。
15)使用--squash 构建镜像
docker build --squash -t cjavapy .
注意:使用--squash需要要将 experimental 参数设置为 true;
docker v20版本是通过修改/etc/docker/daemon.json开启:
{
    "experimental": true
}--squash一方面压缩了镜像的大小,另一方面保存了镜像的构建信息。
4、选项说明
选项  | 默认  | 描述  | 
--add-host  | 添加一个自定义的主机到ip映射(host:ip)  | |
--build-arg  | 设置构建时变量  | |
--cache-from  | 视为缓存源的镜像  | |
--cgroup-parent  | 容器的可选父cgroup  | |
--compress  | 使用gzip压缩构建上下文  | |
--cpu-period  | 限制CPU CFS(完全公平调度程序)周期  | |
--cpu-quota  | 限制CPU CFS(完全公平调度器)配额  | |
--cpu-shares , -c  | CPU份额(相对权重)  | |
--cpuset-cpus  | 允许执行的cpu (0-3,0,1)  | |
--cpuset-mems  | 允许执行的MEMs (0-3,0,1)  | |
--disable-content-trust  | true  | 跳过镜像验证  | 
--file , -f  | Dockerfile的名称(默认为'PATH/Dockerfile')  | |
--force-rm  | 始终删除中间容器  | |
--iidfile  | 将镜像ID写入文件  | |
--isolation  | 容器隔离技术  | |
--label  | 设置镜像的元数据  | |
--memory , -m  | 内存限制  | |
--memory-swap  | 交换限制等于内存加上交换:'-1'以启用无限交换  | |
--network  | 在构建期间为RUN指令设置网络模式  | |
--no-cache  | 在构建镜像时不使用缓存  | |
--output , -o  | 输出目标(格式:type=local,dest=path)  | |
--platform  | 如果服务器支持多平台,需要设置平台  | |
--progress  | auto  | 设置进度输出类型(auto、plain、tty)。 使用plain来显示容器输出  | 
--pull  | 总是尝试拉取镜像的新版本  | |
--quiet , -q  | 关闭构建输出并在成功时打印镜像ID  | |
--rm  | true  | 在成功构建后移除中间容器  | 
--secret  | 要暴露给构建的秘密文件(仅当启用BuildKit时):i d=mysecret,src=/local/secret  | |
--security-opt  | 安全选项  | |
--shm-size  | /dev/shm的大小  | |
--squash  | 将新建的层压缩为一个新层  | |
--ssh  | 要向构建公开的SSH代理套接字或密钥 (仅当BuildKit启用时)(格式: default|[=|[,]])  | |
--stream  | Stream附加到server以协商构建上下文  | |
--tag , -t  | 名称和可选的'name:tag'格式的标签  | |
--target  | 设置要构建的目标构建阶段。  | |
--ulimit  | ulimit 选项, 使用这些--ulimit标志值启动 每个构建步骤的容器。  |