如何在Docker容器中挂载主机目录

我正在尝试将主机目录挂载到Docker容器中,以便在主机上完成的任何更新都反映到Docker容器中。

我哪里做错了。这是我做的:

kishore$ cat Dockerfile
FROM ubuntu:trustyRUN apt-get updateRUN apt-get -y install git curl vimCMD ["/bin/bash"]WORKDIR /test_containerVOLUME ["/test_container"]

kishore$tree.──Dockerfile──main_folder──tfile1.txt──tfile2.txt──tfile3.txttfile4.txt

1个目录,5个文件kishore$pwd/Users/kishore/tdock

kishore$docker build--tag=k3_s3:最新。

Uploading context 7.168 kBUploading contextStep 0 : FROM ubuntu:trusty---> 99ec81b80c55Step 1 : RUN apt-get update---> Using cache---> 1c7282005040Step 2 : RUN apt-get -y install git curl vim---> Using cache---> aed48634e300Step 3 : CMD ["/bin/bash"]---> Running in d081b576878d---> 65db8df48595Step 4 : WORKDIR /test_container---> Running in 5b8d2ccd719d---> 250369b30e1fStep 5 : VOLUME ["/test_container"]---> Running in 72ca332d9809---> 163deb2b1bc5Successfully built 163deb2b1bc5Removing intermediate container b8bfcb071441Removing intermediate container d081b576878dRemoving intermediate container 5b8d2ccd719dRemoving intermediate container 72ca332d9809

docker run-d-v /Users/kishore/main_folder:/test_containerk3_s3:最新c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea

kishore$docker run-i-tk3_s3:最新 /bin/bash

root@0f17e2313a46:/test_container# ls -altotal 8drwx------  2 root root 4096 Apr 29 05:15 .drwxr-xr-x 66 root root 4096 Apr 29 05:15 ..

root@0f17e2313a46:/test_container#退出退出kishore$docker-vDocker版本0.9.1,构建867b2a9

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

问题,面临的问题:

  1. 如何将main_folder链接到docker容器内的test_container文件夹?
  2. 我需要自动执行此操作。如何在不使用run -d -v命令的情况下执行此操作?
  3. 如果boot2docker崩溃会发生什么?Docker文件存储在哪里(除了Dockerfile)?
1362851 次浏览

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

ADD . /path/inside/docker/container

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

第二种方法是您尝试的方法,即挂载一个卷。由于尝试尽可能便携,您无法将主机目录映射到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

您是否可能通过boot2docker或类似的方式在OS X上使用docker。

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

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

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

boot2docker与VirtualBox访客添加
如何将 /Users安装到boot2docker

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

tl; dr使用VirtualBox来宾构建您自己的自定义boot2docker.iso添加(见链接)或下载http://static.dockerfiles.io/boot2docker-v1.0.1-virtualbox-guest-additions-v4.3.12.iso并保存到~/. boot2docker/boot2docker.iso.

您可以使用cli中的-v选项,此功能无法通过Dockerfile获得

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

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

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

如何将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工作方式的内在特性。你最好把它们放入外壳脚本中,以节省你反复编写它们。

如果boot2docker崩溃会发生什么?docker文件存储在哪里?

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

如果您使用了“docker build-t myimage.”和Dockerfile,那么您的文件将被烘焙到映像中。

我相信你的docker映像存储在boot2docker-vm中。当我从VirtualBox中删除vm时,我的映像消失了,我发现了这一点。(注意,我不知道Virtualbox是如何工作的,所以映像可能仍然隐藏在其他地方,只是Docker不可见)。

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

你基本上需要两个连续的坐骑:

第一个将目录从您的主机挂载到您的系统的

第二个将新目录从boot2docker挂载到您的容器中,如下所示:

  • 1)在boot2docker上挂载本地系统

    sudo mount -t vboxsf hostfolder /boot2dockerfolder
  • 2) Mount boot2docker file on linux container

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

Then when you ls inside the containerfolder you will see the content of your hostfolder.

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

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

所有当前的答案都在谈论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机器并挂载我们刚刚共享的文件夹:

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应用程序:

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

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

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

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

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标志时,它可以完美地工作。

我发现系统指令下的任何目录(如/var/usr/etc)都无法挂载到容器下。

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

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

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

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

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

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

  • 挂载的type,可以是bindvolumetmpfs(我们将使用bind

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

  • destination将文件或目录将挂载在容器中的路径作为其值。可以指定为destinationdsttarget

因此,要使用/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

您还必须处理文件权限,请参阅这篇文章

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

从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设置中“共享驱动器”。

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

下面为我工作。

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

我有同样的问题,我试图在docker上挂载C:\用户\文件夹
我就是这样做的Docker Toolbox命令行

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

对于Windows10用户,将挂载点放在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/的本地主机文件夹中看到这个新文件。

我也遇到了同样的问题。我的命令行看起来像这样:

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

问题出在'pwd'上。所以我将其更改为$(pwd):

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

这是一个带有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欣赏的路径格式。

例如:

将其复制到剪贴板:

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.;; --------------------------------------------------------------------------------------------------------------
#NoEnvSendMode InputSetWorkingDir %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 colonNewStr := StrReplace(NewStr, SubStr(NewStr, 1, 2), tmpVar)
; Replace backslashes with forward slashesNewStr := StrReplace(NewStr,  "\", "/")
; Replace all colons with nothingNewStr := StrReplace(NewStr, ":", "")
; Remove the last char if it's a trailing forward slashNewStr :=  RegExReplace(NewStr, "/$")
; Append a leading forward slash if not already thereif RegExMatch(NewStr, "^/") == 0NewStr :=  "/" . NewStr
; If there are any spaces in the path ... wrap in double quotesif RegExMatch(NewStr, " ") > 0NewStr :=  """" . NewStr . """"
; Send the result to the active windowSendInput % NewStr

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

docker run -it -p 12001:80 -v c:\Users\C\Desktop\dockerStorage:/root/sketches

确保主机驱动器是共享的(在这种情况下是C)。在我的情况下,我在运行上面的命令后收到了一个要求共享权限的提示。

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

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

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

docker run -v c:/Users/<user.name>/Desktop/dockerStorage:/data -other -options

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

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

ls /projects

您也可以使用波特 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”访问Web应用程序。首次登录时,系统将提示您设置Portainer管理员凭据。

在Web应用程序中,按照以下菜单和按钮操作:(容器>添加容器>填充设置>部署容器)

我在使用Portainer创建“挂载”卷时遇到了麻烦,我意识到在创建容器卷时必须单击“绑定”。下面是用于创建绑定到主机的挂载卷的容器的卷绑定设置的示例。

卷绑定设置

附注:我正在使用Docker 19.035和Portainer 1.23.1

使用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
  • 标签:最新
  • LOCAL_PORT:8080
  • CONTAINER_PORT:8080
  • LOCAL_PATH: /volume-to-mount
  • CONTAINER_PATH: /mnt

示例:

  1. 首先创建 /volume-to-mount.(如果存在,跳过)
$ mkdir -p /volume-to-mount
  1. docker-compose-fdocker-compose.yaml-d
version: '2'services:cms:image: ghost-cms:latestports:- 8080:8080volumes:- /volume-to-mount:/mnt
  1. 验证您的容器:
docker exec -it CONTAINER_ID ls -la /mnt

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

docker run -d --name some-container -v ${PWD}/folder:/var/folder ubuntu

引用官网

  1. 确保您没有运行任何以前的入门容器。

  2. 从应用目录运行以下命令。

  • x86-64 Mac或Linux设备:

    docker run-dp 3000:3000\/运行时间

    -w /app-v"$(pwd):/app"\

    节点:12-高山\

    sh-c"纱线安装&&纱线运行开发"

  • Windows(PowerShell):

    docker run-dp 3000:3000'运行环境

    -w /app-v"$(pwd):/app"'

    节点:12-高山'

    sh-c"纱线安装&&纱线运行开发"

  • 使用硅Mac或其他ARM64设备:

    docker run-dp 3000:3000\/运行时间

    -w /app-v"$(pwd):/app"\

    节点:12-高山\

    sh-c"apk add--no-ache python2 g++make&&arn install&&arn run dev"

解释:

  • DP 3000:3000-和以前一样。在分离(后台)模式下运行并创建端口映射
  • W /app-设置“工作目录”或命令运行的当前目录
  • v"$(pwd):/app"-将当前目录从主机绑定到容器中的 /app目录
  • 节点:12-高山-要使用的图像。

请注意,这是我们应用程序的基本映像,来自Dockerfile sh-c“ar n install&&ar n run dev”-命令。

我们使用sh(alpine没有bash)启动一个shell并运行worn install来安装所有依赖项,然后运行worn run dev。如果我们查看package.json,我们会看到开发脚本正在启动no的。