如何在Docker容器中安装主机目录

Kis*_*nav 552 mount docker boot2docker

我正在尝试将主机目录挂载到Docker容器中,以便在主机上完成的任何更新都会反映到Docker容器中.谷歌搜索和阅读Docker音量链接后,我无法成功.

我在哪里做错了什么.这是我做的:

kishore$ cat Dockerfile

FROM ubuntu:trusty
RUN apt-get update
RUN apt-get -y install git curl vim
CMD ["/bin/bash"]
WORKDIR /test_container
VOLUME ["/test_container"]
Run Code Online (Sandbox Code Playgroud)

kishore$ tree
.
??? Dockerfile
??? main_folder
    ??? tfile1.txt
    ??? tfile2.txt
    ??? tfile3.txt
    ??? tfile4.txt

1 directory, 5 files kishore$ pwd /Users/kishore/tdock

Run Code Online (Sandbox Code Playgroud)
kishore$ docker build --tag=k3_s3:latest .

Uploading context 7.168 kB
Uploading context
Step 0 : FROM ubuntu:trusty
 ---> 99ec81b80c55
Step 1 : RUN apt-get update
 ---> Using cache
 ---> 1c7282005040
Step 2 : RUN apt-get -y install git curl vim
 ---> Using cache
 ---> aed48634e300
Step 3 : CMD ["/bin/bash"]
 ---> Running in d081b576878d
 ---> 65db8df48595
Step 4 : WORKDIR /test_container
 ---> Running in 5b8d2ccd719d
 ---> 250369b30e1f
Step 5 : VOLUME ["/test_container"]
 ---> Running in 72ca332d9809
 ---> 163deb2b1bc5
Successfully built 163deb2b1bc5
Removing intermediate container b8bfcb071441
Removing intermediate container d081b576878d
Removing intermediate container 5b8d2ccd719d
Removing intermediate container 72ca332d9809
Run Code Online (Sandbox Code Playgroud)

kishore $ docker run -d -v/Users/kishore/main_folder:/ test_container k3_s3:latest c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea

kishore$ docker run -i -t k3_s3:latest /bin/bash

root@0f17e2313a46:/test_container# ls -al
total 8
drwx------  2 root root 4096 Apr 29 05:15 .
drwxr-xr-x 66 root root 4096 Apr 29 05:15 ..
Run Code Online (Sandbox Code Playgroud)

root @ 0f17e2313a46:/ test_container #exit exit

kishore$ docker -v
Docker version 0.9.1, build 867b2a9
Run Code Online (Sandbox Code Playgroud)

  • 我不知道如何检查boot2docker版本

问题,面临的问题:

  1. 如何将main_folder链接到docker容器中的test_container文件夹?
  2. 我需要自动完成.如果没有真正使用run -d -v命令,我该怎么做呢?
  3. 如果boot2docker崩溃会怎么样?存储Docker文件在哪里(除了Dockerfile)?

nhj*_*hjk 457

有几种方法可以做到这一点.最简单的方法是使用dockerfile ADD命令,如下所示:

ADD . /path/inside/docker/container
Run Code Online (Sandbox Code Playgroud)

但是,在构建dockerfile之后对主机上的此目录所做的任何更改都不会显示在容器中.这是因为在构建容器时,docker将目录压缩为a .tar并将该上下文永久地上载到容器中.

执行此操作的第二种方法是您尝试的方式,即装入卷.由于试图将尽可能实现可移植性你不能映射主机目录的dockerfile内的泊坞窗容器目录,因为主机目录可以根据哪台机器上正在运行的改变.要将主机目录映射到docker容器目录,您需要-v在使用docker run时使用该标志,如下所示:

docker run -v /host/directory:/container/directory -other -options image_name command_to_run
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说在mac os x上使用docker-machine和VirtualBox.我通过反复试验发现的一个警告是主机目录必须是完整路径而不是相对路径. (27认同)
  • `ADD`实际上不是"挂载"它将文件复制到容器内部. (17认同)
  • 你能同时拥有 ADD 吗?和 -v 卷同时挂载。如果未指定主机安装,则使用默认 app_dir? (2认同)

Edu*_*ana 175

这个问题的用户正在使用Docker version 0.9.1, build 867b2a9,我会给你一个docker版本> = 17.06的答案.

您想要的是,在容器目录中保持本地目录同步,是通过安装类型的卷来完成的bind.这将绑定源(您的系统)和目标(在docker容器)目录.它与在linux上安装目录几乎相同.

根据Docker文档,现在安装适当的命令mount而不是-v.这是它的文档:

  • --mount:由多个键值对组成,以逗号分隔.每个键/值对采用<key>=<value>元组的形式.该--mount语法比更详细的-v--volume,但按键的顺序并不显著,并且标志的价值更容易理解.

  • type安装件,其可以是bind,volume,或tmpfs.(我们将使用bind)

  • source安装的.对于绑定装入,这是Docker守护程序主机上的文件或目录的路径.可以指定为sourcesrc.

  • destination文件或目录安装在容器中的路径作为其值.可以指定为destination,dsttarget.

因此,要安装当前目录(源)与/test_container(目标),我们将使用:

    docker run -it --mount src="$(pwd)",target=/test_container,type=bind k3_s3
Run Code Online (Sandbox Code Playgroud)

如果这些安装参数有空格,则必须在它们周围加上引号.当我知道他们不这样做时,我会`pwd`改用:

    docker run -it --mount src=`pwd`,target=/test_container,type=bind k3_s3
Run Code Online (Sandbox Code Playgroud)

您还必须处理文件权限,请参阅此文章.

  • 我想自从这个答案以来文档已经更新了,因为现在它似乎推荐卷,而不是安装。在做出任何事情之前,值得先考虑一下。 (3认同)
  • 我赞成您的回答,因为我喜欢它的简洁性并没有错,但是您可能要根据我在/sf/answers/3628047321/上的回答进行一些更新 (2认同)
  • Docker 仍然建议在开发用例中使用绑定挂载:https://docs.docker.com/develop/dev-best-practices/ “适合使用绑定挂载的一种情况是在开发过程中,当您可能想要挂载时您的源目录或刚刚构建到容器中的二进制文件。对于生产,请使用卷,将其安装到与开发期间安装绑定安装相同的位置。 (2认同)

小智 78

2个连续的安装:我想这里的很多帖子可能都使用了两个boot2docker,你没有看到任何东西的原因是因为你从boot2docker安装的目录不是来自你的主机.

您基本上需要2个连续的挂载:第一个从主机到系统挂载目录,第二个挂载从boot2docker到您的容器,如下所示:

1.在boot2docker上安装本地系统

sudo mount -t vboxsf hostfolder /boot2dockerfolder
Run Code Online (Sandbox Code Playgroud)

2.在linux容器上挂载boot2docker文件

docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename
Run Code Online (Sandbox Code Playgroud)

然后,当您boot2docker在容器文件夹中时,您将看到主机文件夹的内容.


rga*_*aut 60

你可以使用cli中的-v选项,这个工具不能通过Dockerfile使用

docker run -t -i -v <host_dir>:<container_dir> ubuntu /bin/bash

其中host_dir是要装入的主机的目录.你不需要担心容器的目录,如果它不存在,docker会创建它.

如果您在host_dir中对主机进行任何更改(在root权限下),它将对容器可见,反之亦然.

  • 这是一个很好的,干净的,可以说明主机挂载选项的示例.它可以通过使用真实目录来改进:`docker run -t -i -v/tmp:/ tmp ubuntu/bin/bash`其中主机`/ tmp`将安装在容器`/ tmp`上.现在可以从容器中"触摸/ tmp/hello-world",看到文件出现在主机上. (4认同)
  • 完美的作品。但是以这种方式安装会将目录所有者设置为root,这也希望容器以root运行。当容器以非根用户身份运行时,如何将目录以非根用户身份挂载? (2认同)

Mik*_*Chu 36

对于那些想要在当前目录中挂载文件夹的人:

docker run -d --name some-container -v ${PWD}/folder:/var/folder ubuntu
Run Code Online (Sandbox Code Playgroud)


小智 33

是否有可能在OS X上使用docker boot2docker或类似的东西.

我已经取得了相同的经验 - 命令是正确的,但无论如何都没有(明智的)安装在容器中.

事实证明 - 它已经在docker文档中解释过了.当您键入docker run -v /var/logs/on/host:/var/logs/in/container ...那么/var/logs/on/host实际上是从映射的boot2dockerVM映像,而不是你的Mac.

您必须通过VM将共享文件夹传输到您的实际主机(在我的情况下为Mac).

  • 您的文档链接是 404 (3认同)
  • 我很想看到通过VM将共享文件夹传递给实际主机的示例. (3认同)
  • 该 docker 文档的 URL 不再有效 (2认同)

Eli*_*Eli 28

[更新]截至2017年6月,Docker for Mac负责处理所有烦人的部分,你必须弄乱VirtualBox.它允许您使用/private前缀基本上映射本地主机上的所有内容.更多信息在这里.[/ UPDATE]

所有当前的答案都谈到了Boot2docker.由于现在已经弃用了docker-machine,这适用于docker-machine:

首先,ssh进入docker-machine vm并创建我们要映射到的文件夹:

docker-machine ssh $MACHINE_NAME "sudo mkdir -p \"$VOL_DIR\""
Run Code Online (Sandbox Code Playgroud)

现在将文件夹共享到VirtualBox:

WORKDIR=$(basename "$VOL_DIR")
vboxmanage sharedfolder add "$MACHINE_NAME" --name "$WORKDIR" --hostpath "$VOL_DIR" --transient
Run Code Online (Sandbox Code Playgroud)

最后,再次进入docker-machine并挂载我们刚刚共享的文件夹:

docker-machine ssh $MACHINE_NAME "sudo mount -t vboxsf -o uid=\"$U\",gid=\"$G\" \"$WORKDIR\" \"$VOL_DIR\""
Run Code Online (Sandbox Code Playgroud)

注意:对于UID和GID,只要它们尚未被采用,您基本上可以使用任何整数.

这是在OS X El Capitan上测试的docker-machine 0.4.1和docker 1.8.3.

  • @igracia '-v' 标志并不像您在 OS X(或 Windows)中所期望的那样工作。Docker 在虚拟机中运行,因此“-v”中引用的文件夹指向虚拟机中的文件夹,而不是根操作系统中的文件夹。该技术的下一步是将虚拟机文件夹映射回根操作系统。 (2认同)

Sve*_*ven 27

我只是尝试让我的SailsJS应用程序在Docker容器中运行,以保持我的物理机器清洁.

我正在使用以下命令在/ app下挂载我的SailsJS/NodeJS应用程序:

cd my_source_code_folder
docker run -it -p 1337:1337 -v $(pwd):/app my_docker/image_with_nodejs_etc

  • 如何在Dockerfile中执行此操作? (5认同)

小智 20

docker run -v /host/directory:/container/directory -t IMAGE-NAME /bin/bash

docker run -v /root/shareData:/home/shareData -t kylemanna/openvpn /bin/bash
Run Code Online (Sandbox Code Playgroud)

在我的系统中,我已经纠正了nhjk的答案,当你添加-t标志时它会完美无瑕.


bor*_*mat 20

在 Mac OS 上,要/Users/<name>/projects/在 mac 上的容器根目录下挂载文件夹:

docker run -it -v /Users/<name>/projects/:/projects <container_name> bash

ls /projects


Bay*_*ria 15

使用command-line

docker run -it --name <WHATEVER> -p <LOCAL_PORT>:<CONTAINER_PORT> -v <LOCAL_PATH>:<CONTAINER_PATH> -d <IMAGE>:<TAG>
Run Code Online (Sandbox Code Playgroud)

使用docker-compose.yaml

version: '2'
  services:
    cms:
       image: <IMAGE>:<TAG>
       ports:
       - <LOCAL_PORT>:<CONTAINER_PORT>
       volumes:
       - <LOCAL_PATH>:<CONTAINER_PATH>
Run Code Online (Sandbox Code Playgroud)

认为 :

  • 图片:k3_s3
  • 标签: 最新
  • 本地端口:8080
  • 容器_端口:8080
  • LOCAL_PATH: /volume-to-mount
  • 容器_路径:/mnt

例子 :

  1. 首先创建/volume-to-mount。(如果存在则跳过)
$ mkdir -p /volume-to-mount
Run Code Online (Sandbox Code Playgroud)
  1. docker-compose -f docker-compose.yaml up -d
version: '2'
  services:
    cms:
       image: ghost-cms:latest
       ports:
       - 8080:8080
       volumes:
       - /volume-to-mount:/mnt
Run Code Online (Sandbox Code Playgroud)
  1. 验证您的容器:
docker exec -it CONTAINER_ID ls -la /mnt
Run Code Online (Sandbox Code Playgroud)


Tal*_*Tal 11

2015年7月更新 - boot2docker现在支持直接安装.您可以-v /var/logs/on/host:/var/logs/in/container直接在Mac提示符下使用,无需双重安装


Nik*_*tQa 11

我一直有同样的问题.我的命令行看起来像这样:

docker run --rm -i --name $NAME -v `pwd`:/sources:z $NAME
Run Code Online (Sandbox Code Playgroud)

问题出在'pwd'上.所以我改为$(pwd):

docker run --rm -i --name $NAME -v $(pwd):/sources:z $NAME
Run Code Online (Sandbox Code Playgroud)

  • z选项指示绑定安装内容在多个容器之间共享。 (2认同)

Duk*_*e79 10

如果主机是Windows 10,请使用反斜杠而不是正斜杠-

docker run -it -p 12001:80 -v c:\Users\C\Desktop\dockerStorage:/root/sketches
Run Code Online (Sandbox Code Playgroud)

确保主机驱动器是共享的(在这种情况下为C)。在我的情况下,运行上述命令后,提示我询问共享权限。


rai*_*bba 8

从Docker 18-CE开始,您可以用于docker run -v /src/path:/container/path对主机文件夹进行2向绑定。

但是,如果您使用的是Windows 10 / WSL,并且使用Windows的Docker-CE作为主机,然后使用WSL的docker-ce客户端工具,这里会有一个重大问题。WSL知道整个/文件系统,而Windows主机只知道您的驱动器。在WSL内,您可以使用/ mnt / c / projectpath,但是如果尝试使用docker run -v ${PWD}:/projectpath,您将在主机中发现/ projectpath /为空,因为在主机上/ mnt无效。

如果您从/ c / projectpath开始工作,然后docker run -v ${PWD}:/projectpath在容器中找到,则/ projectpath将实时反映/ c / projectpath。除了看到客户机内部的空挂载以外,没有错误或任何其他方式可以检测到此问题。

您还必须确保在Docker for Windows设置中“共享驱动器”。


K F*_*K F 8

对于Windows 10用户,将挂载点放在C:/Users/目录中很重要。我尝试了几个小时才能使它正常工作。这篇文章有所帮助,但起初并不明显,因为Windows 10的解决方案是对已接受答案的评论。这是我的方法:

docker run -it -p 12001:80 -v //c/Users/C/Desktop/dockerStorage:/root/sketches \
<your-image-here> /bin/bash
Run Code Online (Sandbox Code Playgroud)

然后对其进行测试,您可以echo TEST > hostTest.txt在图像内部进行操作。您应该可以在本地主机文件夹中看到此新文件C:/Users/C/Desktop/dockerStorage/

  • 我们可以提供帮助您解决问题的帖子的链接吗? (2认同)

Man*_*Ali 7

我发现在系统指令下放置的任何目录(如/var,/usr)/etc都无法安装在容器下.

该指令应该在用户的空间-v开关指示docker守护进程将本地目录挂载到容器,例如:

docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}
Run Code Online (Sandbox Code Playgroud)


mat*_*tes 5

boot2docker和VirtualBox Guest Additions
如何将用户安装到boot2docker

https://medium.com/boot2docker-lightweight-linux-for-docker/boot2docker-together-with-virtualbox-guest-additions-da1e3ab2465c

tl; dr使用VirtualBox Guest Additions(请参阅链接)构建您自己的自定义boot2docker.iso 或下载 http://static.dockerfiles.io/boot2docker-v1.0.1-virtualbox-guest-additions-v4.3.12.iso 并保存到〜/ .boot2docker / boot2docker.iso。


Emi*_*ile 5

如何将main_folder链接到docker容器中存在的test_container文件夹?

您的以下命令是正确的,除非您在Mac上使用boot2docker(取决于将来的更新),在这种情况下,您可能会发现该文件夹为空。有关更正此问题的教程,请参见遮罩答案。

docker run -d -v /Users/kishore/main_folder:/test_container k3_s3:latest
Run Code Online (Sandbox Code Playgroud)

我需要自动运行该程序,如何在不真正使用run -d -v命令的情况下执行此操作。

您真的无法摆脱使用这些命令的麻烦,它们是docker工作方式所固有的。您最好将它们放入shell脚本中,以免您反复将它们写出来。

如果boot2docker崩溃怎么办?Docker文件存储在哪里?

如果您设法使用-v arg并引用您的主机,则文件将在您的主机上安全。

如果您使用了'docker build -t myimage'。使用Dockerfile,您的文件将被烘焙到映像中。

我相信您的docker映像存储在boot2docker-vm中。当我从VirtualBox删除虚拟机时图像消失时,我发现了这一点。(请注意,我不知道Virtualbox的工作方式,因此图像可能仍隐藏在其他地方,只是对docker不可见)。


mat*_*eus 5

有同样的问题。在docker文档中找到了这个:

注意:主机目录本质上是依赖主机的。因此,您无法从Dockerfile挂载主机目录,VOLUME指令不支持传递主机目录,因为构建的映像应该是可移植的。主机目录并非在所有潜在主机上都可用。

因此,只能使用命令中的-v参数来安装读/写主机目录docker run,因为其他答案正确指出。


Cha*_*hak 5

请注意,在 Windows 中您必须提供绝对路径。

下面为我​​工作。

docker run -t -i -v D:/projects/:/home/chankeypathak/work -p 8888:8888 jupyter/tensorflow-notebook /bin/bash
Run Code Online (Sandbox Code Playgroud)


J. *_*ein 5

这是一个带有 Windows 路径的示例:

docker run -P -it --name organizr --mount src="/c/Users/MyUserName/AppData/Roaming/DockerConfigs/Organizr",dst=/config,type=bind organizrtools/organizr-v2:latest
Run Code Online (Sandbox Code Playgroud)

作为旁注,在所有这些头发拉扯过程中,不得不一遍又一遍地弄清楚和重新输入路径,我决定AutoHotkey编写一个小脚本将 Windows 路径转换为“Docker Windows ”格式的路径. 这样我所要做的就是将我想用作安装点的任何 Windows 路径复制到剪贴板,按键盘上的“应用程序键”,它会将其格式化为 Docker 喜欢的路径格式。

例如:

将此复制到剪贴板:

C:\Users\My PC\AppData\Roaming\DockerConfigs\Organizr

Apps Key当光标是希望它的命令行,它会粘贴此有:

"/c/Users/My PC/AppData/Roaming/DockerConfigs/Organizr"

为我节省了很多时间。在这里,它适用于可能会发现它有用的任何其他人。

; --------------------------------------------------------------------------------------------------------------
;
; Docker Utility: Convert a Windows Formatted Path to a Docker Formatter Path
;                   Useful for (example) when mounting Windows volumes via the command-line.
;
; By:       J. Scott Elblein
; Version:  1.0
; Date:     2/5/2019
;
; Usage:    Cut or Copy the Windows formatted path to the clipboard, press the AppsKey on your keyboard
;           (usually right next to the Windows Key), it'll format it into a 'docker path' and enter it
;           into the active window. Easy example usage would be to copy your intended volume path via
;           Explorer, place the cursor after the "-v" in your Docker command, press the Apps Key and
;           then it'll place the formatted path onto the line for you.
;
; TODO::    I may or may not add anything to this depending on needs. Some ideas are:
;           
;           - Add a tray menu with the ability to do some things, like just replace the unformatted path
;               on the clipboard with the formatted one rather than enter it automatically.
;           - Add 'smarter' handling so the it first confirms that the clipboard text is even a path in
;               the first place. (would need to be able to handle Win + Mac + Linux)
;           - Add command-line handling so the script doesn't need to always be in the tray, you could
;               just pass the Windows path to the script, have it format it, then paste and close.
;               Also, could have it just check for a path on the clipboard upon script startup, if found
;               do it's job, then exit the script.
;           - Add an 'all-in-one' action, to copy the selected Windows path, and then output the result.
;           - Whatever else comes to mind.
;
; --------------------------------------------------------------------------------------------------------------

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%

AppsKey::

    ; Create a new var, store the current clipboard contents (should be a Windows path)
    NewStr := Clipboard

    ; Rip out the first 2 chars (should be a drive letter and colon) & convert the letter to lowercase
    ; NOTE: I could probably replace the following 3 lines with a regexreplace, but atm I'm lazy and in a rush.
    tmpVar := SubStr(NewStr, 1, 2)
    StringLower, tmpVar, tmpVar

    ; Replace the uppercase drive letter and colon with the lowercase drive letter and colon
    NewStr := StrReplace(NewStr, SubStr(NewStr, 1, 2), tmpVar)

    ; Replace backslashes with forward slashes
    NewStr := StrReplace(NewStr,  "\", "/")

    ; Replace all colons with nothing
    NewStr := StrReplace(NewStr, ":", "")

    ; Remove the last char if it's a trailing forward slash
    NewStr :=  RegExReplace(NewStr, "/$")

    ; Append a leading forward slash if not already there
    if RegExMatch(NewStr, "^/") == 0
        NewStr :=  "/" . NewStr

    ; If there are any spaces in the path ... wrap in double quotes
    if RegExMatch(NewStr, " ") > 0
        NewStr :=  """" . NewStr . """"

    ; Send the result to the active window
    SendInput % NewStr 
Run Code Online (Sandbox Code Playgroud)


Ada*_*ith 5

为了让它在Windows 10 中工作,我必须从系统托盘打开 Docker 设置窗口并转到共享驱动器部分。

然后我选中了旁边的框C。Docker 要求我提供桌面凭据以获得写入我的用户文件夹的授权。

然后我按照上面的示例以及该设置页面上的示例运行 docker 容器,附加到/data容器中。

docker run -v c:/Users/<user.name>/Desktop/dockerStorage:/data -other -options
Run Code Online (Sandbox Code Playgroud)