Compose: 如何在不重用以前的卷的情况下`docker-compose up --force-recreate`

创建于 2015-10-02  ·  23评论  ·  资料来源: docker/compose

使用docker-compose 1.4.2和docker 1.8.2
您可以在下面看到第一个卷e583c6a8 ... 5a93788a0被重用了

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

 $ sudo docker-compose up -d --force-recreate
   Recreating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data:/home/transmission/.config/transmission-daemon:rw",
   "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data:/home/transmission/Downloads:rw"
   "Source": "/mnt/docker/volumes/e583c6a87437a5b4b1af50ee2693bd3e5dce574ec72d60dce1311215a93788a0/_data",
   "Source": "/mnt/docker/volumes/cefce79850d7162f4f99541559c2dfc7315c83db717a7a5953118bd3c4b273e0/_data",

我被迫先创建stop然后再创建rm

 $ sudo docker-compose stop 
   Stopping remotetransmission_torrent_1... done

 $ sudo docker-compose rm
   Going to remove remotetransmission_torrent_1
   Are you sure? [yN] y
   Removing remotetransmission_torrent_1... done

 $ sudo docker-compose up -d --force-recreate
   Creating remotetransmission_torrent_1...

 $ docker inspect remotetransmission_torrent_1 | grep volumes
   "Source": "/mnt/docker/volumes/c5bb9a8f7b68c762c42e9c0ee92afbca3aa0d7ff9d09aaf45fd260f6fc663ec9/_data",
   "Source": "/mnt/docker/volumes/9dcce8440bafc8893e07352111d1aefb625c36df10da6dc4eaa593220266ea31/_data",

_
有没有比stop/rm方法更好的方法?

areup kindocs kinquestion

最有用的评论

该策略似乎违反了docker最佳做法,并让我们头疼不已,对为什么重新创建容器处于泄漏状态感到疑惑。 当我告诉docker重新创建时,这并不意味着“在容器运行过程中保留一些数据,而是重新启动容器中的进程”。 这意味着铺路并重新开始。 如果要保存卷,则可以显式装载卷。 我_never_希望任何类型的自动挂载卷在容器运行期间都将持续存在。

所有23条评论

stop/rm是正确的方法。 卷中的数据可能很重要,因此我们希望很难意外删除它。

我们可能会对此进行更好的记录。

该策略似乎违反了docker最佳做法,并让我们头疼不已,对为什么重新创建容器处于泄漏状态感到疑惑。 当我告诉docker重新创建时,这并不意味着“在容器运行过程中保留一些数据,而是重新启动容器中的进程”。 这意味着铺路并重新开始。 如果要保存卷,则可以显式装载卷。 我_never_希望任何类型的自动挂载卷在容器运行期间都将持续存在。

跨运行持久保留数据确实是使用卷的唯一原因。 如果您不想保留数据,为什么要将其放入一个卷中?

我没有设置音量。 我的docker-compose.yml没有任何卷设置,我也没有传递任何数据到docker-compose.yml来附加任何卷。

命令:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

version: '2'
services:
  foo:
    build:
      context: .
      dockerfile: src/integration/foo/Dockerfile
    ports:
      - "3306:3306"
      - "33060:33060"

Dockerfile:

FROM mysql:5.7

COPY schema/foo/migration.sql /data/db_schema.sql
COPY src/integration/foo/create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD true

EXPOSE 3306 33060

create_test_db.sh:

#!/bin/bash
set -e
mysql --no-defaults -u root -e "drop database if exists agent_state; create database foo"
mysql --no-defaults -u root foo < "/data/db_schema.sql"

如果执行上述操作,则向DB中写入一些内容,然后写入SIG_INT,然后再次运行命令。

这是MySQL映像的问题。 它在底部创建一个体积
图片。 您可以使用其他MySQL来解决此问题
映像,或者可能通过强制它为数据使用其他路径。

2016年10月19日下午6:36,“ Micah Zoltu” [email protected]写道:

我没有设置音量。 我的docker-compose.yml没有任何内容
卷设置,我没有将任何内容传递给docker-compose.yml
附加任何卷。

命令:

docker-compose up --force-recreate --abort-on-container-exit --build foo

docker-compose.yml:

版本:“ 2”
服务:
foo:
建立:
内容:。
dockerfile:src / integration / foo / Dockerfile
端口:
-“ 3306:3306”
-“ 33060:33060”

Dockerfile:

来自mysql:5.7

COPY schema / foo / migration.sql /data/db_schema.sql
复制src / integration / foo / create_test_db.sh /docker-entrypoint-initdb.d/create_test_db.sh
ENV MYSQL_ALLOW_EMPTY_PASSWORD是

展览3306 33060

create_test_db.sh:

!/ bin / bash

设置-e
mysql --no-defaults -u root -e“删除数据库(如果存在agent_state;创建数据库foo)”
mysql --no-defaults -u root foo <“ /data/db_schema.sql”

如果执行上述操作,则将一些内容写入数据库,然后是SIG_INT,然后运行
再次命令我放置在数据库中的数据将在整个运行过程中保持不变。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/2127#issuecomment -254986952,
或使线程静音
https://github.com/notifications/unsubscribe-auth/AAa_RG_pJj0i-OSCfcBlG__8ToFDtGKMks5q1sWlgaJpZM4GHruC

嗯,这违反了我对docker容器的理解。 没有在主机上提供路径的情况下如何安装卷? 我的理解是,除非您明确安装卷,否则Docker容器是临时的?

卷不需要主机路径。 卷共有三种:

  • 主机绑定挂载( -v /host:/container
  • 命名卷( -v name:/container ,使用docker volume create
  • 匿名卷( -v /containerVOLUME内的Dockerfile

mysql映像使用匿名卷。 在运行时,您可以告诉容器对容器中的该路径使用不同的卷,但是如果不这样做,匿名卷仍然存在。

匿名卷不是很大。 它们是这三个中最古老的,并且它们的大部分行为都是旧版,仅出于向后兼容的原因而保留。

至少有一些命令行选项,例如“ --recreate-volumes”会很好...

好的,伙计们,这是需要考虑的情况:

1)我想将我的Rails公共目录重新安装到nginx容器中,以便nginx可以直接提供一些静态内容。
2)我将一个“匿名”(未安装在主机上,未命名)卷分配给/ usr / local / app / app / public,并通过“ volumes_from”将其共享给nginx
3)“公共”内容经常在映像构建中更改-不仅是顶级文件,而且子目录中的某些文件也很重要(这很重要)

当前,如果我重新创建容器,最终会得到旧版本的“ public”-图像中的内容将被忽略。 是的,Docker应该将丢失的文件复制到匿名卷中,但是由于各种原因,它并不总是发生(我怀疑,对子目录结构没有深入的检查)。

因此,我要么被迫执行“ stop-rm-up”序列(在生产中不太方便),要么被迫使用单独的目录作为共享卷,并在应用程序容器开始显式调用“ rsync”以填充/更新它。

如果有一种方法可以让匿名卷与父容器一起使用,那将是一个很大的改进。

不要将卷用于代码(或静态资产)。 卷是要在部署之间保留的数据,这与您在此处想要的相反。 用静态资产构建Nginx映像,或代理包含它们的Web服务器容器。

感谢您的观点! 我从这个角度还没有想到。

这似乎是(仍在发展中的)Docker体系结构的概念问题之一。 到目前为止,我们已经看到了数据卷概念的演变(例如,从“数据容器”到“命名卷”),并且可能还没有完成。

如果您查看https://docs.docker.com/engine/tutorials/dockervolumes/#/data -volumes,您会看到大多数描述的好处(绕过AUFS,共享)不一定与数据持久性有关(最初为哪些卷设计的)。

因此,毫不奇怪,包括我在内的人们都在尝试以超出其原始目的的多种方式使用卷。 例如,将短暂的或图像控制的数据从一个容器共享到另一个容器,而无需进行大量显式复制。

也许有一天我们会找出一致的标准方法。 :)到目前为止,可以使用上述一些非常简单的解决方法。 只要适当地设置了架构期望,这不是理想的,但是可以接受的。

再次感谢您的答复,说明和所做的出色工作!

我今天遇到了这个问题,感谢大家的出色解释,这无疑帮助我理解了这个问题。

对我来说,一个主要的困惑是理解dockerfile中的VOLUME标签会导致创建一致的匿名卷。 我可能在文档中错过了它,但是找不到它。

@dnephin

正如提到的@ hleb-rubanau。 解决方案是使用Rails和Nginx运行单个容器吗? (像这样:https://docs.docker.com/engine/admin/multi-service_container/?)

我应该打破最佳做法(“每个容器应该只关注一个问题
“)仅用于服务资产?:(

对于那些感兴趣的人,我得出以下结论:

1)在我的设置中,我现在总是使用绑定安装(也称为主机安装)卷。 匿名卷和命名卷具有太多特殊/不明显/有条件/不一致/隐含逻辑,因此无法考虑。 是的,很容易理解每​​种类型的生命周期和管理的细节,但是当我不关心所有这些无关紧要的差异时,我发现对体系结构的思考比较容易。 对于分布式FS,Gluster可以正常工作(从Docker角度来看,仍然可以进行绑定安装)。

2)共享卷是绑定安装的,而不是映像中存储资产的目录。 在开始时(在入口点),我正在运行本地rsync,以便将映像目录中的资产复制/ rsync到绑定安装的共享存储路径。

谢谢@ hleb-rubanau

无论如何,我不确定某些编排工具(如RancherOS)是否支持这些卷配置,或者是否适合扩展规模。 最后,使用docker部署更加困难...

我更喜欢使用匿名卷来清理孤儿。

这是我的生产Rails堆栈: https :

当我测试jenkins / jenkins映像时,这也引起了我很大的困惑,并且它不尊重我对/ usr / share / jenkins / ref中文件的更改,因为它已经复制了它们。

那是一种非常出乎意料的用户体验-docker compose为所有意图和目的创建一个“隐藏”卷。 如果您使用普通的docker run则每次都会获得一个新的卷。 在docker-compose up中什么都没有谈论的意义上,这是一个隐藏的内容,因此,除非您详细了解图像的作用,否则必须进行挖掘。

至少,我们应该打印一条消息,说“不要重新创建体积x”,这样以后其他人就不必浪费时间去想发生了什么。

@dnephin

我叫sudo rm -rf /var/lib/docker/volumes/aa_dbdatavol现在我不能再docker-compose up我的postgres docker-compose了。

得到这个错误

使用默认驱动程序创建网络“ aa_default”
创建aa_postgres_1
错误:对于postgres无法为服务postgres创建容器:没有这样的文件或目录
错误:启动项目时遇到错误。
来自守护程序的错误响应:没有这样的容器:aa_postgres_1

由于您可能有解决此问题的方法,请分享。 谢谢!

https://github.com/docker/compose/issues/2127#issuecomment -347152650

只需重新创建文件夹即可解决我的问题。
/var/lib/docker/volumes/aa_dbdatavol/_data

非常感谢@dnephin您的回答在第一时间效果很好。 墨西哥牧草。

@dnephin说:

跨运行持久保留数据确实是使用卷的唯一原因。 如果您不想保留数据,为什么要将其放入一个卷中?

在容器之间共享文件。 有没有不使用卷就可以做到这一点的更好方法?

“共享文件”是什么意思?

您是否期望一个容器将写入文件,而另一个容器将看到这些写入? 文件系统通常不是两个服务之间的良好接口,但是如果是这样,您可以通过将更新写入卷来让其中一个服务“管理”文件系统。

如果“共享”只是两个容器碰巧读取了一些相同的文件,则不需要卷。 使用COPY将文件添加到两个容器中。

我正在使用Docker version 18.06.1-ce, build e68fc7a ,可以使用以下命令来重新创建匿名卷:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

似乎最近添加了标记--renew-anon-volumes

我正在使用Docker version 18.06.1-ce, build e68fc7a ,可以使用以下命令来重新创建匿名卷:

docker-compose up -d --build --force-recreate --renew-anon-volumes db

似乎最近添加了标记--renew-anon-volumes

感谢您使用此选项。

此页面是否有帮助?
0 / 5 - 0 等级