翻译·原文地址

大多数 Dockerfile 是从父镜像开始的。如果需要完全控制你的镜像内容,则需要创建基础镜像。区别是:

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

  • 基础镜像在其 Dockerfile 中没有 FROM 行,或者具有 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 Repository 中,但你无法拉取,运行或标记任何名称为 scratch 的镜像。但是,你可以在 Dockerfile 中引用它。例如,要使用 scratch 创建一个最小容器:

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

假设你按照 https://github.com/docker-library/hello-world/ 上的说明构建了 “hello” 可执行示例,并使用 -static 标志编译它,你可以使用 docker builed 命令构建此 Docker 镜像:

$ docker build --tag hello .

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

注意:由于 Docker for Mac 和 Docker 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

(完)