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

Posted

技术标签:

【中文标题】如何让 docker-compose 始终从新图像重新创建容器?【英文标题】:How to get docker-compose to always re-create containers from fresh images? 【发布时间】:2015-12-13 06:42:03 【问题描述】:

我的 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 的当前行为似乎与这种方法完全冲突.. 还是我在这里错过了一些要点?

【问题讨论】:

【参考方案1】:

对我来说,工作命令如下: docker-compose down - 删除容器 docker-compose build - 使用缓存重建图像。如果代码发生更改,则仅重新编译应用程序 docker-compose up - 创建硬币容器并启动它们

使用docker-compose up --build 我看到没有使用缓存

【讨论】:

【参考方案2】:

对我有用的唯一解决方案是这个命令:

docker-compose build --no-cache

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

【讨论】:

另外,在Windows 10下可以帮助将设置中的DNS服务器从自动设置为固定或从固定设置为自动。 在使用 docker-comopse 版本 2 构建 OS X 时为我工作。 在 OS X docker 上工作。 这在 Mac OS 中也适用于我。接受的答案没有。【参考方案3】:

另外,如果 compose 有多个服务,而我们只想强制构建其中之一:

docker-compose build --no-cache <service>

【讨论】:

【参考方案4】:

我通过这个在 ubuntu AWS 中申请了 3.5gb 空间。

清洁码头

docker stop $(docker ps -qa) && docker system prune -af --volumes

重新构建

码头工人构建。

docker-compose 构建

码头工人组成

【讨论】:

【参考方案5】:
docker-compose up --build

docker-compose build --no-cache

【讨论】:

如果可能,请努力提供额外的解释,而不仅仅是代码。此类答案往往更有用,因为它们可以帮助社区成员,尤其是新开发人员更好地理解解决方案的推理,并有助于避免需要解决后续问题。 其实这个答案对我来说是最干净最清晰的。 我的理解是 --build 命令重建,但使用缓存的部分,因此不能完全“重新创建”容器。只有第二个做我想要的。 在 centos 7 上无法在 docker 上工作,必须 rm -rf /var/lib/docker 两个命令完全不同! docker-compose up --build 使用缓存图像(如果存在)。 docker-compose build --no-cache 从不使用缓存。【参考方案6】:

目前官方documentation 有一个捷径可以停止和删除由 up 创建的容器、网络、卷和映像,如果它们已经停止或部分删除等等,那么它也可以解决问题:

docker-compose down

如果您对图像或 Dockerfile 有新的更改,请使用:

docker-compose build --no-cache

最后:docker-compose up

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

【讨论】:

docker-compose build --no-cache 仅在 Dockerfile 发生更改时才需要。 确实,维克多。谢谢!我认为在更新容器启动时执行的模块/应用程序之后也有必要。对于这些情况,在运行docker-compose up 之前,需要使用docker-compose build 重建服务。【参考方案7】:

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

这是我用的:

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

重新创建容器的原因是为了保留任何可能使用的数据量(而且它也恰好使up 更快)。

如果您正在执行 CI,您不希望这样做,因此只需删除所有内容即可满足您的需要。

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

【讨论】:

是的,实际上这也是我在 CI 中所做的。不知道为什么我没有提到... @dnephin docker-compose run -d 不存在?你想说docker-compose up -d不? 如果您在docker-compose rm -f 之前运行docker-compose pull,您可以节省更多时间 最后的-d标志是做什么的? "-d 分离模式:在后台运行容器,"【参考方案8】:
$docker-compose build

如果有新的东西,它将被重建。

【讨论】:

【参考方案9】:

您可以将--force-recreate 传递给docker compose up,这应该使用新鲜的容器。

我认为重复使用容器的原因是为了在开发过程中保留任何更改。请注意,Compose 对卷执行类似操作,这也将在容器重新创建之间持续存在(重新创建的容器将附加到其前身的卷)。这会很有帮助,例如,如果您有一个 Redis 容器用作缓存,并且您不希望每次进行小的更改时都丢失缓存。在其他时候,这只是令人困惑。

我认为您无法从 Compose 文件中强制执行此操作。

可以说它确实与不可变的基础架构原则相冲突。反驳的观点可能是您(还)没有在生产中使用 Compose。另外,我不确定我是否同意不可变基础设施是 Docker 的基本理念,尽管它肯定是一个很好的用例/卖点。

【讨论】:

感谢您的回答。我认为在配置级别强制它会非常有用,例如。为数据库容器强制执行它并默认为应用程序容器禁用重新创建.. --force-recreate 对我不起作用...即使有较新的版本也不会提取图像... @lisak 我从来没有说过它会拉取新图像。它没有。它只是使用本地可用的任何图像启动新容器。您需要手动运行 docker pull。

以上是关于如何让 docker-compose 始终从新图像重新创建容器?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cloud Function with Flutter 从新图像中获取 URL?

使用 docker-compose 从私有仓库拉取镜像

如何定义使用 docker-compose 构建的图像的名称

如何使用 docker-compose 下载私有图像(本地)

运行docker-compose run时始终包含参数

如何使用 docker-compose 标记 docker 镜像