单个文件卷作为目录安装在Docker中

TTT*_*TTT 48 linux docker dockerfile

Docker文档说可以将单个文件挂载到Docker容器中:

-v标志还可用于从主机安装单个文件 - 而不仅仅是目录.

$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

这将使您进入新容器中的bash shell,您将获得主机的bash历史记录,当您退出容器时,主机将具有在容器中键入的命令的历史记录.

当我尝试这个时,文件安装为目录:

tom@u ~/project $ docker run --rm -it -v file.json:/file.json test
total 80K
drwxr-xr-x  9 root root 4.0K Dec  7 12:58 .
drwxr-xr-x 63 root root 4.0K Dec  7 12:58 ..
drwxr-xr-x  2 root root 4.0K Dec  4 16:10 file.json
Run Code Online (Sandbox Code Playgroud)

我的Dockerfile看起来像这样:

FROM ubuntu:14.04
MAINTAINER Tom
CMD ["ls", "-lah", "/test"]
Run Code Online (Sandbox Code Playgroud)

Docker版本是1.9.1,构建a34a1d5.

这是一个文档问题,在我身边的误解,还是还有其他事情发生?

小智 54

也许这在上面的答案中是清楚的......但是我花了一些时间来解决这个问题.

导致与-v共享文件的基本原因是作为目录而不是文件出现,Docker无法在主机上找到该文件.因此Docker在容器中创建一个新目录,其名称是主机上非现有文件的名称,因为docker认为用户只想共享将来创建的卷/目录.

因此,在上面报告的问题中,如果在-v命令中使用了相对目录,并且docker不了解相关目录,则表示在主机上找不到该文件,因此docker创建了一个目录.当问题是由相对目录引起时,上面的答案建议使用$(pwd)将是正确的解决方案.

但对于那些阅读此页面的人而言,他们没有使用相对目录并且遇到同样的问题......那么试着理解为什么主机上缺少文件.

这可能只是一个愚蠢的错字......

可能是您从客户端运行"docker run"命令,该客户端在另一台主机上生成docker容器,并且该共享文件不存在于该主机上.与-v共享的文件必须存在于docker agent将生成容器的主机上...不一定在执行"docker run -v ..."命令的客户端上(尽管它们在很多情况).

对于Mac和Windows,还有其他可能的解释......也可能是这样.

因此,主机中缺少的文件是问题...解决您的设置中的问题...使用$(pwd)可能是解决方案,但并非总是如此.

  • 好的建议。+1 (3认同)
  • 是的,确实+1。在某些用例中,如果您的容器应该创建此文件(并且主机上尚不存在该文件),则这确实不起作用(即“docker run ... -v $(pwd)/file.json: <CONTAINER_FILE>" 实际上会将 file.json 创建为 *dir*,并且您将无法从容器中写入它,因为它不是 *file* 而是 *dir*)。要解决此问题,请确保首先在主机上使用“$ touch file.json”之类的内容创建一个空的 file.json *文件*,然后运行容器。 (2认同)

Von*_*onC 35

test是使用' docker build -t test' 构建的图像的名称,而不是/test文件夹.

尝试Dockerfile使用:

CMD ["ls", "-lah", "/"]
or
CMD ["cat", "/file.json"]
Run Code Online (Sandbox Code Playgroud)

和:

docker run --rm -it -v $(pwd)/file.json:/file.json test
Run Code Online (Sandbox Code Playgroud)

请注意使用$(pwd)以使用其完整绝对路径挂载文件(不支持相对路径)

  • 对于通过谷歌发现这一点的人,请注意`$(pwd)`是你来这里的原因.@ Nikopol的回答如下非常详细地解释了这一点./sf/answers/3146534611/ (3认同)
  • @TTT可以尝试用`$(pwd)/`挂载吗?`docker run --rm -it -v $(pwd)/file.json:/file.json test` (2认同)
  • @TTT太棒了!我已经在答案中使用了绝对路径,以获得更多可见性. (2认同)

JDL*_*JDL 20

我在Windows上花了一些时间与这个问题进行斗争并诊断出这个问题.这也可能会影响在Mac OSX上运行的人,所以我在这里为可能在这些环境中遇到问题的人添加了一个答案,因为我的搜索带我到这个地方,并添加了对docker中发生的事情的解释.

在Windows或Mac OSX中,您的docker实际上在boot2docker VM中运行,默认情况下,实际上只共享users目录.在Windows上,此用户目录以/ c/Users /共享,但是在Docker Machine附带的MinGW shell中,驱动器可以作为/ C或/ c访问,因此如果您忘记了docker命令,这可能会让您感到疯狂实际上是针对boot2docker虚拟机运行的,你的文件路径必须存在于boot2docker虚拟机上,并以它们存在的方式指定,因为在docker中出现的情况是,而不是发出目录/文件所做的警告或错误不存在,码头工人默默地创建指定的源作为boot2docker VM的目录,所以没有现成的输出,以表明你是不正确的做任何事情.

因此,如上面的答案所示,如果您的文件作为目录安装,请检查您是否提供绝对路径.对于Windows和Mac OSX,请检查您安装的绝对路径是否存在于boot2docker VM中.


Mat*_*ice 7

即使您确定该文件存在,Docker 也可能找不到该文件

\n

正如 edi9999 指出的那样,如果您告诉 docker 守护进程挂载文件,它不会查看当前容器的文件系统,而是查看守护进程正在运行的文件系统。

\n

如果您的 docker 守护进程由于某种原因在其他地方运行,您可能会遇到此问题。

\n
\xe2\x9d\xaf docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock docker\n/ # echo "bar" > /foo\n/ # docker run --rm -v /foo:/foo ubuntu bash -c 'cat foo'\ncat: foo: Is a directory\n
Run Code Online (Sandbox Code Playgroud)\n

Docker 在其主机上找不到 /foo 文件,因此它(有帮助吗?)在那里创建一个目录,这样至少您已经安装了一些东西。

\n

解决方法

\n

您可以通过将主机目录安装到外部容器中,然后将该目录用于要显示在内部容器中的卷来解决此问题:

\n
\xe2\x9d\xaf docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v /dev/shm:/dev/shm docker\n/ # echo "bar" > /dev/shm/foo\n/ # docker run --rm -v /dev/shm/foo:/dev/shm/foo ubuntu bash -c 'cat /dev/shm/foo'\nbar\n
Run Code Online (Sandbox Code Playgroud)\n

这使得路径/dev/shm/foo在任一上下文中引用相同的文件,因此您可以从外部容器引用该文件,并且守护进程将在主机上找到它,这意味着它将在内部容器中显示为自身,而不是作为目录。

\n


edi*_*999 5

在docker内部运行docker时(/var/run/docker.sock例如通过挂载),您需要注意,如果在docker内部进行挂载,则使用的文件路径始终是主机上的文件路径。

因此,如果在主机上,请执行以下安装:

-v /tmp/foobar.txt:/my/path/foobar.txt
Run Code Online (Sandbox Code Playgroud)

你应该没有做到以下几点安装内泊坞窗:

-v /my/path/foobar.txt:/my/other/path.txt
Run Code Online (Sandbox Code Playgroud)

但是,请改用主机文件路径,例如:

-v /tmp/foobar:txt:/my/other/path.txt
Run Code Online (Sandbox Code Playgroud)

  • 这正是我在使用 Gitlab CI 时所面临的问题。有没有办法从容器内部知道主机文件路径? (2认同)