如何升级Docker镜像而不创建新镜像?

20
似乎这是我找不到答案的最简单的问题。
1. 我构建了一个 Docker 镜像。 2. 运行 docker images 显示它已存在。 3. 然后我在 Dockerfile 中添加了一行新代码。 4. 接着我重新构建了镜像。 5. 旧镜像仍然在 docker images 中,并且现在有一个新的镜像。
如何只更新旧镜像而不创建新镜像呢?
我的 Docker 命令:docker build -t nick_app . --force-rm --no-cache (注意:我刚才把那些 --force-rm 命令和 --no-cache 命令扔掉了,因为看起来它们会起作用。) 之前: Dockerfile:
FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y
CMD ["echo", "Sup"]

docker镜像命令:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nick_app            latest              421662154c3f        9 minutes ago       746.9 MB
ruby                2.3.3               d00ebde6a601        2 days ago               730.1 MB
hello-world         latest              c54a2cc56cbb        4 months ago          1.848 kB

之后: Dockerfile:

FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y \
   build-essential
CMD ["echo", "Sup"]

docker镜像命令:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nick_app            latest              bcf9b3667202        3 seconds  ago       746.9 MB
<none>              <none>              421662154c3f        10 minutes ago      746.9 MB
ruby                2.3.3               d00ebde6a601        2 days ago          730.1 MB
hello-world         latest              c54a2cc56cbb        4 months ago        1.848 kB

每次我修改Dockerfile并重新构建后,都会创建一个新的none镜像。它们是累积的,所以每次我进行更改和重建时,都会得到另一个none镜像。
如何才能在每次修改Dockerfile后摆脱这个中间的none呢?

毕竟,你正在创建图像的新版本,所以发生的事情是有意义的。你需要用一些方式来包装它,比如编写一个 bash 脚本,而不是直接调用 docker build 命令(使用答案中显示的命令)。 - Arran
从技术上讲,当我对文本文件进行更改时,它在某种程度上是文本文件的新版本,但是文字处理器仍然会在原地更新新的文本文件而不创建中间文件,这是有道理的。看起来这可能是Docker应用程序的一个有用案例:如果我使用相同的标签重新构建,则假定它将是相同的映像,并删除所有中间/旧版本。 - Dr. Chocolate
2个回答

19

那些<none>:<none>实际上是您应用程序的旧版本,由于您将nick_app:latest移动到了新构建中,因此它失去了命名指针。

在构建映像时,我认为您不能告诉它销毁旧映像,它只会创建一个新映像。但是有一条命令可以帮助您列出或删除这些悬空映像:

docker images --filter dangling=true #lists all images that are dangling and has no pointer to it
docker rmi `docker images --filter dangling=true -q` #Removes all those images.

8
谢谢提供信息。 不太喜欢没有标志或选项可以自动执行此操作。 这似乎是一个相当常见的用例。 我有一个快捷方式 docker rmi $(docker images -f "dangling=true" -q), 但每次重建都要这样做似乎有点不够优雅。 - Dr. Chocolate
“dicker image rm”和“docker rmi”之间有什么区别吗? - CpILL
@CpILL,是Docker,不是Dicker,哈哈。docker rmi用于删除具有相同ID但不同标签的映像。而docker image rm用于删除不符合上述情况的Docker映像。 - KunYu Tsai

1

您可以使用:

docker build -t nick_app . --force-rm --no-cache && docker image prune -a --force

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接