如何获取docker-compose以使用存储库中的最新映像


81

我不知道我在做什么错,但是我docker-compose up必须先从系统中完全删除旧容器,然后才能从注册表中使用最新映像。即使docker-compose pull获取了新的映像,compose似乎仍在使用先前启动的映像。

我研究了如何使docker-compose始终从新映像重新创建容器?这似乎与我的问题相似,但是那里提供的解决方案都不适合我,因为我正在寻找可以在生产服务器上使用的解决方案,因此我不想在启动它们之前先删除所有容器再次(可能丢失数据?)。我只想检测更改图像的新版本,将它们拉出,然后使用这些新图像重新启动服务。

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

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

我的docker-compose.yml:

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发生变化时,我都会在存储库中获得一个新的版本标签。

如果我现在跑步

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

在我计算机上的文件夹中,其中的内容仅是docker-compose.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命令以获取新版本以按预期方式显示在屏幕上。

这是docker-compose的预期行为吗?也就是说,即使在生产服务器上,我也应该始终docker-compose rm -fup再次运行之前执行一次吗?还是我在对这里的谷物做些什么,这就是为什么它不起作用的原因?

目标是让我们的构建过程构建并创建docker-compose.yml中所需图像的标记版本,将其推送到我们的私有注册表中,然后进行“发布到生产步骤”以简单地复制docker-compose。 yml到生产服务器,并运行,docker-compose pull && docker-compose -f docker-compose.yml up -d以使新映像开始在生产中使用。如果有人对此有建议,或者可以为这种设置指向最佳实践教程,也将不胜感激。


1
docker-compose up -d --force-recreate没有工作吗?
BMitch

为避免在删除/重新创建容器时发生数据丢失的风险,请使用主机或命名卷。看来您已经在使用其他容器的主机卷了。首次使用时,空的命名卷将使用图像卷的内容进行初始化。
BMitch

--force-recreated无法正常工作,不:(我正在使用卷进行数据存储,因此数据丢失部分可能并不重要。但是我仍然对必须在之前进行docker-compose rm感到困惑重新启动容器应不起来,命令,尤其是与力重新创建,采取使用,而不是感觉错了,我不得不强制在生产服务器上移除notificing新形象的照顾。?
延Wegar

如果--force-recreate不是重新创建容器,则可能需要在上提交错误报告docker-compose。请记住,使用新映像将重新创建容器,这将删除它。而且,如果您在此过程中没有删除任何特定于容器的卷,那么您将获得一个相当长的悬挂数据列表,这些数据将不再在其中使用docker volume ls -f dangling=true。因此,您的解决方案是docker-compose应该为您做的上半部分。
BMitch

好的谢谢!我将不得不花更多的时间来确保我理解该过程(关于Docker还是一个新手),但是看起来像docker-compose rm -f才是我要做的。
詹斯·韦加尔

Answers:


65

为了确保您正在使用:latest注册表的最新版本(例如docker hub),还需要再次提取最新标签。如果已更改,则将docker-compose up再次下载差异文件并启动。

所以这是要走的路:

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

我将其粘贴到我运行的图像中以启动docker-compose并确保图像保持最新:https : //hub.docker.com/r/stephanlindauer/docker-compose-updater/


27
docker-compose pull && docker-compose up -d足够。它会自动检查正在运行的容器是否过时,如果是,请使用最新的图像重新创建它们
Mindaugas Varkalys,

@MindaugasVarkalys,先生,您的评论应该已经被接受。像魅力一样工作。
Yuriy Pozniak

36

要获取最新图像,请使用docker-compose build --pull

我使用下面的命令实际上是三合一

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

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


也许您应该docker-compose pull使用image:而不是build:in添加更新服务的映像,docker-compose.yml否则docker-compose build --pull会这样做吗?
oceanBT

nginx uses an image, skipping在使用docker-compose build --pull时得到了因此没有更新图像。
安东尼奥·阿劳霍

24

为了解决这个问题,似乎有效的方法正在运行

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

就像我在问题中说的那样,我不知道这是否是正确的过程。但这似乎适用于我们的用例,因此在找到更好的解决方案之前,我们将继续使用该解决方案。


如果要回滚到以前的容器版本怎么办?冲洗,重复吗?
'88八月

1
还没有尝试过,但是,我承担了很多。由于容器版本应在docker-compose.yml中定义(例如myimage:2.0.1),如果要回滚,则将docker-compose.yml更新为要回滚的版本(例如2.0) .0),然后再次执行相同的冲洗重复过程。
詹斯·韦加尔

如果我想回滚,我只是还原提交,让docker hub构建,然后等待更新程序将其接收。可能不是最复杂的系统,但它适用于我的业余项目。
stephanlindauer

3

我已经在7-8个docker生产系统中看到了这种情况。在生产中对我有用的另一个解决方案是运行

docker-compose down
docker-compose up -d

这将删除容器,并似乎使“容器”根据最新图像创建新容器。

这还没有解决我的梦想,即每个更改后的容器的向下+向上运行(通常,减少停机时间),但是可以强制“向上”来更新容器。


docker-compose downafaik还将删除链接到正在运行的容器的所有数据卷容器。因此,如果数据卷仅包含可以从正在运行的容器中重新创建的内容,则没问题。但是,如果卷中包含要保留的数据,则应小心。
Jens Wegar '16

down默认情况下删除当前文档:容器,网络和默认网络。Doc说:“永远不会删除定义为外部的网络和卷”。我可以使用命名卷(我想对于命名网络也是如此)。
arminfro

3

选项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

2

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

卷:-api-data:/ src / patterns

但事实是,在这里是我们更改的代码。但是在更新docker时,代码没有更改。

因此,如果您正在检查其他人的代码,并且由于某种原因未在更新,请选中此选项。

因此,通常这种方法有效:

码头工人组成

docker-compose构建

docker-compose up -d


0

'up'命令的docker-compose文档明确指出,自上次执行'up'后,如果更改了映像,它将更新容器:

如果已有用于服务的容器,并且在创建容器后更改了服务的配置或映像,则docker-compose up会通过停止并重新创建容器(保留装入的卷)获取更改。

因此,通过使用“停止”,然后是“拉动”,然后是“向上”,因此应该避免正在运行的容器丢失体积的问题,当然,对于已更新映像的容器除外。

我目前正在尝试此过程,并将在不久的评论中包含我的结果。


0

如果docker compose配置位于文件中,则只需运行:

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


-3

我正在使用以下命令来获取最新图像

sudo docker-compose down -rmi all

sudo docker-compose up -d

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.