如何使docker-compose始终从新映像重新创建容器?


198

我的Docker映像构建在Jenkins CI服务器上,并被推送到我们的私有Docker Registry。我的目标是使用docker-compose配置环境,该环境始终会启动映像的原始构建状态。

我目前在不同的机器上使用docker-compose 1.3.2以及1.4.0,但是我们之前也使用了旧版本。

我总是使用docker-compose pull && docker-compose up -d命令从注册表中获取新图像并启动它们。我相信我的首选行为在某个时间点之前都可以按预期工作,但是从那时起,它docker-compose up开始重新运行以前停止的容器,而不是每次都启动原始构建的映像。

有没有办法摆脱这种行为?这样可以成为在docker-compose.yml配置文件中关联的一种方式,以不依赖于每次调用时“不要忘记”命令行上的某些内容吗?

ps。除了找到实现目标的方法外,我还想进一步了解这种行为的背景。我认为Docker的基本思想是构建一个不变的基础架构。docker-compose的当前行为似乎与这种方法完全冲突..还是我在这里错过了几点?

Answers:


232

docker-compose up --force-recreate是一个选择,但是如果您将其用于CI,我将以构建开始,docker-compose rm -f以停止并删除容器和卷(然后通过上拉并跟随它)。

这是我用的:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

重新创建容器的原因是保留所有可能使用的数据量(同时它也会使up速度更快)。

如果您正在执行CI,则不需要这样做,因此只需删除所有内容即可获得所需的信息。

更新:使用1.7 up --build中添加的功能docker-compose


1
是的,实际上这也是我在CI中所做的。不知道为什么我没有提到...
Adrian Mouat

@dnephin docker-compose run -d不存在吗?你想说docker-compose up -d不?
纪尧姆·文森特

2
如果您在跑步docker-compose pull之前docker-compose rm -f可以节省更多时间
stephanlindauer

2
最后的-d标志是什么?
戴维·戴维斯

3
“ -d分离模式:在后台运行容器,”
dnephin

135

唯一对我有用的解决方案是以下命令:

docker-compose build --no-cache

这将自动从存储库中提取新图像,并且不会使用预先使用任何参数预先构建的缓存版本。


1
此外,在Windows 10下,它可以帮助将DNS服务器设置为“自动”到“固定”或从“固定”到“自动”。
qräbnö

2
在docker-comopse版本2的OS X构建上为我工作。–
RoboBear

1
在OS X docker上工作。
HelloWorld

55

在当前的官方文档中,有一条捷径可以停止并删除由up创建的容器,网络,卷和映像,如果它们已被停止或已部分删除等,那么它也可以解决问题:

docker-compose down

然后,如果您对映像或Dockerfile进行了新更改,请使用:

docker-compose build --no-cache

最后:docker-compose up

在一个命令中: docker-compose down && docker-compose build --no-cache && docker-compose up


2
docker-compose build --no-cache仅在Dockerfile上有更改时才需要。
Victor Timoftii,

的确,维克多。谢谢!我认为在更新容器启动时执行的模块/应用程序之后也有必要。对于这些情况,在运行之前docker-compose up,必须使用来重建服务docker-compose build
ivanleoncz

18

您可以传递--force-recreatedocker compose up,该应使用新鲜的容器。

我认为重用容器的原因是为了保留开发过程中的所有更改。请注意,Compose与卷具有相似的功能,在容器重新创建之间也将保持不变(重新创建的容器将附加到其前身的卷上)。例如,如果您将Redis容器用作缓存,并且不想每次更改都丢失缓存,这将很有用。在其他时候,这只是令人困惑。

我不认为有任何方法可以从Compose文件中强制执行此操作。

可以说,它确实与不变的基础架构原则发生了冲突。相反的论点可能是您尚未在生产中使用Compose(尚未)。另外,我不确定我是否同意不变的基础是Docker的基本思想,尽管它肯定是一个很好的用例/销售点。


感谢你的回答。我认为在配置级别强制使用它确实很有用,例如。去执行一个数据库容器和禁用娱乐默认为应用容器..
克里斯托夫乔沙

8
--force-recreate不适用于我...即使在那里有较新的版本也无法拉出图像...
lisak

1
@lisak我从没说过要拉新图像。没有。它只是使用本地可用的任何映像启动新容器。您需要手动运行docker pull。
阿德里安·穆阿特

2
docker-compose up --build

要么

docker-compose build --no-cache

1
如果可能,请尝试提供其他说明,而不只是提供代码。这样的答案往往会更有用,因为它们可以帮助社区成员,尤其是新开发人员更好地了解解决方案的原因,并可以帮助避免需要解决后续问题。
拉詹

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.