如何强制Docker清理构建图像

Pav*_*pta 684 docker aerospike

我使用下面的命令从Docker文件构建了一个Docker镜像.

$ docker build -t u12_core -f u12_core .
Run Code Online (Sandbox Code Playgroud)

当我尝试使用相同的命令重建它时,它正在使用构建缓存,如:

Step 1 : FROM ubuntu:12.04
 ---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
 ---> Using cache
 ---> 4354ccf9dcd8
Step 3 : RUN apt-get update
 ---> Using cache
 ---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
 ---> Using cache
 ---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
 ---> Using cache
 ---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
 ---> Using cache
 ---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
 ---> Using cache
 ---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
 ---> Using cache
 ---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
 ---> Using cache
 ---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
 ---> Using cache
 ---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
 ---> Using cache
 ---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
 ---> Using cache
 ---> 47d1660bd544
Step 13 : RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 ---> Using cache
 ---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
 ---> Using cache
 ---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
 ---> Using cache
 ---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
 ---> Using cache
 ---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
 ---> Using cache
 ---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
 ---> Using cache
 ---> 25f5fe70fa84
Successfully built 25f5fe70fa84
Run Code Online (Sandbox Code Playgroud)

缓存显示已安装aerospike.但是,我没有在这个图像中产生的容器内找到它,所以我想重建这个图像而不使用缓存.如何在没有缓存的情况下强制Docker重建干净的图像?

Ass*_*vie 1231

有一个--no-cache选择:

docker build --no-cache -t u12_core -f u12_core .
Run Code Online (Sandbox Code Playgroud)

在旧版本的Docker中你需要传递--no-cache=true,但现在不再是这种情况了.

  • 另请注意,`--no-cache`适用于`docker-compose build`. (65认同)
  • 您可能还想使用`--pull`.这将告诉docker获取最新版本的基本映像.如果你已经有了基本图像(例如:`ubuntu/latest`),那么除了`--no-cache`之外,这是必要的,并且基础图像自上次拉动以来已经更新.请参阅docs [here](https://docs.docker.com/engine/reference/commandline/build/#options). (25认同)
  • @CollinKrawll:`--pull`选项对我有用。只是--no-cache,构建仍然失败了。也放入`--pull`,构建成功!谢谢! (2认同)
  • 如果有人调用 docker build ,是不是假设他们想要在没有缓存的情况下重建?在什么用例中,有人会想要构建一个镜像并使用之前构建的镜像?&lt;rant&gt; 我刚刚损失了一天,因为早期的构建悄无声息地失败了,但“成功”完成了,而且我使用的是损坏的图像,不明白为什么构建脚本的更新不起作用&lt;/rant&gt; (2认同)
  • @Jeff开发docker映像时,docker build将仅重做已修改的层/步骤。如果我有五个步骤,并在索引3处添加了一个新步骤,则可以重复使用与步骤1和2关联的图层。这大大加快了开发过程 (2认同)
  • @Jeff 我必须构建需要 2 小时才能完全构建的图像。在这些情况下缓存非常有用。如果有效使用,将会节省大量时间。构建 docker 镜像以充分利用这一点是很常见的。 (2认同)

Wal*_*rée 109

在某些极端情况下,绕过重复出现的构建失败的唯一方法是运行:

docker system prune
Run Code Online (Sandbox Code Playgroud)

该命令将要求您确认:

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N]
Run Code Online (Sandbox Code Playgroud)

这当然不是这个问题的直接答案,但可能会挽救一些生命......它确实拯救了我的生命.

  • 这甚至会删除已停止容器的映像,这可能是您不想要的。最新版本的 docker 有命令“docker builder prune”来清除缓存的构建层。盲目地从堆栈溢出复制命令后就陷入了陷阱。 (8认同)
  • 添加-a -f使其更好 (7认同)
  • 仍然没有清除图层缓存. (6认同)
  • 这甚至不能作为问题的解决方案。 (4认同)
  • 对于这种情况来说,这太过分了,如果您不想删除所有内容,那么这不是一个可用的答案。 (3认同)

小智 56

该命令docker build --no-cache .解决了我们类似的问题.

我们的Dockerfile是:

RUN apt-get update
RUN apt-get -y install php5-fpm
Run Code Online (Sandbox Code Playgroud)

但应该是:

RUN apt-get update && apt-get -y install php5-fpm
Run Code Online (Sandbox Code Playgroud)

防止缓存更新并单独安装.

请参阅:编写Dockerfiles的最佳实践

  • "应该是"是误导性的.如果Docker发现它有一个缓存的副本`RUN apt-get update && apt-get -y install php5-fpm`,你仍会看到它被重用旧内容. (9认同)
  • 实际上加入它们仍然是有意义的,否则如果你改变安装线,它仍然会使用旧的包缓存,如果缓存过期(通常,文件将是404),这通常会有问题. (9认同)

dav*_*xxx 26

这里的大部分信息都是正确的。
这是它们的汇编以及我使用它们的方式。

这个想法是坚持推荐的方法(构建特定的并且对其他存储的 docker 对象没有影响)并在不够时尝试更激进的方法(不是构建特定的并且对其他存储的 docker 对象有影响)。

推荐方法:

1) 强制执行 Dockerfile 中的每个步骤/指令:

docker build --no-cache 
Run Code Online (Sandbox Code Playgroud)

或与docker-compose build

docker-compose build --no-cache
Run Code Online (Sandbox Code Playgroud)

我们还可以将其与up重新创建所有容器的子命令结合起来:

docker-compose build --no-cache &&
docker-compose up -d --force-recreate 
Run Code Online (Sandbox Code Playgroud)

这些方式不使用缓存,而是使用 docker builder 和FROM指令引用的基本图像。

2)擦除docker builder缓存(如果我们使用Buildkit,我们很可能需要它):

docker builder prune -af
Run Code Online (Sandbox Code Playgroud)

3)如果我们不想使用父图片的缓存,我们可以尝试删除它们,例如:

docker image rm -f fooParentImage
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,这 3 件事足以让我们的形象干净利落。
所以我们应该努力坚持这一点。

更激进的方法:

在构建过程中似乎仍在使用 docker 缓存中的某些对象并且看起来可重复的极端情况下,我们应该尝试了解原因,以便能够非常具体地擦除丢失的部分。如果我们真的找不到从头开始重建的方法,还有其他方法,但重要的是要记住,这些方法通常会删除比所需的多得多的内容。所以当我们不在本地/开发环境中时,我们应该谨慎地使用它们。

1) 删除所有没有至少一个容器关联的图像:

docker image prune -a
Run Code Online (Sandbox Code Playgroud)

2)删除更多的东西:

docker system prune -a
Run Code Online (Sandbox Code Playgroud)

说的是 :

警告!这将删除:
  - 所有停止的容器
  - 至少一个容器未使用的所有网络
  - 没有至少一个容器关联的所有图像
  - 所有构建缓存

使用该超级删除命令可能还不够,因为它在很大程度上取决于容器的状态(运行与否)。当该命令不够用时,我会尝试仔细考虑哪些 docker 容器可能会对我们的 docker 构建产生副作用,并允许退出这些容器,以便通过命令删除它们。


Oli*_*ier 13

我不建议--no-cache在你的情况下使用.

您正在运行从步骤3到9的几个安装(顺便说一句,我希望使用一个内衬),如果您不希望每次构建图像​​时重新运行这些步骤的开销,您可以Dockerfile在您的wget指示之前通过临时步骤修改您的.

我习惯做类似的事情RUN ls .并将其改为RUN ls ./当时RUN ls ./.等等,对于检索到的tarball进行的每个修改都是如此wget

你当然可以做一些事情,例如RUN echo 'test1' > test && rm test增加'test1每次迭代的数量.

它看起来很脏,但据我所知,它是继续受益于Docker缓存系统的最有效方式,当你有多层时节省时间......

  • 许多人都要求能够在某一点之后不使用高速缓存(请参见https://github.com/moby/moby/issues/1996了解高速缓存清除的替代方法) (2认同)

M_d*_*_dk 9

为确保完全重建您的构建,包括检查基础映像是否有更新,请在构建时使用以下选项:

--no-cache -这将强制重建已经可用的图层

--pull -这将触发对使用FROM引用的基本映像的拉动,以确保获得最新版本。

因此,完整的命令将如下所示:

docker build --pull --no-cache --tag myimage:version .
Run Code Online (Sandbox Code Playgroud)

相同的选项可用于docker-compose:

docker-compose build --no-cache --pull
Run Code Online (Sandbox Code Playgroud)

  • 这个应该就是答案。 (4认同)
  • 奇怪的是这对我不起作用! (2认同)

小智 8

有时docker build --no-cache,甚至删除系统上的所有容器和映像也不会清除所有 docker 内容,在这种情况下,您应该使用docker system prune, 来删除所有未使用的容器、网络、映像和卷。这将删除所有缓存的数据,包括任何悬空的图像或容器。因此,要实现强制全新构建,请运行以下命令:

//remove all containers
1- docker rm -f $(docker ps -aq) 

//remove all images
2- docker image rm $(docker images -q)  

/remove all unused containers, networks, images, and volumes
3- docker system prune  /
Run Code Online (Sandbox Code Playgroud)

所以现在与 docker 相关的任何内容都消失了,并且 docker 缓存也被完全删除,就像您有一个全新的 docker 安装一样。


小智 7

使用docker-compose试试 docker-compose up -d --build --force-recreate


小智 5

您可以使用以下方式管理构建器缓存docker builder

要在没有提示的情况下清理所有缓存: docker builder prune -af