创建基础镜像

大多数Dockerfile以父镜像为起点。如果需要完全控制镜像的内容,则可能需要创建基础镜像。区别在于:

  • 父镜像是镜像所基于的镜像。 它使用Dockerfile中FROM指令引用。 Dockerfile中的每个后续声明都会修改此父镜像。 大多数Dockerfile从父镜像而不是基础镜像开始。 但是,这两个术语有时可以互换使用。

  • 基础镜像应在Dockerfile中使用FROM scratch

本主题向您展示了创建基础镜像的几种方法。 具体过程将在很大程度上取决于您要打包的Linux发行版。 我们在下面提供了一些示例,建议您提交请求以贡献新的示例。

使用tar创建完整镜像

通常,在我们的工作机器上运行着您要作为父镜像打包的发行版,尽管某些工具(例如Debian的Debootstrap)并不需要,也可以用来构建Ubuntu镜像。

创建Ubuntu父镜像很简单:

$ sudo debootstrap xenial xenial > /dev/null
$ sudo tar -C xenial -c . | docker import - xenial

a29c15f1bf7a

$ docker run xenial cat /etc/lsb-release

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"

在Docker GitHub Repo中还有更多用于创建父镜像的示例脚本:

使用scratch创建一个简单的父镜像

您可以使用Docker的保留,最小镜像,scratch作为构建容器的起点。 使用scratch“镜像”向构建过程发出信号,表示您希望Dockerfile中的下一个命令成为镜像中的第一个文件系统层。

scratch出现在hub上的Docker仓库,您无法对其进行拉取,运行或使用scratch名称标记任何镜像。 但是,您可以在Dockerfile中引用它。 例如,使用scratch创建一个最小的容器:

FROM scratch
ADD hello /
CMD ["/hello"]

假设您按照https://github.com/docker-library/hello-world/上的说明构建了“hello”可执行示例,并使用-static标记对其进行了编译,则可以使用此docker build命令构建该Docker镜像。

docker build --tag hello .

别忘了最后一个字符.,它将构建上下文设置为当前目录。

注意:由于Docker Desktop for Mac和Docker Desktop for Windows使用Linux VM,因此您需要Linux二进制文件,而不是Mac或Windows二进制文件。 您可以使用Docker容器来构建它:

$ docker run --rm -it -v $PWD:/build ubuntu:16.04

container# apt-get update && apt-get install build-essential
container# cd /build
container# gcc -o hello -static -nostartfiles hello.c

要运行新镜像,请使用docker run命令:

docker run --rm hello

本示例创建了教程中使用的hello-world镜像。 如果要对其进行测试,则可以克隆镜像仓库

更多资源

有许多可用资源可帮助您编写Dockerfile。

  • 在参考部分中,有一份在Dockerfile中使用的所有指令的完整指南
  • 为了帮助您编写精简,可读,可维护的Dockerfile,我们还编写了Dockerfile[最佳指南]/docker/docker-guides/best-practices-for-writing-dockerfiles)。
  • 如果您的目标是创建新的官方映像,请务必阅读Docker的官方映像