挂载被拒绝。路径…未从OS X共享,也未知于Docker。

170
命令docker run -v /var/folders/zz/...会产生以下错误。
docker: Error response from daemon: Mounts denied: 
The paths /var/folders/zz/... and /var/folders/zz/...
are not shared from OS X and are not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.

当我打开文件共享时,我发现 /private 已经被列出。
如果我尝试添加 /var/folder/,它会解析成 /private/var/folders,这是 /private 的子集,因此添加操作被拒绝。
总之,看起来像是 OS X 共享了 /var/folders/.. 目录作为 /private 的子目录,因此必须被 Docker 所知。任何有关解决此问题的帮助都将不胜感激。
作为一个实验,我用 /private/var/folders 替换了文件共享中的 /private,并重新启动了 Docker,但结果没有改变。
只是为了更完整的参考,这是.sh脚本,它运行这个Python脚本,然后运行Docker命令。

4
你尝试过使用-v /private/var/folders/zz/...吗? - Dan Lowe
@DanLowe:我之前没有这样做,因为代码是这样的 WORKING_DIR="$(mktemp -d)-v ${WORKING_DIR}。但是将其修改为 WORKING_DIR="/private"$(mktemp -d),似乎解决了问题。非常感谢 :) - Aayush
我会在有空的时候发布一个答案,解释为什么它有效。 - Dan Lowe
太好了,再次感谢。 - Aayush
我遇到了相同的错误信息。 我的情况是在目录中不包含任何空格。 我将“server side”更改为“serverSide”,然后问题得到解决。 希望能对某些人有所帮助。 - andrew54068
将/data更改为/private。在示例中,/data是常见的。 - Clode Morales Pampanga III
18个回答

185

Docker for Mac 的卷挂载与基础的 Docker 系统有所不同。这主要是因为 Docker 试图遵守苹果的文件系统沙盒指南。

如 Docker 首选项中所示,只有特定路径在 macOS 中被导出:

  • /Users
  • /Volumes
  • /tmp
  • /private

文件共享偏好设置面板

在 macOS 中,/var 是指向 /private 的符号链接。对于 /tmp 也是如此:

$ ls -ld /tmp /var
lrwxr-xr-x@ 1 root  wheel  11 Jan 26 16:18 /tmp -> private/tmp
lrwxr-xr-x@ 1 root  wheel  11 Jan 26 16:18 /var -> private/var

为什么/tmp出现在共享面板中,而/var没有(尽管两者都是/private的一部分)?Docker for Mac有关文件系统命名空间的文档解释:

默认情况下,您可以直接共享/Users//Volumes//private//tmp中的文件。要添加或删除导出到Docker的目录树,请使用Docker首选项鲸鱼菜单->首选项->文件共享中的文件共享选项卡(请参阅首选项)。

除了-v绑定挂载中使用的所有其他路径都来自运行Docker容器的Moby Linux VM,所以诸如-v /var/run/docker.sock:/var/run/docker.sock之类的参数应该按预期工作。如果未共享macOS路径并且在VM中不存在,则尝试绑定挂载将失败,而不是在VM中创建它。 Docker保留已存在于VM中并包含文件的路径,并且不能从macOS导出。

请注意,在此处特别提到了/var/run作为应从Linux VM而不是macOS挂载的位置。

当您要求卷挂载时,会首先检查macOS文件系统导出。如果在此处没有匹配项,则接下来将检查运行Docker的Linux VM。如果它们都没有您请求的路径,则挂载失败。

在您的情况下,/var未受macOS导出。/var存在于Linux VM中,但/var/folders不存在。因此,该路径不可用,挂载失败。

如果将路径更改为/private/var,则会成功,因为macOS导出整个/private文件系统树以进行挂载。

为了使事情更具可移植性,您可能需要测试当前运行的平台,并且如果是macOS,请在挂载路径前缀中使用/private


5
@SamuelMéndez 只需要翻译第一个。格式为mac-path:container-path,其中/private仅存在于Mac端。 - Dan Lowe
3
我遇到了类似的问题,请问是否有人能帮我解决?挂载被拒绝: 路径/etc/localtime不是从OS X共享的,也不为Docker所知。 您可以从Docker->首选项...->文件共享中配置共享路径。 有关更多信息,请参见https://docs.docker.com/docker-for-mac/osxfs/#namespaces。我尝试通过Docker ->首选项...->文件共享添加/etc,但它说/etc保留给mac os。有什么解决办法吗? - Sandish Kumar H N
1
在 macOS 上,/etc 是链接到 /private/etc 的。而 /private 已经在 Docker 首选项的导出列表中了。尝试挂载 /private/etc/localtime - Dan Lowe
1
@DanLowe 感谢您的回复。如果我尝试添加 /private/etc/localtime,会抛出“导出路径 /private/etc/localtime 与导出路径 /private 重叠”的错误。我尝试添加 "/etc/localtime",但是出现了新的错误,它说“APIError: 500 Server Error: Internal Server Error ("error while creating mount source path '/etc/localtime': mkdir /etc/localtime: file exists")”。有什么想法吗? - Sandish Kumar H N
2
让我们在聊天中继续这个讨论 - Sandish Kumar H N
显示剩余9条评论

49

前置条件:需要安装“Docker Desktop”, 按照图片中的步骤进行操作: 在这里输入图片描述


1
这适用于任何版本的Docker桌面版。我在Ubuntu 20.04上使用它。 - Daisuke Aramaki
1
从图像中的步骤: 1)单击“设置” 2)单击“资源”以展开 3)单击“文件共享” 4)单击“+”图标添加路径 5)选择路径后,单击“应用并重启” - Tracy Logan
这在我的Mac上有效。 - Pallawi.ds
点击“添加”图标后,按下“回车”键,这样您才能将其添加到列表中。 (我花了一些时间才找到这个细节,仅仅输入新文件夹是不够的,我无法将其添加到列表中) - José Victor

31

在 Docker for mac 的新版本 3.0.0 中,您需要在“偏好设置 > 实验特性”中禁用使用 gRPC FUSE 进行文件共享。


3
因为某些原因,禁用 gRPC FUSE 对我没有解决问题。 - Arkon
1
矛盾的是,从常规设置中打开 gRPC FUSE 对我有帮助。 - Gamma032

20

我遇到了类似的问题,我在我的 Mac 上创建了一个目录 /var/tmp,我想将其挂载到我的 Docker 容器中。

通过将目录路径添加到文件中解决了这个问题,具体操作如下:

$ cat ~/Library/Group\ Containers/group.com.docker/settings.json  
{
  "filesharingDirectories" : [
    "\/Users",
    "\/Volumes",
    "\/private",
    "\/tmp",
    "\/var\/tmp"
  ],
…

现在我可以在Docker->偏好设置->资源->文件共享中看到目录/var/tmp,然后我重新启动了Docker。

这解决了我的挂载问题。


我在一个历史原因需要挂载到根路径(即 /product_name)的项目中遇到了这个问题。我按照 MacOS synthetic.conf 的编辑方式将它们映射到可访问的文件夹,并使用 docker 设置文件共享共享了这些映射的文件夹。但这还不够,因为 docker UI 不允许您使用 finder 文件选择对话框选择符号链接,所以我必须像描述的那样使用 json 文件编辑文件路径。 - Rob
必须同时添加 /private/var/tmp 和 /var/tmp 才能使其正常工作。 - yaara4
是的,我不想根据我是在我的 Mac 还是 Unix 服务器上运行来更改可访问文件夹的位置。这样可以使 Mac 在其他环境中保持一致。 - Erick G. Hagstrom

13

作为一个替代方案

将路径从/private/instance1-data:/home更改为./instance1-data:/home

在*nix和Docker中,.表示当前目录。由于macOS对沙盒越来越挑剔,这似乎是macOS的可行解决方案。只需在同一目录中创建需要用于instance1的文件夹。

此解决方案的另一个优点是,它消除了使用sudo运行docker-compose的需要。无论如何,在这种情况下不会造成任何伤害,但仍然有优势。


我喜欢这个!它是便携的,不需要“if(macOs)...”,而且在项目根目录中拥有卷可能会更整洁(可以争议)。 - Jannik
1
Docker开始支持相对路径了吗?我使用"$(pwd)/instance1-data"。 - Nick Manning

5
在当前最新版本(Docker 3.0.2)中,在macOS上,您必须允许读取Docker的目录。

enter image description here


5

在此处找到了比列出的版本更新的版本:https://docs.docker.com/docker-for-mac/release-notes/(3.0 版本破坏了我的 Docker 设置) - risa_risa
2
版本3.0也破坏了我的Docker设置。我一直在尝试挂载文件夹,但是不断收到docker-compose错误。我回退到了2.4.0版本。 - kenecaswell
5
另一个解决方法是在Docker首选项的“实验功能”中禁用“使用gRPC Fuse进行文件共享”。请注意保持内容原意不变,同时让翻译更通俗易懂。 - Mohit Rajan

2

例如,使用Portainer,这个命令对我有效:

docker run -d --restart unless-stopped -p 9000:9000 \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var:/data portainer/portainer --no-auth

但是,如果我稍微更改-v /var:/data,它就不起作用了。我认为(但不确定)这是因为Docker尝试进行mkdir操作。因此,如果我尝试挂载-v /var/whatever:/data,则由于权限不足而无法创建目录,从而导致其无法工作。
我有两个Mac(High Sierra),我在两个上都尝试过。同样的问题。我还尝试使用Docker Beta渠道。我想我明白了Dan Lowe的答案:如果这对我有效,我会更新这个答案。
更新:
现在这个可以工作了。注意:我配置docker允许访问/var/tmp。
docker run -d --restart unless-stopped -p 9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/tmp/data:/data portainer/portainer --no-auth

1
如果您在Mac上无法看到文件夹,请打开终端并输入以下内容:
defaults write com.apple.Finder AppleShowAllFiles YES
然后通过按住alt键并在Finder上右键单击(两个手指),选择重新启动,然后在菜单栏中的“文件”旁边单击Finder,单击“偏好设置”,在“显示这些项目”下添加硬盘的检查,然后在侧边栏中也检查硬盘,然后转到隐藏的文件夹并将其拖到收藏夹中,它将出现在docker>首选项>资源>文件共享>+窗口中。

1
如果您在MAC上仍然遇到此问题,请尝试添加:$PWD
像这样在本地文件目录路径之前添加$PWD:docker run -v $PWD/folders/:/path/to/directory。

问题已经解决,谢谢 :) - Suraj K

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