docker 镜像构建

描述从 Dockerfile 构建镜像
用法docker image build [OPTIONS] PATH | URL | -
别名
docker build docker buildx build docker builder build

描述

docker build命令从 Dockerfile 和“上下文”构建 Docker 映像。构建的上下文是位于指定 PATHURL.构建过程可以引用上下文中的任何文件。例如,您的构建可以使用 COPY 指令来引用上下文中的文件。

URL参数可以引用三种资源:Git 存储库、预打包的 tarball 上下文和纯文本文件。

Git 存储库

URL参数指向 Git 存储库的位置时,该存储库充当构建上下文。系统递归地获取存储库及其子模块。不保留提交历史记录。首先将存储库拉入本地主机上的临时目录中。成功后,该命令将目录发送到 Docker 守护进程作为上下文。本地副本使您能够使用本地用户凭据、VPN 等访问私有存储库。

笔记

如果URL参数包含片段,系统将递归克隆存储库及其子模块。

Git URL 在其片段部分接受上下文配置,以冒号 ( :) 分隔。第一部分表示 Git 签出的引用,可以是分支、标签或远程引用。第二部分表示存储库内用作构建上下文的子目录。

例如,运行以下命令以使用docker分支中 调用的目录container

$ docker build https://github.com/docker/rootfs.git#container:docker

下表列出了所有有效的后缀及其构建上下文:

构建语法后缀提交已使用构建使用的上下文
myrepo.gitrefs/heads/master/
myrepo.git#mytagrefs/tags/mytag/
myrepo.git#mybranchrefs/heads/mybranch/
myrepo.git#pull/42/headrefs/pull/42/head/
myrepo.git#:myfolderrefs/heads/master/myfolder
myrepo.git#master:myfolderrefs/heads/master/myfolder
myrepo.git#mytag:myfolderrefs/tags/mytag/myfolder
myrepo.git#mybranch:myfolderrefs/heads/mybranch/myfolder

压缩包上下文

如果将 URL 传递到远程 tarball,该命令会将 URL 本身发送到守护程序:

$ docker build http://server/context.tar.gz

运行 Docker 守护进程的主机执行下载操作,该主机不一定是发出构建命令的同一主机。 Docker 守护进程获取context.tar.gz并将其用作构建上下文。 Tarball 上下文必须是符合标准 Unix 格式的 tar 存档 ,并且可以使用、或 (无压缩)格式tar中的任何一种进行压缩。xzbzip2gzipidentity

文本文件

Dockerfile您可以在 中 传递单个上下文,URL或者通过管道将文件传入 via ,而不是指定上下文STDIN。通过管道传输 a Dockerfilefrom STDIN

$ docker build - < Dockerfile

使用 Windows 上的 PowerShell,您可以运行:

Get-Content Dockerfile | docker build -

如果您使用STDIN或指定URL指向纯文本文件,守护程序会将内容放入Dockerfile, 并忽略任何-f,--file 选项。在这种情况下,没有上下文。

默认情况下,该命令在构建上下文的根目录中docker build查找 a 。 , ,Dockerfile选项允许您指定要使用的替代文件的路径。这在使用同一组文件进行多个构建的情况下非常有用。该路径必须是构建上下文中的文件。相对路径被解释为相对于上下文的根。-f--file

在大多数情况下,最好将每个 Dockerfile 放在一个空目录中。然后,仅将构建 Dockerfile 所需的文件添加到该目录。为了提高构建的性能,您还可以通过.dockerignore向该目录添加文件来排除文件和目录。有关创建该文件的信息,请参阅 .dockerignore 文件

如果 Docker 客户端失go与守护进程的连接,它将取消构建。如果您中断 Docker 客户端CTRL-c或者 Docker 客户端因任何原因被终止,就会发生这种情况。如果构建发起的拉取在取消构建时仍在运行,则客户端也会取消拉取。

选项

选项默认描述
--add-host添加自定义主机到 IP 映射 ( host:ip)
--build-arg设置构建时变量
--cache-from考虑作为缓存源的图像
--cgroup-parentRUN在构建期间为指令设置父 cgroup
--compress使用 gzip 压缩构建上下文
--cpu-period限制CPU CFS(完全公平调度程序)周期
--cpu-quota限制CPU CFS(完全公平调度程序)配额
-c, --cpu-sharesCPU 份额(相对权重)
--cpuset-cpus允许执行的 CPU (0-3, 0,1)
--cpuset-mems允许执行的 MEM (0-3, 0,1)
--disable-content-trusttrue跳过图像验证
-f, --fileDockerfile 的名称(默认为PATH/Dockerfile
--force-rm始终移除中间容器
--iidfile将图像 ID 写入文件
--isolation容器隔离技术
--label设置图像的元数据
-m, --memory内存限制
--memory-swap交换限制等于内存加交换:-1 启用无限制交换
--networkAPI 1.25+ 在构建期间设置 RUN 指令的网络模式
--no-cache构建镜像时不要使用缓存
--platformAPI 1.38+ 如果服务器支持多平台,则设置平台
--pull始终尝试拉取更新版本的映像
-q, --quiet成功时抑制构建输出并打印图像 ID
--rmtrue成功构建后删除中间容器
--security-opt安全选项
--shm-size尺寸为/dev/shm
--squashAPI 1.25+ 实验性(守护进程) 将新构建的层压缩为单个新层
-t, --tagname:tag名称和可选格式的标签
--target设置要构建的目标构建阶段。
--ulimit极限选项

例子

使用路径构建

$ 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

此示例指定 is PATH, .so tars 本地目录中的所有文件并将它们发送到 Docker 守护进程。指定PATH在何处查找 Docker 守护进程上的构建“上下文”的文件。请记住,守护进程可以在远程计算机上运行,​​并且在客户端(您正在运行的位置)不会发生 Dockerfile 的解析 docker build。这意味着所有文件都会被发送,而不仅仅是 Dockerfile 中PATH列出的文件 。ADD

docker当您看到“正在发送构建上下文”消息时,客户端表示上下文从本地计算机传输到 Docker 守护程序 。

如果您希望在构建完成后保留中间容器,则必须使用--rm=false.这不会影响构建缓存。

使用 URL 构建

$ docker build github.com/creack/docker-firefox

这将克隆 GitHub 存储库,使用克隆的存储库作为上下文,并使用存储库根目录下的 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 内部路径。其中引用本地路径的任何命令都必须相对于 内部内容的根目录。在上面的示例中,tarball 包含一个目录,因此操作按预期进行。ctx.tar.gzDockerfileADDDockerfilectx.tar.gzctx/ADD ctx/container.cfg /

构建与 -

$ docker build - < Dockerfile

此示例在没有上下文的情况下读取 Dockerfile STDIN。由于缺少上下文,该命令不会将任何本地目录的内容发送到 Docker 守护程序。由于没有上下文,DockerfileADD仅在引用远程 URL 时才起作用。

$ docker build - < context.tar.gz

此示例为从 读取的压缩上下文构建图像STDIN。支持的格式有:bzip2gzipxz

使用 .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 文件的详细信息。

使用 BuildKit 后端时, docker build搜索.dockerignore与 Dockerfile 名称相关的文件。例如,docker build -f myapp.Dockerfile .首先运行会查找名为 的忽略文件myapp.Dockerfile.dockerignore。如果找不到这样的文件(如果存在),则会使用该.dockerignore文件。.dockerignore如果项目包含多个希望忽略不同文件集的 Dockerfile,则使用基于 Dockerfile 非常有用。

标记图像(-t、--tag)

$ docker build -t vieux/apache:2.0 .

此示例的构建方式与前面的示例相同,但它随后标记了生成的图像。存储库名称将为vieux/apache,标签为2.0

阅读有关有效标签的更多信息

您可以将多个标签应用于一张图像。例如,您可以将latest 标签应用于新建的映像,并添加引用特定版本的另一个标签。

例如,要将图像标记为whenry/fedora-jboss:latestwhenry/fedora-jboss:v2.1,请使用以下命令:

$ docker build -t whenry/fedora-jboss:latest -t whenry/fedora-jboss:v2.1 .

指定 Dockerfile (-f, --file)

$ docker build -f Dockerfile.debug .

Dockerfile.debug这使用一个名为构建指令的文件而不是Dockerfile.

$ curl example.com/remote/Dockerfile | docker build -f - .

上面的命令使用当前目录作为构建上下文并从标准输入读取 Dockerfile。

$ docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .
$ docker build -f dockerfiles/Dockerfile.prod  -t myapp_prod .

上述命令构建当前构建上下文(由 指定 .)两次。一次使用调试版本Dockerfile,一次使用生产版本。

$ 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 buildno such file or directory如果上传的上下文中不存在该文件或目录,则返回错误。如果没有上下文,或者您指定了主机系统上其他位置的文件,则可能会发生这种情况。出于安全原因,上下文仅限于当前目录(及其子目录),并确保远程 Docker 主机上的可重复构建。这也是ADD ../file行不通的原因 。

使用自定义父 cgroup (--cgroup-parent)

当您docker build使用该选项运行时,守护进程会使用相应的flag--cgroup-parent运行构建中使用的容器 。docker run

在容器中设置 ulimit (--ulimit)

使用--ulimit选项 with会导致守护进程使用这些标志值docker build启动每个构建步骤的容器 。--ulimit

设置构建时变量(--build-arg)

您可以使用ENVDockerfile 中的指令来定义变量值。这些值保留在构建的映像中。很多时候,坚持并不是你想要的。用户希望根据他们在哪个主机上构建映像来指定不同的变量。

一个很好的例子是http_proxy用于拉取中间文件的源版本。该ARG指令允许 Dockerfile 作者定义用户可以使用以下标志在构建时设置的值--build-arg

$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 --build-arg FTP_PROXY=http://40.50.60.5:4567 .

该标志允许您传递构建时变量,这些变量像RUNDockerfile 指令中的常规环境变量一样被访问。这些值不会像ENV值一样保留在中间或最终图像中。您必须--build-arg为每个构建参数添加。

使用此标志不会改变您在构建过程回显ARGDockerfile 中的行时看到的输出。

有关使用ARGENV说明的详细信息,请参阅 Dockerfile 参考

您还可以使用--build-arg不带值的标志,在这种情况下,守护进程会将值从本地环境传播到它正在构建的 Docker 容器中:

$ export HTTP_PROXY=http://10.20.30.2:1234
$ docker build --build-arg HTTP_PROXY .

这个例子与工作原理类似docker run -e。请参阅 docker run文档 以获取更多信息。

可选的安全选项(--security-opt)

此标志仅在 Windows 上运行的守护程序上受支持,并且仅支持该credentialspec选项。必须采用或 的credentialspec格式 。file://spec.txtregistry://keyname

指定容器的隔离技术(--isolation)

当您在 Windows 上运行 Docker 容器的情况下,此选项非常有用。该--isolation=<value>选项设置容器的隔离技术。在 Linux 上,唯一支持的是default使用 Linux 命名空间的选项。在 Microsoft Windows 上,您可以指定以下值:

价值描述
default使用 Docker 守护进程的--exec-opt.如果daemon未指定隔离技术,Microsoft Windows 将使用process其默认值。
process仅命名空间隔离。
hypervHyper-V 管理程序基于分区的隔离。

指定--isolation不带值的标志与设置相同--isolation="default"

将条目添加到容器主机文件(--add-host)

/etc/hosts您可以使用一个或多个标志将其他主机添加到构建容器的文件中--add-host。此示例为名为 my-hostname和 的主机添加静态地址my_hostname_v6

$ docker build --add-host my_hostname=8.8.8.8 --add-host my_hostname_v6=2001:4860:4860::8888 .

如果您需要构建连接到主机上运行的服务,则可以使用 的特殊host-gateway--add-host。在以下示例中,构建容器解析host.docker.internal为主机的网关 IP。

$ docker build --add-host host.docker.internal=host-gateway .

您可以将 IPv6 地址括在方括号中。 =:都是有效的分隔符。以下示例中的两种格式均有效:

$ docker build --add-host my-hostname:10.180.0.1 --add-host my-hostname_v6=[2001:4860:4860::8888] .

指定目标构建阶段(--target)

当构建具有多个构建阶段的 Dockerfile 时,您可以使用该--target 选项按名称指定中间构建阶段作为生成映像的最终阶段。守护进程会跳过目标阶段之后的命令。

FROM debian AS build-env
# ...

FROM alpine AS production-env
# ...
$ docker build -t mybuildimage --target build-env .

自定义构建输出(--output)

笔记

此功能需要 BuildKit 后端。您可以 启用 BuildKit或使用 提供更多输出类型选项的buildx插件。

默认情况下,本地容器镜像是根据构建结果创建的。--output(或)标志 -o允许您覆盖此行为,并指定自定义导出器。自定义导出器允许您将构建工件导出为本地文件系统上的文件而不是 Docker 映像,这对于生成本地二进制文件、代码生成等非常有用。

的值--output是一个 CSV 格式的字符串,定义导出器类型以及支持导出器的local选项tar

导出器local将生成的构建文件写入客户端的目录中。导出 tar器类似,但将文件写入单个 tarball ( .tar)。

如果未指定类型,则该值默认为本地导出器的输出目录。使用连字符 ( -) 将输出 tarball 写入标准输出 ( STDOUT)。

以下示例使用当前目录 ( .) 作为构建上下文来构建映像,并将文件导出到out当前目录中指定的目录。如果该目录不存在,Docker 会自动创建该目录:

$ docker build -o out .

上面的示例使用简写语法,省略了选项type,因此使用默认的 ( local) 导出器。下面的示例显示了使用普通 CSV 语法的等效内容,同时指定了typeand dest(目标路径):

$ docker build --output type=local,dest=out .

使用该tar类型将文件导出为.tar存档:

$ docker build --output type=tar,dest=out.tar .

下面的示例显示了使用简写语法时的等效内容。在本例中,-被指定为目标,它会自动选择类型tar,并将输出 tarball 写入标准输出,然后将其重定向到文件out.tar

$ docker build -o - . > out.tar

--output选项从目标阶段导出所有文件。仅导出特定文件的常见模式是进行多阶段构建,并将所需文件复制到新的暂存阶段 COPY --from

下面的示例Dockerfile使用单独的阶段来收集构建工件以供导出:

FROM golang AS build-stage
RUN go get -u github.com/LK4D4/vndr

FROM scratch AS export-stage
COPY --from=build-stage /go/bin/vndr /

使用该选项构建 Dockerfile 时-o,该命令仅将最后阶段的文件导出到目录out,在本例中为vndr二进制文件:

$ docker build -o out .

[+] Building 2.3s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                                          0.1s
 => => transferring dockerfile: 176B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                             0.0s
 => => transferring context: 2B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/golang:latest                                                              1.6s
 => [build-stage 1/2] FROM docker.io/library/golang@sha256:2df96417dca0561bf1027742dcc5b446a18957cd28eba6aa79269f23f1846d3f   0.0s
 => => resolve docker.io/library/golang@sha256:2df96417dca0561bf1027742dcc5b446a18957cd28eba6aa79269f23f1846d3f               0.0s
 => CACHED [build-stage 2/2] RUN go get -u github.com/LK4D4/vndr                                                              0.0s
 => [export-stage 1/1] COPY --from=build-stage /go/bin/vndr /                                                                 0.2s
 => exporting to client                                                                                                       0.4s
 => => copying files 10.30MB                                                                                                  0.3s

$ ls ./out
vndr

指定外部缓存源(--cache-from)

笔记

此功能需要 BuildKit 后端。您可以 启用 BuildKit或使用 buildx插件。以前的构建器对从预拉取的图像中重用缓存的支持有限。

除了本地构建缓存之外,构建器还可以使用--cache-from指向注册表中图像的标志来重用以前构建生成的缓存。

要使用图像作为缓存源,需要在创建时将缓存元数据写入图像中。您可以通过--build-arg BUILDKIT_INLINE_CACHE=1 在构建图像时进行设置来做到这一点。之后,您可以使用构建的镜像作为后续构建的缓存源。

导入缓存后,构建器仅从注册表中提取 JSON 元数据,并根据该信息确定可能的缓存命中。如果存在缓存命中,构建器会将匹配的图层拉入本地环境。

除了图像之外,还可以从 buildxBuildKit CLI ( buildctl) 生成的特殊缓存清单中提取缓存。这些清单(当使用type=registrymode=max 选项构建时)允许为多阶段构建中的中间阶段拉取层数据。

以下示例使用内联缓存元数据构建一个映像并将其推送到注册表,然后将该映像用作另一台计算机上的缓存源:

$ docker build -t myname/myapp --build-arg BUILDKIT_INLINE_CACHE=1 .
$ docker push myname/myapp

推送镜像后,该镜像将作为另一台机器上的缓存源。如果需要,BuildKit 会自动从注册表中提取映像。

在另一台机器上:

$ docker build --cache-from myname/myapp .

在构建期间设置 RUN 指令的网络模式(--network)

概述

网络模式的可用选项有:

  • default(默认):在默认网络中运行。
  • none:在没有网络访问的情况下运行。
  • host:在主机的网络环境中运行。

在Dockerfile 文档中查找更多详细信息 。

挤压图像的图层(--squash)(实验)

概述

注意--squash选项是一个实验性功能,不应被视为稳定。

构建图像后,此标志会将新图层压缩为具有单个新图层的新图像。挤压不会破坏任何现有图像,而是使用挤压图层的内容创建一个新图像。这有效地使其看起来像是所有Dockerfile命令都是使用单个层创建的。该--squash标志保留构建缓存。

如果您的 Dockerfile 生成修改相同文件的多个层,则压缩层可能会很有用。例如,在一个步骤中创建并在另一步骤中删除的文件。对于其他用例,压缩图像实际上可能会对性能产生负面影响。当拉取由多个层组成的图像时,守护进程可以并行拉取层并允许在图像之间共享层(节省空间)。

对于大多数用例,多阶段构建是更好的选择,因为它们可以对构建进行更细粒度的控制,并且可以利用构建器中的未来优化。 有关更多信息,请参阅 多阶段构建部分。

已知的限制

--squash选项有许多已知的限制:

  • 压缩图层时,生成的图像无法利用与其他图像共享图层的优势,并且可能会使用更多的空间。仍然支持共享基础镜像。
  • 使用此选项时,您可能会发现由于存储图像的两份副本而使用了更多的空间,一份用于所有缓存层完好无损的构建缓存,另一份用于压缩版本。
  • 虽然压缩图层可能会产生较小的图像,但它可能会对性能产生负面影响,因为提取单个图层需要更长的时间,并且您无法并行下载单个图层。
  • 当尝试压缩未对文件系统进行更改的映像时(例如,Dockerfile 仅包含ENV指令),压缩步骤将失败(请参阅 问题 #33823)。

先决条件

本页的示例是在 Docker 23.03 中使用实验模式。

您可以通过--experimental在启动 Docker 守护进程时使用该标志或在配置文件experimental: true中进行设置来启用实验模式daemon.json

默认情况下,实验模式处于禁用状态。要查看 Docker 守护程序的当前配置,请使用命令docker version并检查Experimental 以下部分中的行Engine

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

test接下来,构建一个使用标志命名的图像--squash

$ docker build --squash -t test .

构建完成后,历史记录如下所示。历史记录可以显示图层名称为<missing>,并且有一个带有 COMMENT 的新图层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