如何强制干净构建 Docker 映像?

当您执行 Docker pull 命令或 Docker run 命令时,守护进程首先通过比较镜像的摘要来检查本地机器中是否有类似的镜像。

如果找到匹配项,则不需要在注册表中搜索映像,守护程序可以简单地创建现有映像的副本。但是,如果找不到副本,它会开始从注册表中提取它。当您尝试使用 Dockerfile 构建映像时,情况也是如此。

我们都知道 Docker 镜像是包含多个镜像层的多层文件。Dockerfile 中提到的每条指令都负责创建一个新层。

一个层只包含前一层和当前层之间的差异。如果您之前构建了相同的图像,守护进程将寻找包含相同图像层的缓存。如果找到后续缓存,它将仅使用此缓存而不构建新层。

但是,在某些情况下,即使存在后续层的构建缓存,您也可能希望强制构建干净的映像。在这里,Docker 也支持你。让我们看看如何强制清理构建 Docker 映像。

考虑下面的 Dockerfile。

RUN apt-get update
RUN apt-get -y install vim

在上面的 Dockerfile 中,我们在不同的行中使用了两个不同的 RUN 指令。这会导致构建单独的图像层和构建缓存。当 Docker 守护进程处理诸如 RUN apt-get -y update 之类的更新命令时,不会比较更新命令在其上工作的容器内的那些包,以确定是否发生缓存命中。在这种情况下,仅比较命令字符串以找到匹配项。

您可以将它们链接起来以减少图像层的数量,从而降低缓存命中的可能性,而不是为两个连续的 RUN 指令使用两个单独的行。

RUN apt-get update && apt-get -y install vim

如果您根本不想让守护程序执行缓存检查,则可以使用--no-cache选项来执行此操作。当您使用 Docker build 命令构建 Docker 镜像时,您可以简单地使用 --no-cache 选项,该选项将允许您指示守护程序不要查找已经存在的镜像层,而只需强制清理构建镜像。

例如,如果您想从以下 Dockerfile 构建映像 -

FROM                                                                 ubuntu:latest
WORKDIR /app
COPY                                      .                                      .
MAINTAINER                                                admin@nhooo.com
RUN        apt-get                        -y                                update
RUN        apt-get           install      -y                         openjdk-7-jdk
RUN        apt-get           install      -y                              git-core
RUN        apt-get           install      -y                       build-essential
RUN        apt-get           install      -y                           lsb-release
CMD ["javac", "sample.java"]

假设您之前已经构建了此映像,并且您现在在构建上下文中进行了一些更改。因此,COPY 指令缓存会中断,所有后续指令的缓存也会中断。如果您没有进行任何更改并再次构建映像,则不会出现缓存中断,守护程序仅使用图像层的现有缓存来构建映像。

这是默认行为,如果要覆盖此默认行为,可以将 --no-cache 选项与 Docker 构建命令一起使用。

$ docker build --no-cache -t sample-image:sample-tag .

当您执行此命令时,守护程序将不会查找现有镜像层的缓存构建,而是会强制从 Dockerfile 清洁构建 Docker 镜像。

如果您使用 Docker compose,则可以使用以下命令。

$ docker-compose build --no-cache

您还可以将其与 up 命令链接以重新创建所有容器。

$ docker-compose build --no-cache && docker-compose up -d --force-recreate

请注意,这些方式不使用缓存,而是使用 FROM 指令引用构建器和基础图像。您可以使用 - 清理构建器缓存

$ docker builder prune -af

如果您不想使用它的缓存,您也可以清除父图像。

$ docker image rm -f parent-image

这些是您可以用来强制清理图像构建和避免使用图像层缓存的最常见方法。最好也可能是最简单的选项是使用 --no-cache 选项。