我正在尝试将主机目录挂载到 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"]
kishore$ tree
.
├── Dockerfile
└── main_folder
├── tfile1.txt
├── tfile2.txt
├── tfile3.txt
└── tfile4.txt
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
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 ..
kishore$ docker -v
Docker version 0.9.1, build 867b2a9
我不知道如何检查 boot2docker 版本
问题,面临的问题:
我如何需要将 main_folder 链接到 docker 容器内的 test_container 文件夹?我需要自动做到这一点。在不真正使用 run -d -v 命令的情况下如何做到这一点?如果 boot2docker 崩溃了怎么办? Docker 文件存储在哪里(Dockerfile 除外)?
有几种方法可以做到这一点。最简单的方法是使用 dockerfile ADD
命令,如下所示:
ADD . /path/inside/docker/container
但是,在构建 dockerfile 后对主机上的此目录所做的任何更改都不会显示在容器中。这是因为在构建容器时,docker 会将目录压缩为 .tar
并将该 context 永久上传到容器中。
第二种方法是您尝试的方式,即挂载卷。由于试图尽可能便携,您不能将主机目录映射到 dockerfile 中的 docker 容器目录,因为主机目录可能会根据您运行的机器而改变。要将主机目录映射到 docker 容器目录,您需要在使用 docker run
时使用 -v
标志,例如:
# Run a container using the `alpine` image, mount the `/tmp`
# directory from your host into the `/container/directory`
# directory in your container, and run the `ls` command to
# show the contents of that directory.
docker run \
-v /tmp:/container/directory \
alpine \
ls /container/directory
这个问题的用户使用的是Docker version 0.9.1, build 867b2a9
,我会给你一个 docker version >= 17.06 的答案。
你想要的,保持本地目录在容器目录中同步,是通过挂载类型为 bind
的卷来完成的。这将绑定源(您的系统)和目标(在 docker 容器中)目录。这几乎与在linux上挂载目录相同。
According to Docker documentation,现在要挂载的适当命令是 mount
而不是 -v
。这是它的文档:
--mount:由多个键值对组成,以逗号分隔。每个键/值对都采用
挂载类型,可以是 bind、volume 或 tmpfs。 (我们将使用绑定)
坐骑的来源。对于绑定挂载,这是 Docker 守护程序主机上文件或目录的路径。可以指定为 source 或 src。
目标将文件或目录安装在容器中的路径作为其值。可以指定为目的地、dst 或目标。
因此,要使用 /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。
您可以使用 cli 中的 -v 选项,此功能无法通过 Dockerfile 获得
docker run -t -i -v <host_dir>:<container_dir> ubuntu /bin/bash
其中 host_dir 是您要挂载的主机目录。如果容器目录不存在,您无需担心容器目录,docker 会创建它。
如果您从主机(在 root 权限下)对 host_dir 进行任何更改,它将对容器可见,反之亦然。
docker run -t -i -v /tmp:/tmp ubuntu /bin/bash
,其中主机 /tmp
将安装在容器 /tmp
上。现在可以从容器中touch /tmp/hello-world
看到文件出现在主机上。
2 次连续挂载:我猜这里的许多帖子可能使用了两个 boot2docker,您看不到任何内容的原因是您正在从 boot2docker 挂载一个目录,而不是从您的主机上挂载。
你基本上需要2个连续的坐骑:
第一个将目录从主机挂载到系统,第二个将新目录从 boot2docker 挂载到容器,如下所示:
1) 在 boot2docker 上挂载本地系统 sudo mount -t vboxsf hostfolder /boot2dockerfolder
2)在linux容器上挂载boot2docker文件 docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename
然后,当您在 containerfolder
中ls
时,您将看到 hostfolder
的内容。
net share
命令一起出现的命令。而且您必须将该文件夹添加为 virtualBox GUI 的共享文件夹(如果您按照我的逻辑使用相同的名称)。如果你不分享它,它会起作用,但你会面临权限和刷新性能的问题。
mount: unknown filesystem type 'vboxsf'
,使用 ubuntu 来宾和主机
您是否可以通过 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)。
我只是在尝试让我的 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
[更新] 自 2017 年 6 月起,Docker for Mac 会处理您必须与 VirtualBox 搞混的所有烦人部分。它允许您使用 /private
前缀基本上映射本地主机上的所有内容。更多信息here。 [/更新]
当前所有答案都在谈论 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 开始测试的。
docker-machine
文档的一部分。
-v
标志?
-v
标志不像您在 OS X(或 Windows)中所期望的那样工作。 Docker 在 VM 中运行,因此 -v
中引用的文件夹指向 VM 中的文件夹,而不是根操作系统中的文件夹。该技术将 VM 文件夹映射回根操作系统的下一步。
/Users
以共享到 docker。这意味着如果您的工作文件在 ~/*
中,那么您就可以开始了。如果您的开发环境设置用完 /development
或 /Users
以外的任何内容,您将遇到问题 docs.docker.com/engine/userguide/containers/dockervolumes
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
标志时,它可以完美运行。
在 Mac OS 上,要将文件夹 /Users/<name>/projects/
挂载到容器根目录的 Mac 上:
docker run -it -v /Users/<name>/projects/:/projects <container_name> bash
ls /projects
使用 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>
认为 :
图片:k3_s3
标签: 最新
本地端口:8080
容器端口:8080
LOCAL_PATH: /volume-to-mount
CONTAINER_PATH: /mnt
例子 :
首先创建 /volume-to-mount。 (如果有则跳过)
$ mkdir -p /volume-to-mount
docker-compose -f docker-compose.yaml up -d
version: '2'
services:
cms:
image: ghost-cms:latest
ports:
- 8080:8080
volumes:
- /volume-to-mount:/mnt
验证您的容器:
docker exec -it CONTAINER_ID ls -la /mnt
对于那些想要在当前目录中挂载文件夹的人:
docker run -d --name some-container -v ${PWD}/folder:/var/folder ubuntu
Docker version 20.10.14
,仅此而已。谢谢!
如果主机是 Windows 10,则不要使用正斜杠,而是使用反斜杠 -
docker run -it -p 12001:80 -v c:\Users\C\Desktop\dockerStorage:/root/sketches
确保主驱动器是共享的(在本例中为 C)。就我而言,在运行上面的命令后,我收到了询问共享权限的提示。
对于 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/
的本地主机文件夹中看到这个新文件。
-v $(pwd):/var/xx
并且确实有效,但结果是一个空目录。我正在通过 babun 运行 cyg。
从 Docker 18-CE 开始,您可以使用 docker run -v /src/path:/container/path
对主机文件夹进行双向绑定。
但是,如果您使用的是 Windows 10/WSL,并且将 Docker-CE for Windows 作为您的主机,然后在 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 设置中“共享驱动器”。
/c/projectpath
运行,但随后出现错误 bind mount source path does not exist: /host_mnt/c/projectpath
。
2015 年 7 月更新 - boot2docker 现在支持直接挂载。您可以直接在 Mac 提示符下使用 -v /var/logs/on/host:/var/logs/in/container
,无需双重安装
我一直有同样的问题。我的命令行如下所示:
docker run --rm -i --name $NAME -v `pwd`:/sources:z $NAME
问题出在“密码”上。所以我把它改成了 $(pwd):
docker run --rm -i --name $NAME -v $(pwd):/sources:z $NAME
z
有什么用?
如何将 main_folder 链接到 docker 容器内的 test_container 文件夹?
您下面的命令是正确的,除非您在使用 boot2docker 的 Mac 上(取决于将来的更新),在这种情况下您可能会发现文件夹为空。有关更正此问题的教程,请参阅 mattes answer。
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 中删除 vm 时,我的图像消失了,我发现了这一点。 (注意,我不知道 Virtualbox 是如何工作的,所以图像可能仍然隐藏在其他地方,只是对 docker 不可见)。
有同样的问题。在 docker documentation 中找到了这个:
注意:主机目录本质上是依赖于主机的。出于这个原因,您不能从 Dockerfile 挂载主机目录,VOLUME 指令不支持传递主机目录,因为构建的图像应该是可移植的。主机目录不会在所有潜在主机上都可用。
因此,只能使用 docker run
命令中的 -v
参数安装读/写主机目录,正如其他答案正确指出的那样。
我发现像 /var
、/usr
、/etc
这样的系统指令下的任何目录都无法安装在容器下。
该指令应该在用户空间 -v
开关指示 docker daemon 将本地目录挂载到容器,例如:
docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}
这是一个带有 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 路径复制到剪贴板,按键盘上的“应用程序键”,它会将其格式化为 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
为了让它在 Windows 10 中运行,我必须从系统托盘打开 Docker 设置窗口并转到共享驱动器部分。
然后我选中了 C
旁边的框。 Docker 要求我提供桌面凭据以获得写入我的用户文件夹的授权。
然后我按照上面的示例以及该设置页面上的示例运行 docker 容器,并附加到容器中的 /data
。
docker run -v c:/Users/<user.name>/Desktop/dockerStorage:/data -other -options
boot2docker 与 VirtualBox Guest Additions 如何将 /Users 挂载到 boot2docker
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。
请注意,在 Windows 中,您必须提供绝对路径。
主机:Windows 10
容器:TensorFlow Notebook
下面为我工作。
docker run -t -i -v D:/projects/:/home/chankeypathak/work -p 8888:8888 jupyter/tensorflow-notebook /bin/bash
我有同样的问题,我试图在 docker 上挂载 C:\Users\ 文件夹,这就是我的做法 Docker Toolbox 命令行
$ docker run -it --name <containername> -v /c/Users:/myVolData <imagename>
您也可以使用 Portainer 网络应用程序来实现这一点,以获得不同的视觉体验。
首先拉取 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 访问 Web 应用程序:“http://localhost:9000”。首次登录时,系统会提示您设置 Portainer 管理员凭据。
在 Web 应用程序中,按照以下菜单和按钮操作:(容器 > 添加容器 > 填充设置 > 部署容器)
我在使用 Portainer 创建“挂载”卷时遇到了麻烦,我意识到在创建容器卷时我必须单击“绑定”。下面是卷绑定设置的图示,该设置适用于我的容器创建,其中已安装卷绑定到主机。
https://i.stack.imgur.com/GXXeb.png
PS:我使用的是 Docker 19.035 和 Portainer 1.23.1
我有从容器挂载主机目录的相同要求,我使用了卷挂载命令。但是在测试过程中注意到它也在容器内创建文件但是经过一些挖掘发现它们只是符号链接和实际使用的文件系统来自主机。
ADD
实际上不是“挂载”,而是将文件复制到容器中,将其持久保存在其中。