如果您没有碰巧使用最新版本的docker镜像(类似于npm outdated, gradlew dependencyUpdates gem outdated
(,如何在包含多个服务的docker compose文件中找到新版本的docker镜像的可用性
Docker镜像不像包管理器那样具有版本的概念。Docker图像具有标签。这些标签可以是图像作者选择的任何标签。一些图像作者可能会发布指示图像中软件版本的标签,而其他图像作者可能只是随着时间的推移将更新的图像推到同一标签之上。
例如,如果您在指定图像时使用nginx:mainline
标记,那么它将在您提取图像时获取当前nginx主线版本。这是由于nginx
官方图像出版商在标记图像的方式上所采取的政策。它们还有特定的版本标签,如nginx:1.21.1
,在编写此答案时,它恰好指向与nginx:mainline
相同的Blob。
给定特定的图像标记策略,可以将docker-compose.yml
设置为指向nginx:mainline
并定期运行docker-compose up --pull -d
。这将导致compose再次尝试拉取nginx:mainline
映像,然后循环任何需要循环的容器。在注册表中存在较新的nginx:mainline
映像的情况下,compose将提取该新映像,然后使用该新映像重新创建容器。
docker compose本身无法将注册表上的内容与本地docker引擎上的内容进行比较。
您可以通过API查询注册表以查看给定标记返回的sha256摘要,或者使用reg
CLI工具与注册表交互:https://github.com/genuinetools/reg
继续以nginx:mainline
为例,假设我使用nginx:mainline
部署了我的compose文件,当时对应的版本是1.20.0,但现在1.21.1已经发布。我会做以下比较:
docker inspect nginx:mainline --format '{{.Id}}'
这将返回nginx:mainline
的长sha256图像id
然后我可以用以下内容查询存储库:
reg manifest nginx:mainline
这将返回一个描述图像及其层的json文档。在config
密钥中,有一个digest
密钥。如果这个键匹配,你就知道它是同一个图像。如果不同,则表示远程副本不同。
您可以将jq
与此命令结合使用以获得正确的值:
reg manifest nginx:mainline | jq -r .config.digest
这意味着,如果我重新运行docker-compose up --pull -d
,远程映像将被提取,并且我的容器将被重新创建以使用它
--
如果您使用特定的版本标记而不是主线标记,那么您可以编写可用标记的脚本,并尝试以编程方式确定是否有新版本。
在nginx存储库的情况下,版本特定的标签(不包括像-alpine
这样的变体(总是只包含数字和点。因为这是该图像在其标签中进行版本控制的特定策略,所以我可以获得这样的列表,并按版本进行排序:
reg tags nginx | grep '^[0-9,.]*$' | sort -V
我必须确定一些方法来将版本列表与当前版本进行比较,这在这个堆栈溢出问题中已经涵盖:如何在Bash中比较两个点分隔版本格式的字符串?
当然,这只是一个基于docker官方图像的图像标记策略的例子,该策略专门标记这种特定模式下的软件版本。其他图像作者可能有自己的模式,您需要为其实现逻辑。