你是否正在尝试将一个目录挂载到一个文件上(或者反过来)?

160

我有一个版本为17.06.0-ce的Docker。当我尝试使用以下命令在Docker中安装NGINX时:

docker run -p 80:80 -p 8080:8080 --name nginx -v $PWD/www:/www -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf -v $PWD/logs:/wwwlogs -d nginx:latest

这表明:

docker:守护程序的错误响应:OCI运行时错误: container_linux.go:262:启动容器进程导致 “process_linux.go:339:容器初始化导致“rootfs_linux.go:57: 将\”/appdata/nginx/conf/nginx.conf\“挂载到rootfs上 \”/var/lib/docker/aufs/mnt/dcea22444e9ffda114593b18fc8b574adfada06947385aedc2ac09f199188fa0\\" 在 \"/var/lib/docker/aufs/mnt/dcea22444e9ffda114593b18fc8b574adfada06947385aedc2ac09f199188fa0/etc/nginx/nginx.conf\" 导致\"不是目录\" \"\" :您是否尝试将目录挂载到文件(或反之)? 检查指定的主机路径是否存在且为预期类型。

如果不挂载nginx.conf文件,一切都好。 那么,我如何挂载配置文件?


ls -al . 的输出是什么?想看看你的 pwd 是什么样子。 - Tri Nguyen
1
在我的情况下,我不小心将主机上的一个目录映射到了容器中的一个文件。重新启动容器也无法解决问题。我不得不删除该容器(docker rm...)然后重新创建它。 - slhck
28个回答

158

自从版本v2.2.0.0起,这种情况不应再发生,请参考此处


如果您正在使用Docker for Windows,并且最近更改了密码,则可能会出现此错误。

解决方法:

  1. 首先确保删除已损坏的容器的卷
    docker rm -v <container_name>
    更新:在不需要先删除卷的情况下,以下步骤可能也可以适用。
  2. 打开Docker设置
  3. 转到“共享驱动器”选项卡
  4. 单击窗口底部的“重置凭据…”链接
  5. 重新共享要与Docker使用的驱动器
  • 您应该会被提示输入用户名/密码
  1. 单击“应用”
  2. 转到“重置”选项卡
  3. 单击“重新启动Docker”
  4. 重新创建您的容器/卷

感谢GitHub上的BaranOrnarli提供了解决方案。


2
谢谢!对我来说,从第二步开始并避免最后一步是有效的。 - Mateo Hermosilla
1
我能够通过从第二步开始并省略最后一步来解决问题。我不需要销毁容器/卷以重新挂载。 - Christian Engel
当我尝试安装sandbox-proxy(hadoop)时运行proxy-deploy.sh时,我遇到了相同的错误。按照这个解决方案并没有解决它。 - Vaibhav
2
这对我来说是个问题。密码重置是每几个月一次,所以我经常忘记在Docker中重置共享驱动器凭据。 - Anders Marzi Tornblad
我在Ubuntu下遇到了这个错误,当我改变了一个之前不存在的卷中挂载的文件时。 - undefined
显示剩余2条评论

111

简要概述:删除与容器相关联的卷。

使用docker ps -a查找容器名称,然后使用以下命令删除该容器:

docker rm -v <container_name>

问题:

如果您以前尝试运行docker run命令时,在主机目录中应该存在的文件不存在,您可能会遇到错误。

在这种情况下,Docker守护程序将在容器内创建一个目录,当正确的文件放置在主机目录中并再次运行docker命令时,该目录无法正确映射到相应的文件。

解决方案:

删除与容器关联的卷。如果您不关心其他容器卷,也可以使用以下命令:

# WARNING, THIS WILL REMOVE ALL VOLUMES
docker volume rm $(docker volume ls -q)

@programmerq 看看这个错误,它说当它尝试在 /var/lib/docker/aufs/mnt/dcea22444e9ffda114593b18fc8b574adfada06947385aedc2ac09f199188fa0\\\" 挂载时,挂载失败了。我的推断是:由于之前的运行已经有一个文件夹了,所以如果你尝试将一个文件映射到那个文件夹,它会失败。 - Ayushya
这里可能出了两个问题,要么是主机有错误的东西,要么已经创建的卷有不正确的东西。假设主机是正确的,我认为最好解决现有卷的问题。 - Ayushya
1
这实际上是一个有效的答案,当容器已经与卷关联,并且该卷的类型在下一次运行中被更改时。因此,删除卷可能会有所帮助! - Yan Foto
1
这很有帮助。在我的情况下问题确实是我仍然定义了旧容器。使用docker rm将它们删除,然后执行docker-compose up即可正常工作。 - Max Tardiveau
我发现只需运行 docker-compose down -v 命令清除失败的卷数据就很有帮助,而不是清除所有卷,但这个答案的详尽程度仍然很有用。 - netpoetica
显示剩余3条评论

44

因为 Docker 会将 $PWD/conf/nginx.conf 识别为一个文件夹而不是文件。请检查 $PWD/conf/ 目录是否包含 nginx.conf 文件夹。

测试用例:

> cat $PWD/conf/nginx.conf 
cat: nginx.conf/: Is a directory
否则,打开一个名为Docker issue的问题报告。
对我来说,使用相同配置一切都正常运作。

2
作为一个中级 Linux 用户,我很好奇,Linux 为什么会将那个识别为文件夹而不是文件? - J. Scott Elblein
4
因为它实际上是一个文件夹。如果文件不存在,Docker会根据卷参数-v创建一个文件夹。 - callmemath
5
好的,所以如果 Docker 不得不创建一个路径,因为该路径之前不存在,Linux 只会将其识别为文件夹;但是如果 nginx.conf 已经存在于该路径中,Linux 将把它识别为文件,对吗? - J. Scott Elblein

9
@Ayushya给出的解释是我遇到这个有点令人困惑的错误消息的原因,必要的清理工作可以轻松完成,就像这样:
$ docker container prune
$ docker volume prune

8
我遇到了同样的问题。我在Windows 10 17.09中使用Docker桌面版与WSL。
问题的原因是Docker for Windows希望您以与此匹配的格式提供卷路径:
/c/Users/username/app 但是,WSL使用的格式是:
/mnt/c/Users/username/app 这很令人困惑,因为当我在控制台中检查文件时,我看到了它,对我来说一切都是正确的。我不知道Docker for Windows对于“卷路径”的期望。
解决问题的方法是将自定义挂载点绑定以修复Docker for Windows和WSL之间的差异:
sudo mount --bind /mnt/c /c
就像在这篇令人惊叹的指南中建议的那样:Setting Up Docker for Windows and WSL to Work Flawlessly,现在一切都正常工作了。
在我开始使用WSL之前,我也遇到了这个问题,当时我在使用Git Bash。

1
更多细节请参见:https://github.com/10up/wp-local-docker/issues/81#issuecomment-376265974 - nbeuchat
我在解决问题后找到了这个。我的解决方案是将当前文件夹与我的主机挂载文件从我的主目录移动到 /e/(这是另一个驱动器,正如您在答案中所解释的那样),以使其正常工作。我感谢您的评论,您解释了问题所在,我只是意识到我的解决方案可行,但不知道原因。 - Arizon

8

在我的Mac上,我必须在“设置 -> 通用”中取消勾选“使用gRPC FUSE进行文件共享”的复选框。

输入图像描述


2
谢谢,这解决了我的问题。我还在“实验性功能”部分关闭了使用Docker Compose v2的选项。 - Jafferwaffer
1
这在苹果硅芯片的Mac上不起作用,可能会导致Docker卡在启动守护程序的状态。 - sparanoid
这对我有用。我使用的是硅片 Mac。 - Wlada
1
对我来说没用。 - Talha Meh

8

针对使用Docker Toolbox的用户的答案:

这里至少有3个回答涉及到了问题,但没有很好地解释和给出完整的解决方案。这只是一个文件夹挂载问题

问题描述:

Docker Toolbox通过创建一个虚拟机(在捆绑的VirtualBox中)来绕过Docker的Hyper-V要求。 Docker安装并在VM内运行。为了使Docker正常工作,它需要访问主机机器上的内容。但是在这里它无法访问。

安装Docker Toolbox后,它创建了VirtualBox VM,并仅将C:\ Users 加载到机器上,如\ c \ Users \ 。我的项目位于C:\ projects 中,因此未在已挂载的卷上找到任何路径。当我将路径发送到VM时,它将不存在,因为C:\ projects 未挂载。因此,出现了上述错误。

假设我的项目包含在C:/ projects / project_name /中,其中包含我的ngnix配置

修复方法:

  1. 进入VirtualBox,右键单击默认值(来自Docker的VM)>设置>共享文件夹 “输入图像描述”
  2. 点击右侧带加号的小图标,添加一个新共享。我使用了以下设置:

enter image description here

  1. 上述操作将把C:\projects映射到VM中的/projectsROOT/projects),这意味着现在您可以像这样引用项目中的任何路径:/projects/project_name ,因为C:\projects\project_name中的project_name现在已经加载。

要使用相对路径,请考虑将路径命名为c/projects而不是projects

  1. 重新启动一切,它现在应该正常工作。我手动停止了VirtualBox中的虚拟机并重新启动了Docker Toolbox CLI。

在我的docker文件中,我现在可以像这样引用nginx.conf

volumes:
    - /projects/project_name/docker_config/nginx/nginx.conf:/etc/nginx/conf.d/default.conf

nginx.conf 实际位于 C:\projects\project_name\docker_config\nginx\nginx.conf


5
也许有人会发现这很有用。我的组合文件挂载了以下卷。
./file:/dir/file

由于 ./file 文件不存在,它被默认挂载到 ABC (作为文件夹)。

在我的情况下,我有一个容器是由以下命令产生的:

docker commit ABC cool_image

当我后来创建了./file并运行docker-compose up时,出现了以下错误:
[...]你是否尝试将目录挂载到文件(或反之)?请检查指定的主机路径是否存在并且是期望的类型。
从cool_image启动的容器记得/dir/file是一个目录,并且它与最近创建和挂载的./file发生冲突。
解决方案如下:
touch ./file
docker run abc_image --name ABC -v ./file:/dir/file
# ... desired changes to ABC
docker commit ABC cool_image

谢谢,这也是我的问题,因为我有一个相当复杂的Docker设置! - rmcsharry

4
我正在使用Windows版的Docker工具箱。默认情况下,C盘会自动挂载,所以为了挂载文件,请确保您的文件和文件夹位于C盘内。
例如:C:\Users\%USERNAME%\Desktop

1
我的挂载文件夹是 C:\x-suite\;我分享了我的C盘,但仍未解决我的问题。 - 袁文涛
你正在使用Docker Toolbox吗? - Abhishek D K
minikube+virtualBox+docker ToolBox,localkube已被弃用,我应该使用哪个驱动程序? - 袁文涛
如果您正在从Docker Compose中进行挂载,则使用${pwd}/<路径>。 - Abhishek D K
如果您正在从命令行挂载卷,则使用 -v /c/x-suite/。 - Abhishek D K
1
如果您正在使用Dockerfile,则请使用VOLUME /c/x-suite。 - Abhishek D K

3

对我来说,只需要这样做:

docker compose down
docker compose up -d

docker-compose 之间缺少一个破折号。 - PHZ.fi-Pharazon

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