如何使用库中的最新图像

我不知道我做错了什么,但我只是不能让 docker-compose up使用我们的注册表中的最新映像,除非首先从系统中完全删除旧的容器。看起来构图正在使用之前启动的图像,尽管 docker-compose pull 已经获取了一个较新的图像。

我查看了 如何得到码头组合始终重新创建容器从新的图像?,它似乎与我的问题相似,但是没有一个提供的解决方案适合我,因为我正在寻找一个可以在生产服务器上使用的解决方案,在那里我不想在重新启动它们之前删除所有容器(可能的数据丢失?).我想合成只是为了检测新版本的更改图像,拉他们,然后重新启动与这些新图像的服务。

我为此创建了一个简单的测试项目,其中唯一的目标是在每个新版本上增加一个 nr 版本。如果我浏览到创建的 nginx 服务器,就会显示 nr 版本(这在本地正常工作)。

Docker 版本: 1.11.2 Docker-compose 版本: 1.7.1 OS: 使用 docker-toolbox 在 CentOS 7和 OS X 10.10上进行了测试

我的码头作品:

version: '2'
services:
application:
image: ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
volumes:
- /var/www/html
tty: true


nginx:
build: nginx
ports:
- "80:80"
volumes_from:
- application
volumes:
- ./logs/nginx/:/var/log/nginx
php:
container_name: buildchaintest_php_1
build: php-fpm
expose:
- "9000"
volumes_from:
- application
volumes:
- ./logs/php-fpm/:/var/www/logs

在我们的 Jenkins 服务器上,我运行以下命令来构建和标记图像

cd $WORKSPACE && PROJECT_VERSION=$(cat VERSION)-dev
/usr/local/bin/docker-compose rm -f
/usr/local/bin/docker-compose build
docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest ourprivate.docker.reg:5000/ourcompany/buildchaintest:$PROJECT_VERSION
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest

这似乎正在做它应该做的事情,因为每次构建完成并且版本 nr 被改变时,我都会在我们的存储库中获得一个新的 version 标记。

如果我现在逃跑

docker-compose pull && docker-compose -f docker-compose.yml up -d

在我电脑上的一个文件夹,其中的内容只是码头-组成。Yml 和构建 nginx 和 php 服务所必需的 Dockerfiles,我得到的输出不是注册表中标记的最新版本号,也不是 docker-compose 中显示的最新版本号。Yml (0.1.8) ,但是之前的版本是0.1.7。然而 pull 命令的输出将表明获取了新版本的图像:

Pulling application (ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest)...
latest: Pulling from ourcompany/buildchaintest
Digest: sha256:8f7a06203005ff932799fe89e7756cd21719cccb9099b7898af2399414bfe62a
Status: Downloaded newer image for docker.locotech.fi:5000/locotech/buildchaintest:0.1.8-dev

除非我逃跑

docker-compose stop && docker-compose rm -f

然后运行 docker-compose up命令,我得到的新版本显示在屏幕上的预期。

这是码头作业的预期行为吗?也就是说,在再次运行 up之前,我是否应该总是执行 docker-compose rm -f,即使是在生产服务器上?还是我做了什么违背常理的事所以才没用?

我们的目标是让我们的构建过程构建和创建标记版本的图像需要在一个 docker-撰写。Yml,将它们推送到我们的私有注册中心,然后“ release to production-step”就可以简单地复制 docker-compest。Yml 发送到生产服务器,并为要在生产中启动的新映像运行 docker-compose pull && docker-compose -f docker-compose.yml up -d。如果有人有这方面的建议,或者可以指出这种设置的最佳实践教程,也会非常感激。

222911 次浏览

为了结束这个问题,看起来有效的方法实际上是运行

docker-compose stop
docker-compose rm -f
docker-compose -f docker-compose.yml up -d

即在再次运行 up之前移除容器。

在这样做时需要记住的是,如果只运行 rm -f,数据卷容器也会被删除。为了防止我显式地指定要删除的每个容器:

docker-compose rm -f application nginx php

正如我在问题中所说,我不知道这是否是正确的过程。但是这似乎适用于我们的用例,所以在我们找到更好的解决方案之前,我们将使用这个解决方案。

为了确保使用的是来自注册表的 :latest标记的最新版本(例如 docker hub) ,还需要再次提取最新的标记。如果它改变了,差异将被下载和启动时,你的 docker-compose up再次。

所以我们应该这么做:

docker-compose stop
docker-compose rm -f
docker-compose pull
docker-compose up -d

我把这个粘到一个图像,我运行启动码头组合,并确保图像保持最新的: https://hub.docker.com/r/stephanlindauer/docker-compose-updater/

我在我们的7-8码头生产系统中见过这种情况。 另一个在生产中对我有效的解决方案是运行

docker-compose down
docker-compose up -d

这样可以删除容器,并且似乎可以从最新的图像中创建新的容器。

这还不能解决我的梦想,即每个容器都向下 + 向上修改(连续修改,减少停机时间) ,但它可以强制“向上”更新容器。

向上命令的 docker-compose 文档清楚地表明,如果映像自上次“ up”执行后发生更改,它将更新容器:

如果存在服务的现有容器,并且服务的配置或映像在容器创建之后发生了更改,则 码头工人,冷静点通过停止并重新创建容器(保留挂载的卷)来获取更改。

因此,通过使用“ stop”后跟“ pull”,然后“ up”,应该可以避免正在运行的容器丢失容量的问题,当然,对于图像已经更新的容器除外。

我目前正在试验这个过程,并将包括我的结果在这个评论不久。

使用 码头构造,拉获取最新的图像

我使用下面的命令,它实际上是三分之一

docker-compose down && docker-compose build --pull && docker-compose up -d

这个命令将停止服务,提取最新的映像,然后启动服务。

选项 down解决此问题

我运行我的作文文件:

docker-compose -f docker/docker-compose.yml up -d

然后我删除所有与 down --rmi all

docker-compose -f docker/docker-compose.yml down --rmi all

Stops containers and removes containers, networks, volumes, and images
created by `up`.


By default, the only things removed are:


- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used


Networks and volumes defined as `external` are never removed.


Usage: down [options]


Options:
--rmi type          Remove images. Type must be one of:
'all': Remove all images used by any service.
'local': Remove only images that don't have a custom tag
set by the `image` field.
-v, --volumes       Remove named volumes declared in the `volumes` section
of the Compose file and anonymous volumes
attached to containers.
--remove-orphans    Remove containers for services not defined in the
Compose file

我使用以下命令来获得最新的图像

sudo docker-compose down -rmi all

sudo docker-compose up -d

我花了半天时间解决这个问题。原因是一定要检查音量记录在哪里。

数量: - api-data:/src/pattern

但事实是,在这个地方,我们改变了代码。但是在更新 Docker 时,代码没有改变。

因此,如果您正在检查其他人的代码,并且由于某种原因没有更新,请检查以下内容。

总的来说,这种方法是有效的:

码头,冷静下来

码头构造结构码头构造结构

码头作业

如果 docker 撰写配置在一个文件中,只需运行:

docker-compose -f appName.yml down && docker-compose -f appName.yml pull && docker-compose -f appName.yml up -d

但是

Https://docs.docker.com/compose/reference/up/ - 安静-拉没有打印进度信息

docker-compose up --quiet-pull

不工作?

不要使用
下面是规范中的内容,但是正如注释中指出的那样,还没有实现(docker-compose 1.29.2和2)。

自2020-05-07以来,docker-compose 规范还定义了服务的“ pull _ policy”属性:

version: '3.7'


services:
my-service:
image: someimage/somewhere
pull_policy: always

码头组合 规格表示:

pull_policy defines the decisions Compose implementations will make when it starts to pull images.

可能的值是(tl; dr,检查 spec 以了解更多细节) :

  • 总是,总是拉
  • 永远不要: 不要拉(如果找不到图像就断开)
  • 丢失: 如果图像未缓存,则拉取
  • 总是构建或重建

即使我的容器正在运行,并且它更新得很好,我也会使用下面的代码。

docker-compose pull
docker-compose up -d
docker-compose pull
docker-compose up -d
docker image prune -af

对我有用。

先把最新图像调出来, 更新容器, 终于清除了我们不需要的图像。

您的 docker-compose.yml使用 image引用 ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev。这意味着运行 docker-compose build不会对 ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev采取任何行动。必须有下面这样的命令在某处运行:

docker build -t ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev

这将把版本化的构建放入存储库中。但它不会更新最新的标签。这仍然指向以前的版本(例如,0.1.7-dev)。

然后,你对 Jenkins 运行其他命令:

cd $WORKSPACE && PROJECT_VERSION=$(cat VERSION)-dev
/usr/local/bin/docker-compose rm -f
/usr/local/bin/docker-compose build
docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest ourprivate.docker.reg:5000/ourcompany/buildchaintest:$PROJECT_VERSION
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest

作为 docker-compose build的一部分,您正在服务器上有效地运行 docker pull ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev。但是,这并没有说明标记 ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest(在命令 docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest ourprivate.docker.reg:5000/ourcompany/buildchaintest:$PROJECT_VERSION中引用)是如何到达服务器的。如果 latest标记事先没有被其他东西定义,那么 docker tag命令将会给出这个错误: No such image: ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest。因此,在运行显示的命令之前,Jenkins 服务器必须运行以下命令:

docker pull ourprivate.docker.reg:5000/ourcompany/buildchaintest

这个命令会导致它将当时在存储库中设置为 latest的任何内容拉出。因为在运行上面的 docker pull命令之前,您没有提供任何证据证明您曾经将新构建的 buildchaintest:0.1.8-dev作为 buildchaintest:latest进行推送,所以我们必须假设这就是旧版本的来源。因此,tag 命令可以有效地完成以下工作:

docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest:latest ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev

如果 latest指向 0.1.7-dev的同一个东西,那么它就等于在做:

docker tag ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.7-dev ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev
docker push ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev

然后,当您运行 docker-compose pull && docker-compose up -d时,它当然会提取在存储库中设置为 ourprivate.docker.reg:5000/ourcompany/buildchaintest:0.1.8-dev的内容,这应该是旧版本,因为您将0.1.7-dev 标记为0.1.8-dev。

笔记

您似乎假设 docker-compose build做了一些与构建 buildchaintest相关的事情。然而,事实并非如此。你在你的 docker-compose.yml中设置了 image但没有设置 build。这意味着 docker-compose build没有构建 buildchaintest的 docker 映像ーー它将直接拉取并运行 docker 映像标记。由于 docker-compose build并不尝试构建 buildchaintest,因此在调用该映像之后尝试标记或推送它是没有意义的。

而且,如果你同时指定 buildimagedocker-compose push就会存在并且完成所有的标记和推送操作(因为 image用来通知 docker-compose它应该为构建的东西设置一个标记)。这将推送正确的标记(并且对于 docker-compose.yml文件将正确地为 no-op)。

你的 docker-compose里面有 build而没有 image。无论你在哪里运行 docker-compose up,这些东西都会被构建起来。因此,在构建服务器上运行 docker-compose build毫无意义(除非您添加 image来设置标记并保存那些构建的映像并使用 docker-compose push)(除了测试构建运行到完成之外)。您不会节省任何时间,也不会减少服务器在部署期间执行的工作。您正在增加构建的次数和系统中节点之间的可变性(因为在构建服务器上构建的任何内容都将不同于在服务器上运行的任何内容(例如,文件时间戳、更新的图像标记)。

不幸的是,你的问题不可信。您使用命令时,就好像它们具有不同于应该具有的行为一样。我很抱歉攻击你的问题,但我已经学到了一些令人惊讶的事情(对我来说)关于如何 docker tagdocker-compose的工作结果。谢谢!

博士

确保您真正地标记并将正确的映像推送到存储库中!

拉新图片来源: docker-compose pull

重建码头容器与新的图片: docker-compose up --force-recreate --build -d

删除未使用的图片: docker image prune -f

有点晚了,但至少是:
Docker 版本20.10.17
Docker Compose 版本2.9.0

你可以使用 docker-compose up --pull=always -d

来自 CLI 的帮助:

--pull string Pull image before running ("always"|"missing"|"never") (default "missing")

您也可以在不使用缓存的情况下使用 docker-compose 构建:

$ docker-compose build --no-cache && docker-compose up -d