Docker-compose 命名挂载卷

103
为了跟踪docker-compose使用的卷,我想使用命名卷。这对于像

普通

卷这样的东西非常有效。
version: 2
services: 
  example-app:
    volume:
      -named_vol:/dir/in/container/volume
volumes:
  named_vol:

但是我不知道如何在挂载本地主机时使它工作。我正在寻找类似于:

version: 2
services: 
  example-app:
    volume:
      -named_homedir:/dir/in/container/volume
volumes:
  named_homedir: /c/Users/
或者
version: 2
services: 
  example-app:
    volume:
      -/c/Users/:/home/dir/in/container/ --name named_homedir

这种情况有可能发生吗,还是我只能使用匿名卷?


1
你找到答案了吗?我遇到了类似的问题,但也许我不太明白卷应该是什么:https://dev59.com/VlgR5IYBdhLWcg3wbs2X#41334607 - Richard
1
我没有真正地在Compose内部使用,仍然使用“服务”以及一个空容器和卷(然后使用那个容器的volumes_from)。 - pvgoddijn
5个回答

69

正如您可以在此GitHub问题中阅读到的那样,挂载命名卷现在是一件事情……自1.11或1.12以来。驱动程序特定选项已记录。以下是GitHub线程的一些注释:

docker volume create --opt type=none --opt device=<host path> --opt o=bind

如果主机路径不存在,则不会创建。
选项直接传递给mount系统调用。我们可以为某些“类型”添加特殊情况,因为它们使用起来很麻烦...就像上面提到的nfs示例一样。
- @cpuguy83
针对您具体问题的解答,关于如何在compose中使用它,您需要在volumes部分下书写。
my-named-volume:
     driver_opts:
           type: none
           device: /home/full/path #NOTE needs full path (~ doesn't work)
           o: bind

这是因为正如cpuguy83在链接的github线程中所写的那样,选项(在幕后)直接传递给mount命令。 < p > 编辑: 如评论所述...

  • …@villasv, you can use ${PWD} for relative paths.

  • …@mikeyjk, you might need to delete preexisting volumes:

     docker volume rm $(docker volume ls -q)
     OR
     docker volume prune
    
  • …@Camron Hudson, in case you have no such file or directory errors showing up, you might want to read this SO question/ answer as Docker does not follow symlinks and there might be permission issues with your local file system.


4
这个问题中的compose文件如何利用这一点? - Dave L.
1
创建与上面示例中相同的卷,然后在docker-compose文件https://docs.docker.com/compose/compose-file/#/external中将该卷设置为外部。 - eduncan
1
@david,你可以在你的composer文件中添加以下内容:(格式有点乱)my-named-volume: \n driver_opts: \n type: none \n device: /home/user/your/path/ #注意需要完整路径 \n o: bind \n - linuxbandit
1
@linuxbandit 你可以使用反引号进行行内代码格式化(请参见此文本区域右侧的_help_)。或者:只需在答案中添加[编辑]。这是受欢迎的 :) - kaiser
2
你可以使用${PWD}来避免完整路径的使用,从而使你的项目更具可移植性。 - villasv
显示剩余8条评论

20

OP似乎已经在使用完整路径,但如果像大多数人一样你对于将项目文件夹挂载到容器内感兴趣,这可能会有所帮助。

这是如何使用driver_opts的方法,就像@kaiser所说和@linuxbandit所示范的那样。不过,你可以尝试使用通常可用的环境变量$PWD来避免在docker-compose环境中为目录指定完整路径:

logs-directory:
  driver_opts:
    type: none
    device: ${PWD}/logs
    o: bind

是否可以通过命名绑定仅挂载一个文件? - Eugen Konkov

14

我一直在尝试着做(几乎)同样的事情,似乎可以用类似这样的方式来实现:

version: '2'
services: 
  example-app:
    volume:
      -named_vol:/dir/in/container/volume
      -/c/Users/:/dir/in/container/volume
volumes:
  named_vol:

对我来说似乎可行(我没有深入研究,只是测试了一下)。


8
删除这行 "- named_vol:/dir/in/container/volume" 不会影响您的配置。它仍然可以正常工作。您正在创建一个名为 "named_vol" 的命名卷,然后基本上将其挂载,然后在其位置上挂载其他内容,因此现在 "named_vol" 不再挂载在容器上。要确认这一点,您可以检查容器并检查名为 "named_vol" 的卷是否已挂载到容器上。 - kapad
1
正如问题所述,@pvgoddijn想要一个命名的卷(因此删除该行肯定会影响它),但也将主机卷挂载到其中。 因此,基本上它有点破解,但它所做的是将卷挂载到容器文件夹,然后将主机文件夹挂载到同一位置。 这样,您可以使用卷的名称,并直接从主机编辑容器文件。 虽然对我来说更多是一个实验,我并不真正推荐这样做。如果您被迫这样做,我认为您需要重新设计您的基础架构。 - rmNyro
据我所知,这样做不会带来使用命名卷的最大好处之一:当挂载空目录时,容器数据被复制到主机。因此,正如@kapad所说,你可能只需使用“绑定挂载”。除非还有其他我不知道的好处。 - mikey
胡,如果我错了,请纠正我,但是命名卷没有被复制到磁盘上,“名称”就像一个“ID”。因此,您可以通过其ID从另一个容器中“调用”卷。 数据在第二行“绑定”(复制)到主机上。 但是再说一遍,我没有深入研究它,就像我当时为我的工作玩docker一样,并认为这将是对这个问题的一个好答案(也许问题是错误的^^),这就是全部。 - rmNyro
命名卷本质上驻留在主机磁盘上。当您挂载一个空的命名卷时,相应容器内容会被复制到主机上(请参阅:https://docs.docker.com/storage/volumes)。第一行创建了一个命名卷。第二行创建了一个绑定挂载点,它将始终用主机内容(为空)覆盖容器文件。这个解决方案仍然需要您手动将容器内容复制到主机上,以便从 /c/Users/ 访问。我认为这是一个很好的问题,@kaiser 的答案最好(基于 Github 上 cpuguy83 的解决方案)。 - mikey
很高兴他当时没有那个选项。关于命名卷和主机挂载卷,你是正确的,两者都在主机磁盘上。只有匿名卷据我所知才会留在内存中。话虽如此,我的答案有些“hacky”,并不能阻止新的更好的答案出现... :) - rmNyro

7
我最近也在寻找同样的答案,并偶然发现了这个插件:https://github.com/CWSpear/local-persist,看起来它可以实现主题提出的需求。我还没有亲自尝试过,但我认为它可能对某些人有用。

1
看起来很有趣,但为了方便部署,我想我可能会等待类似于这样的东西最终出现在Docker(-compose)本身中。 - pvgoddijn
你所说的类比于说你不会从应用商店下载应用程序,而是希望有朝一日将其内置到操作系统中。看起来不太可能发生:_@CWSpear我们不会在内置驱动程序中支持此功能。 您可以构建插件来处理此问题._ https://github.com/docker/docker/issues/19990 - Peeter Kokk
2
有关在 docker-compose.yml 中使用 local-persist 的示例,请参见此处:https://github.com/CWSpear/local-persist/blob/master/docker-compose.example.yml - Peeter Kokk

6

主机卷与命名卷或匿名卷不同。它们的“名称”是主机上的路径。

无法使用 volumes 部分来处理主机卷。


1
这里的“主机卷”可能是指绑定挂载。命名卷“名称”不是主机上的路径。可以按照@cpuguy83的解决方案为命名卷指定主机路径:https://github.com/moby/moby/issues/19990#issuecomment-248955005。 - mikey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接