Docker镜像名称会自动更改

3

我在我的主机(Ubuntu Server)上运行了多个容器

我通过以下命令运行 docker 容器:

sudo docker run -d -p 5050:80 gitname/reponame

当我执行 sudo docker ps 命令时,它会显示:

CONTAINER ID: e404ffa2bc6b 
IMAGE: gitname/reponame 
COMMAND: "dotnet run --server…"
CREATED: 14 seconds ago
STATUS: Up 12 seconds
PORTS: 5050/tcp, 0.0.0.0:5050->80/tcp
NAMES: reverent_mcnulty

一周后我再次运行sudo docker ps命令时,会显示其他信息,其中IMAGE已更改,并且看起来类似于ba2486f19dc0。

我不明白为什么会这样。

这对我来说是个问题,因为我使用以下命令停止容器:

sudo docker stop $(sudo docker ps | awk '{ print $1,$2 }' | grep gitname/reponame |  awk '{print $1 }')

这个不起作用是因为图像名称已经被更改了。


与此同时,您是否运行了另一个 docker builddocker pull 命令来更新该镜像标签? - David Maze
@DavidMaze 不,我只是从Docker Hub拉取并运行了它,并且还从Docker Hub运行了另一个构建。 - Igor Cova
1
您可以为容器添加名称:sudo docker run -d -p 5050:80 --name my_app gitname/reponame,然后使用 docker stop my_appdocker start my_app - quentino
@quentino,它会更改名称,但不会更改图像。 - Igor Cova
1个回答

3
每个Docker镜像都有一个唯一的十六进制ID。这些ID在不同系统上(即使是相同镜像的docker pull)也可能不同,但每个镜像只有一个ID。
每个镜像都有一些与之关联的标签,这可能是零个或多个。docker tag会将标签添加到现有镜像中;docker rmi会删除标签,并且(如果镜像没有其他标签、没有其他使用该镜像作为基础的镜像和没有存在的容器使用该镜像),还会删除镜像。
可以“窃取”现有镜像的标签。最明显的方法是使用docker build:
cat >Dockerfile <<EOF
FROM busybox
COPY file.txt /
EOF
echo foo > file.txt
docker build -t foo .

docker images
# note the ID for foo:latest

echo bar > file.txt
docker build -t foo .

docker images
# note the old ID will show as foo:<none>
# note a different ID for foo:latest

一个明确的docker tag也可以做到这一点。 Docker Hub和其他存储库中的镜像也可能会发生变化(ubuntu:16.04通常会重新发布带有安全更新的版本),所以如果您docker pull已有的镜像,它可能会因为新版本而“失去名称”。
这与docker rundocker ps如何交互呢?docker run可以记住启动镜像时使用的镜像标签,但是如果该镜像不再具有该标签,则会忘记该数据。这就是为什么您的docker ps输出会回归显示镜像的十六进制ID。
对于您的应用程序,有几种解决方法:
- 如果镜像是您自己构建的,请始终在构建和运行镜像时使用明确的版本标记(可以是当前日期戳)。然后,您永远不会覆盖现有镜像的标记。(“不要使用:latest标记。”) - 使用docker run --name来跟踪每个容器,并基于此筛选,而不是根据镜像标记。(@quentino在评论中提供的建议。) - 在工作流程中不要显式地docker pull。如果您没有镜像,docker run会自动为您拉取它。这将避免现有镜像获得小更新,并且还将避免现有镜像失去名称。

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