如何强制Docker清理构建图像

时间:2016-02-24 06:37:48

标签: docker aerospike

我使用以下命令从Docker文件构建了Docker镜像。

$ docker build -t u12_core -f u12_core .

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

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

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

9 个答案:

答案 0 :(得分:947)

有一个--no-cache选项:

docker build --no-cache -t u12_core -f u12_core .

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

答案 1 :(得分:92)

在某些极端情况下,您可以通过运行以下方式解决重复出现的构建失败:

docker system prune

该命令会要求您确认:

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]

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

答案 2 :(得分:50)

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

我们的Dockerfile是:

RUN apt-get update
RUN apt-get -y install php5-fpm

但应该是:

RUN apt-get update && apt-get -y install php5-fpm

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

请参阅: Best practices for writing Dockerfiles

答案 3 :(得分:15)

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

这个想法是坚持推荐的方法(构建特定的,对其他存储的docker对象无影响),并尝试更彻底的方法(不构建特定的且对其他存储的docker对象无影响)。

推荐方法:

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

docker build --no-cache 

或使用docker-compose build

docker-compose build --no-cache

我们还可以将其组合到重新创建所有容器的up子命令中:

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

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

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

docker builder prune -af

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

docker image rm -f fooParentImage

在大多数情况下,这三件事足以使我们的形象清晰无瑕。
因此,我们应该坚持这一点。

更彻底的方法:

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

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

docker image prune -a

2)删除更多内容:

docker system prune -a

那是:

WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache

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

答案 4 :(得分:11)

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

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

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

完整的命令将如下所示:

docker build --pull --no-cache --tag myimage:version .

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

docker-compose build --no-cache --pull

答案 5 :(得分:10)

我不建议您使用--no-cache

您将在第3步到第9步中运行几个安装(顺便说一句,我更喜欢使用一个衬垫),如果您不希望每次构建时都重新运行这些步骤的开销图片,您可以在Dockerfile指令之前通过一个临时步骤来修改wget

我曾经做过类似RUN ls .的事情,然后将其更改为RUN ls ./,然后将其更改为RUN ls ./.,依此类推,对wget检索到的tarball进行的每次修改都是如此

您当然可以做类似RUN echo 'test1' > test && rm test的操作,为每次迭代增加'test1中的数字。

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

答案 6 :(得分:1)

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

答案 7 :(得分:0)

GUI驱动的方法::打开Docker桌面工具(通常是Docker附带的):

  1. 在“容器/应用程序”下停止该图像的所有正在运行的实例
  2. 在“图像”下删除构建图像(将鼠标悬停在框名称上方以获得上下文菜单),最后还要删除基础基础图像

答案 8 :(得分:-1)

您可以使用docker builder

管理构建器缓存

要在不提示的情况下清除所有缓存,请执行以下操作: docker builder prune -af