docker - 缓存无效后如何删除已缓存/中间的Docker镜像

标签 docker continuous-integration docker-image

我有一个CI管道,可以为管道的每次运行都为我的应用程序构建一个docker镜像(并且该管道是通过将代码推送到git存储库触发的。)

docker 镜像由几个中间层组成,这些中间层的大小逐渐变大。对于每个运行,大多数中间镜像都是相同的,因此,大大利用了docker的缓存机制。

但是,问题在于每次运行的最后几层是不同的,这是因为它们是由dockerfile中的COPY语句导致的,在该语句中,已构建的应用程序工件被复制到镜像中。由于工件在每次运行时都会被修改,因此已经缓存的最底端图像将始终无效。这些图像的大小均为800mb。

我可以使用什么docker命令来识别(并删除)这些被新镜像替换的镜像,即何时使它们无效?

我想让我的CI管道在运行结束时删除它们,以免它们最终卡在CI服务器上而浪费大量磁盘空间。

最佳答案

如果我理解正确:每执行一次代码推送,CI管道就会创建新镜像,并在其中部署新版本的应用程序。结果,以前创建的图像已过时,因此您要删除它。为此,您必须:

  • 摆脱所有过时的容器,这些容器是根据过时的镜像创建的
  • 使用命令docker ps -a显示所有容器
  • (如果仍在运行),请使用命令docker stop [containerID]
  • 停止过时的容器
  • command docker rm [containerID]删除它们
  • 使用以下命令删除过时的图像:docker rmi [imageID]

  • 总结为什么需要此过程:在任何现有容器使用它之前,您无法删除任何图像(即使停止的容器仍需要其图像)。因此,您应该先停止并删除旧容器,然后再删除旧图像。

    检测部分和删除过程的自动化应基于CI版本在创建新图像时生成的图像版本和容器名称。在不知道您的管道如何正常工作的情况下,很难提供任何具体的解决方案。

    编辑1

    要列出所有与任何已标记图像无关的图像,可以使用命令:docker images -f dangling=true。您可以使用以下命令删除它们:docker images purge

    在此仅需记住的一件事:如果构建图像时未对其进行标记,则该图像将出现在“悬空”图像列表中。您可以通过在构建标记时提供标记来避免这种情况。

    关于docker - 缓存无效后如何删除已缓存/中间的Docker镜像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51612208/

    相关文章:

    ruby-on-rails - 如何解决错误 "bundler could not find compatible version for gem X"

    continuous-integration - Gitlab CI - 无法注册运行者

    docker - 运行 Docker 镜像时的错误响应

    build - VSTS 构建所有分支

    .net - NUnit 和与 Jenkins 的持续集成 : which NUnit-files are needed?

    security - Anchore Engine - Jenkins CI 插件

    angular - ngt_prehh在ng2-admin中缺少脚本

    java - 使用 activemq 添加 camunda-bpm-wildfly 并在同一个 docker 容器中运行

    docker - 我如何在 docker-machine create 上执行脚本

    python - 在 Mac 上安装了 Docker 但找不到命令