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

How to mount a host directory in a Docker container

我正在尝试将主机目录装入Docker容器,以便在主机上所做的任何更新都反映到Docker容器中。在谷歌搜索和阅读Docker卷链接后,我没能成功。

我哪里做错了什么?以下是我所做的:

1
2
3
4
5
6
7
8
9
kishore$ cat Dockerfile
</p>

[cc]FROM ubuntu:trusty
RUN apt-get update
RUN apt-get -y install git curl vim
CMD ["/bin/bash"]
WORKDIR /test_container
VOLUME ["/test_container"]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[cc]kishore$ tree
.
├── Dockerfile
└── main_folder
    ├── tfile1.txt
    ├── tfile2.txt
    ├── tfile3.txt
    └── tfile4.txt
</p>

<p>
1 directory, 5 files
kishore$ pwd
/Users/kishore/tdock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
kishore$ docker build --tag=k3_s3:latest .
</p>

[cc]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

kishore$docker run-d-v/users/kishore/main_folder:/test_container k3_s3:最新c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea

1
2
3
4
5
6
7
[cc]kishore$ docker run -i -t k3_s3:latest /bin/bash
</p>

[cc]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 ..

根@0f17e2313a46:/测试容器退出退出

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

问题,面临的问题:

  • 我需要如何将主文件夹链接到Docker容器中存在的测试容器文件夹?
  • 我需要自动做这个。在不使用run -d -v命令的情况下,如何做到这一点?
  • 如果boot2docker崩溃怎么办?Docker文件存储在哪里(除了DockerFile)?

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

    1
    ADD . /path/inside/docker/container

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

    第二种方法是尝试装载卷。由于试图尽可能地可移植,您无法将主机目录映射到DockerFile中的Docker容器目录,因为主机目录可能会根据运行的计算机而更改。要将主机目录映射到Docker容器目录,在使用Docker run like so时需要使用-v标志:

    1
    docker run -v /host/directory:/container/directory -other -options image_name command_to_run


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

    在容器目录中保持本地目录同步是通过装载类型为bind的卷来实现的。这将绑定源(您的系统)和目标(在Docker容器)目录。它几乎与在Linux上安装目录相同。

    根据Docker文档,要安装的适当命令现在是mount,而不是-v。以下是它的文档:

    • --mount:由多个键值对组成,用逗号分隔。每个键/值对都采用=元组的形式。--mount语法比-v--volume更为冗长,但键的顺序并不重要,标志的值更容易理解。

    • 底座的type,可以是bindvolumetmpfs。(我们将使用bind)

    • 底座的source。对于bind挂载,这是docker守护进程主机上文件或目录的路径。可指定为sourcesrc

    • destination将文件或目录装入容器的路径作为其值。可指定为destinationdsttarget

    因此,要用/test_container号(target)挂载当前目录(source),我们将使用:

    1
        docker run -it --mount src="$(pwd)",target=/test_container,type=bind k3_s3

    如果这些装载参数有空格,则必须在它们周围加引号。如果我知道他们不知道,我会用`pwd`代替:

    1
        docker run -it --mount src=`pwd`,target=/test_container,type=bind k3_s3

    您还必须处理文件权限,请参阅本文。


    2个连续安装:我猜这里的很多帖子可能使用了两个boot2docker,你看不到任何东西的原因是你从boot2docker安装了一个目录,而不是从你的主机。

    您基本上需要两次连续装载:第一次将目录从主机装载到系统,第二次将新目录从boot2docker装载到容器,如下所示:

    1。在boot2docker上安装本地系统

    1
    sudo mount -t vboxsf hostfolder /boot2dockerfolder

    2。在Linux容器上安装boot2docker文件

    1
    docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename

    然后,当您在containerfolder中输入cx1(8)时,您将看到主机文件夹的内容。


    您可以使用cli中的-v选项,此工具无法通过dockerfile使用。

    docker run -t -i -v : ubuntu /bin/bash

    其中,host_dir是要从主机装载的目录。如果容器的目录不存在,您不需要担心,Docker会创建它。

    如果您在主机的主机目录中进行任何更改(在根权限下),那么容器将可以看到它,反之亦然。


    您是否可以通过boot2docker或类似的方式在OSX上使用docker?

    我也有同样的经验——命令是正确的,但容器中无论如何都没有安装任何东西(明智的)。

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

    您必须将共享文件夹通过虚拟机传输到实际主机(在我的例子中是Mac)。


    [更新]截至2017年6月,Docker for Mac负责处理所有恼人的部分,其中您必须处理virtualbox。它允许您基本上使用/private前缀映射本地主机上的所有内容。更多信息。[更新]

    所有当前的答案都是关于boot2docker的。因为现在不赞成使用docker machine,所以这适用于docker machine:

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

    1
    docker-machine ssh $MACHINE_NAME"sudo mkdir -p "$VOL_DIR""

    现在将文件夹共享到virtualbox:

    1
    2
    WORKDIR=$(basename"$VOL_DIR")
    vboxmanage sharedfolder add"$MACHINE_NAME" --name"$WORKDIR" --hostpath"$VOL_DIR" --transient

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

    1
    docker-machine ssh $MACHINE_NAME"sudo mount -t vboxsf -o uid="$U",gid="$G" "$WORKDIR" "$VOL_DIR""

    注意:对于uid和gid,基本上可以使用任何整数,只要它们还没有被取下。

    从OS X El Capitan上的Docker Machine 0.4.1和Docker 1.8.3开始测试。


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

    我正在使用以下命令在/app下安装我的SAILSJS/NODEJS应用程序:

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


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

    docker run -v /root/shareData:/home/shareData -t kylemanna/openvpn /bin/bash

    在我的系统中,我已经更正了NHJK的答案,当您添加-t标志时,它可以毫无瑕疵地工作。


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


    我也有同样的问题。我的命令行如下所示:

    1
    docker run --rm -i --name $NAME -v `pwd`:/sources:z $NAME

    问题出在"pwd"上。所以我把它改成美元(pwd):

    1
    docker run --rm -i --name $NAME -v $(pwd):/sources:z $NAME


    我发现在系统指令下放置的任何目录,如/var/usr/etc都不能安装在容器下。

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

    1
    docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}

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

    不过,如果您使用的是Windows10/WSL,并使用Windows的Docker CE作为主机,然后在WSL中使用Docker CE客户机工具,那么这里有一个主要的问题。wsl知道整个/filesystem,而您的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设置中"共享驱动器"。


    如何将主文件夹链接到Docker容器中的测试容器文件夹?

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

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

    我需要让这个自动运行,如果没有使用run-d-v命令。

    你不能真的摆脱使用这些命令,它们是Docker工作方式的内在因素。最好将它们放入shell脚本中,以避免重复地编写它们。

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

    如果您设法使用-v参数并引用您的主机,那么这些文件在您的主机上将是安全的。

    如果您使用了"docker build-t myimage."和dockerfile,那么您的文件将被烘焙到图像中。

    我相信,你的docker映像存储在boot2docker vm中。当我从virtualbox中删除虚拟机时,我的图像消失了,我发现了这一点。(注意,我不知道virtualbox是如何工作的,因此图像可能仍然隐藏在其他地方,对Docker来说是不可见的)。


    对于Windows10用户,在C:/Users/目录中有装入点是很重要的。我花了好几个小时才把这个做好。这篇文章很有帮助,但起初并不明显,因为Windows10的解决方案是对公认答案的评论。我就是这样做的:

    1
    2
    docker run -it -p 12001:80 -v //c/Users/C/Desktop/dockerStorage:/root/sketches \
    <your-image-here> /bin/bash

    然后,为了测试它,您可以在图像中执行echo TEST > hostTest.txt。您应该能够在C:/Users/C/Desktop/dockerStorage/的本地主机文件夹中看到这个新文件。


    boot2docker和virtualbox来宾添加如何将/用户装入boot2docker

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

    tl;dr Build your own custom boot2docker.iso with VirtualBox Guest
    Additions (see link) or download
    http://static.dockerfiles.io/boot2docker-v1.0.1-virtualbox-guest-additions-v4.3.12.iso
    and save it to ~/.boot2docker/boot2docker.iso.


    有同样的问题。在Docker文档中找到:

    Note: The host directory is, by its nature, host-dependent. For this reason, you can’t mount a host directory from Dockerfile, the VOLUME instruction does not support passing a host-dir, because built images should be portable. A host directory wouldn’t be available on all potential hosts.

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


    下面是一个Windows路径示例:

    1
    docker run -P -it --name organizr --mount src="/c/Users/MyUserName/AppData/Roaming/DockerConfigs/Organizr",dst=/config,type=bind organizrtools/organizr-v2:latest

    作为旁注,在所有这些毛发拉扯的过程中,我不得不反复计算和重新输入路径,我决定创建一个小的AutoHotkey脚本,将Windows路径转换为"Docker Windows"格式的路径。这样,我所要做的就是将我想用作挂载点的任何Windows路径复制到剪贴板上,按键盘上的"应用程序键",然后将其格式化为Docker欣赏的路径格式。

    例如:

    将此复制到剪贴板:

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

    当光标位于命令行上所需的位置时,按Apps Key,它将粘贴到以下位置:

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

    为我节省了很多时间。这是给其他可能会发现它有用的人的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    ; --------------------------------------------------------------------------------------------------------------
    ;
    ; 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


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

    • 主机:Windows 10
    • 容器:TensorFlow笔记本

    下面为我工作。

    1
    docker run -t -i -v D:/projects/:/home/chankeypathak/work -p 8888:8888 jupyter/tensorflow-notebook /bin/bash

    我也有同样的问题,我试图在Docker上挂载c:usersfolder我就是这样做的Docker工具箱命令行

    1
     $ docker run -it --name <containername> -v /c/Users:/myVolData <imagename>


    我有同样的要求从容器装载主机目录,我使用了卷装载命令。但在测试过程中,发现它也在容器内创建文件,但经过一些挖掘发现它们只是符号链接,而实际的文件系统则是从主机上使用的。