如何强制构建干净的 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@tutorialspoint.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 build 命令一起使用。
$ 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 选项。

