我正在尝试将主机目录挂载到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"]
FROM ubuntu:trusty RUN apt-get update RUN apt-get -y install git curl vim CMD ["/bin/bash"] WORKDIR /test_container VOLUME ["/test_container"]
kishore$ tree . ├── Dockerfile └── main_folder ├── tfile1.txt ├── tfile2.txt ├── tfile3.txt └── tfile4.txt
1 directory, 5 files kishore$ pwd /Users/kishore/tdock
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
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:latest
c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea
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 ..
命令,我该怎么做?答案 0 :(得分:394)
有几种方法可以做到这一点。最简单的方法是使用dockerfile ADD
命令,如下所示:
ADD . /path/inside/docker/container
但是,在构建dockerfile之后对主机上的此目录所做的任何更改都不会显示在容器中。这是因为在构建容器时,docker会将目录压缩为.tar
并将上下文永久上传到容器中。
执行此操作的第二种方法是您尝试的方式,即装入卷。由于尝试尽可能地移植,因此无法将主机目录映射到dockerfile中的docker容器目录,因为主机目录可能会根据您运行的计算机而更改。要将主机目录映射到docker容器目录,在使用docker run时需要使用-v
标志:
docker run -v /host/directory:/container/directory -other -options image_name command_to_run
答案 1 :(得分:143)
此问题的用户使用Docker version 0.9.1, build 867b2a9
,我将为您提供docker版本> = 17.06的答案。
通过安装类型为bind
的卷来完成所需的操作,使本地目录在容器目录中保持同步。这将绑定源(您的系统)和目标(在docker容器)目录。它与在linux上安装目录几乎相同。
According to Docker documentation,适当的挂载命令现在是mount
而不是-v
。这是其文档:
--mount
:由多个键值对组成,以逗号分隔。每个键/值对采用<key>=<value>
元组的形式。 --mount
语法比-v
或--volume
更详细,但键的顺序并不重要,标志的值更容易理解。
装载的type
,可以是bind
,volume
或tmpfs
。 (我们将使用 bind )
坐骑的source
。对于绑定装入,这是Docker守护程序主机上的文件或目录的路径。可以指定为source
或src
。
destination
将文件或目录将在容器中装入的路径作为其值。可以指定为destination
,dst
或target
。
因此,要使用/test_container
(目标)挂载当前目录(源),我们将使用:
docker run -it --mount src="$(pwd)",target=/test_container,type=bind k3_s3
如果这些挂载参数有空格,则必须在它们周围加上引号。当我知道他们不知道时,我会改用`pwd`
:
docker run -it --mount src=`pwd`,target=/test_container,type=bind k3_s3
您还必须处理文件权限,请参阅this article。
答案 2 :(得分:67)
连续2次坐骑: 我想这里的很多帖子可能都使用了两个boot2docker,你没有看到任何东西的原因是因为你从boot2docker安装了一个目录而不是你的主机。
你基本上需要2个连续的安装:第一个是从你的主机到你的系统安装一个目录,第二个是将boot2docker中的新目录安装到你的容器中,如下所示:
sudo mount -t vboxsf hostfolder /boot2dockerfolder
docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename
然后当你在容器文件夹中ls
时,你会看到你的文件夹内容。
答案 3 :(得分:52)
你可以使用cli中的-v选项,这个工具不能通过Dockerfile
获得 docker run -t -i -v <host_dir>:<container_dir> ubuntu /bin/bash
其中host_dir是要装入的主机的目录。 你不需要担心容器的目录,如果它不存在,docker会创建它。
如果您在host_dir中对主机进行任何更改(在root权限下),它将对容器可见,反之亦然。
答案 4 :(得分:32)
是否可以通过boot2docker
或类似的东西在OS X上使用docker。
我已经取得了相同的经验 - 命令是正确的,但无论如何都没有(明智的)安装在容器中。
事实证明 - 它已在docker documentation中解释过了。当您键入docker run -v /var/logs/on/host:/var/logs/in/container ...
时,/var/logs/on/host
实际上是从boot2docker
VM映像映射的,而不是您的Mac映射。
您必须通过VM将共享文件夹传输到您的实际主机(在我的情况下为Mac)。
答案 5 :(得分:26)
[更新] 截至2017年6月,Docker for Mac负责处理您必须弄乱VirtualBox的所有烦人部分。它允许您使用/private
前缀基本上映射本地主机上的所有内容。更多信息here。的 [/ UPDATE] 强>
所有当前的答案都谈到了Boot2docker。由于现在已经弃用了docker-machine,这适用于docker-machine:
首先,ssh进入docker-machine vm并创建我们要映射到的文件夹:
docker-machine ssh $MACHINE_NAME "sudo mkdir -p \"$VOL_DIR\""
现在将文件夹共享到VirtualBox:
WORKDIR=$(basename "$VOL_DIR")
vboxmanage sharedfolder add "$MACHINE_NAME" --name "$WORKDIR" --hostpath "$VOL_DIR" --transient
最后,再次ssh到docker-machine并挂载我们刚刚共享的文件夹:
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上测试的。
答案 6 :(得分:25)
我正在尝试让我的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
答案 7 :(得分:18)
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
标志时它会完美无瑕。
答案 8 :(得分:10)
2015年7月更新 - boot2docker现在支持直接安装。您可以直接在Mac提示符下使用-v /var/logs/on/host:/var/logs/in/container
,而无需双重安装
答案 9 :(得分:10)
我遇到了同样的问题。 我的命令行如下所示:
docker run --rm -i --name $NAME -v `pwd`:/sources:z $NAME
问题出在“ pwd”上。所以我将其更改为$(pwd):
docker run --rm -i --name $NAME -v $(pwd):/sources:z $NAME
答案 10 :(得分:8)
使用command-line
:
docker run -it --name <WHATEVER> -p <LOCAL_PORT>:<CONTAINER_PORT> -v <LOCAL_PATH>:<CONTAINER_PATH> -d <IMAGE>:<TAG>
使用docker-compose.yaml
:
version: '2'
services:
cms:
image: <IMAGE>:<TAG>
ports:
- <LOCAL_PORT>:<CONTAINER_PORT>
volumes:
- <LOCAL_PATH>:<CONTAINER_PATH>
假设:
示例:
$ mkdir -p /volume-to-mount
version: '2'
services:
cms:
image: ghost-cms:latest
ports:
- 8080:8080
volumes:
- /volume-to-mount:/mnt
docker exec -it CONTAINER_ID ls -la /mnt
答案 11 :(得分:6)
我发现在/var
,/usr
,/etc
等系统指令下的任何目录都无法安装在容器下。
指令应位于用户的空间-v
开关指示docker守护程序将本地目录挂载到容器,例如:
docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}
答案 12 :(得分:5)
从Docker 18-CE开始,您可以使用docker run -v /src/path:/container/path
对主机文件夹进行双向绑定。
如果您使用的是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设置中“共享驱动器”。
答案 13 :(得分:4)
boot2docker和VirtualBox Guest Additions
如何将/ Users挂载到boot2docker
tl; dr使用VirtualBox Guest构建您自己的自定义boot2docker.iso 添加(参见link)或下载 http://static.dockerfiles.io/boot2docker-v1.0.1-virtualbox-guest-additions-v4.3.12.iso 并将其保存到〜/ .boot2docker / boot2docker.iso。
答案 14 :(得分:4)
对于 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
然后进行测试,您可以在图像中进行echo TEST > hostTest.txt
。您应该能够在C:/Users/C/Desktop/dockerStorage/
的本地主机文件夹中看到此新文件。
答案 15 :(得分:4)
有同样的问题。在docker documentation:
中找到了这个注意:主机目录本质上是依赖于主机的。因此,您无法从Dockerfile安装主机目录,VOLUME指令不支持传递host-dir,因为构建的映像应该是可移植的。主机目录在所有潜在主机上都不可用。
因此,只有-v
命令中的docker run
参数才能安装读/写主机目录,因为其他答案指出正确。
答案 16 :(得分:4)
要使其在 Windows 10 中正常运行,我必须从系统托盘中打开Docker设置窗口,然后转到 Shared Drives 部分。
然后我选中了C
旁边的框。 Docker要求我的桌面凭据来获得授权写入我的Users文件夹。
然后,我按照上面的示例以及该设置页面上的示例运行了docker容器,并将其附加到容器中的/data
。
docker run -v c:/Users/<user.name>/Desktop/dockerStorage:/data -other -options
答案 17 :(得分:4)
如何将main_folder链接到docker容器中的test_container文件夹?
下面的命令是正确的,除非您在使用boot2docker的mac上(取决于将来的更新),在这种情况下您可能会发现该文件夹为空。有关纠正此问题的教程,请参阅mattes答案。
docker run -d -v /Users/kishore/main_folder:/test_container k3_s3:latest
我需要自动运行,如何在没有真正运行的情况下运行 使用run -d -v命令。
你真的无法使用这些命令,它们是docker工作方式所固有的。最好将它们放入shell脚本中以避免重复写入它们。
如果boot2docker崩溃会怎样? docker文件存储在哪里?
如果您设法使用-v arg并引用主机,那么这些文件在您的主机上是安全的。
如果您使用了#docker build -t myimage。&#39;使用Dockerfile,您的文件将被烘焙到图像中。
我认为您的泊坞窗图像存储在boot2docker-vm中。当我从VirtualBox中删除vm时,当我的图像消失时,我发现了这一点。 (注意,我不知道Virtualbox是如何工作的,所以图像可能仍然隐藏在其他地方,对于docker来说是不可见的。)
答案 18 :(得分:2)
请注意,在Windows中,您必须提供绝对路径。
以下为我工作。
docker run -t -i -v D:/projects/:/home/chankeypathak/work -p 8888:8888 jupyter/tensorflow-notebook /bin/bash
答案 19 :(得分:2)
以下是带有Windows路径的示例:
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路径复制到剪贴板,按键盘上的“ Apps Key”,并将其格式化为Docker欣赏的路径格式。 / p>
例如:
将此复制到剪贴板:
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
答案 20 :(得分:2)
如果主机是Windows 10,则不要使用正斜杠,而应使用反斜杠-
docker run -it -p 12001:80 -v c:\Users\C\Desktop\dockerStorage:/root/sketches
确保主机驱动器是共享的(在这种情况下为C)。在我的情况下,运行上述命令后,提示我询问共享权限。
答案 21 :(得分:2)
在Mac OS上,要在Mac上的容器根目录下挂载文件夹/Users/<name>/projects/
:
docker run -it -v /Users/<name>/projects/:/projects <container_name> bash
ls /projects
答案 22 :(得分:2)
您也可以使用Portainer Web应用程序执行此操作,以获得不同的视觉体验。
首先拉出Portainer图片:
docker pull portainer/portainer
然后为Portainer创建一个卷:
docker volume create portainer_data
还要创建一个Portainer容器:
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
您将可以使用浏览器通过以下URL访问网络应用:“ http://localhost:9000”。首次登录时,系统将提示您设置Portainer管理员凭据。
在网络应用中,请遵循以下菜单和按钮:(容器>添加容器> 填充设置>部署容器)
我在用Portainer创建“装载”卷时遇到了麻烦,我意识到在创建容器的卷时必须单击“绑定”。下面是对将容器绑定到主机上的已安装卷用于容器创建的卷绑定设置的说明。
P.S .:我正在使用Docker 19.035和Portainer 1.23.1
答案 23 :(得分:1)
我遇到了同样的问题,我试图在docker上安装C:\ Users \文件夹
这就是我如何做到的Docker Toolbox命令行
{{1}}
答案 24 :(得分:0)
对于那些想要在当前目录中挂载文件夹的人:
docker run -d --name some-container -v ${PWD}/folder:/var/folder ubuntu
答案 25 :(得分:0)
我对从容器挂载主机目录有相同的要求,并且我使用了volume mount命令。但是在测试过程中,它注意到它也在容器内创建文件,但是经过一番挖掘后发现它们只是符号链接,而实际文件系统是从主机使用的。