在Windows 10的Docker中将当前目录挂载为卷

描述

我通过Hyper-V在Windows 10上使用Docker 1.12.5版本,并希望在当前路径中使用容器可执行文件作为命令。我构建了一个运行正常的Docker映像,但在挂载当前路径时遇到了一个问题。其思想是创建一个别名并执行docker run --rm [...]命令,以便它可以在当前目录中在系统范围内使用。

设置

我有一个驱动器E的文件夹“测试”,在那里有一个文件夹称为“文件夹上的windows主机”,以显示该命令正在工作。Dockerfile创建目录/data,并将其定义为VOLUME和WORKDIR。

E:\test作为PowerShell中的当前目录,并使用绝对路径执行Docker命令,我可以看到E:\test的内容:

PS E:\test> docker run --rm -it -v E:\test:/data mirkohaaser/docker-clitools ls -la
total 0
drwxr-xr-x 2 root root 0 Jan  4 11:45 .
drwxr-xr-x 2 root root 0 Jan  5 12:17 folder on windows host

问题

我想使用当前目录,而不是绝对符号。由于不同的错误消息,我无法在卷中使用pwd:

尝试使用($pwd)

PS E:\test> docker run --rm -it -v ($pwd):/data mirkohaaser/docker-clitools ls -la
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error parsing reference: ":/data" is not a valid repository/tag.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

尝试使用/($pwd)

PS E:\test> docker run --rm -it -v /($pwd):/data mirkohaaser/docker-clitools ls -la
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error parsing reference: "E:\\test" is not a valid repository/tag.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

尝试用\´pwd\´

PS E:\test> docker run --rm -it -v ´$pwd´:/data mirkohaaser/docker-clitools ls -la
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Invalid bind mount spec "´E:\\test´:/data": invalid mode: /data.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

尝试使用" pwd "

PS E:\test> docker run --rm -it -v `$pwd`:/data mirkohaaser/docker-clitools ls -la
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: create $pwd: "$pwd" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

在Windows 10的Docker中将当前目录挂载为卷的正确语法是什么?

341046 次浏览

在Windows命令行(cmd)中,你可以像这样挂载当前目录:

docker run --rm -it -v %cd%:/usr/src/project gcc:4.9

在PowerShell中,你使用${PWD},它会给你当前目录:

docker run --rm -it -v ${PWD}:/usr/src/project gcc:4.9

在Linux上:

docker run --rm -it -v $(pwd):/usr/src/project gcc:4.9

跨平台的

以下选项将在PowerShell和Linux(至少Ubuntu)上工作:

docker run --rm -it -v ${PWD}:/usr/src/project gcc:4.9
docker run --rm -it -v $(pwd):/usr/src/project gcc:4.9

这适用于我在PowerShell:

docker run --rm -v ${PWD}:/data alpine ls /data

这个命令应该可以解决这个问题。

docker run——rm -it -v ${PWD}:c:\data mirkohaaser/docker-clitools

{PWD}是主机当前文件夹。:后面是容器文件夹。 如果挂载是正确的,那么文件将被列在容器中的c:\data目录中。< / p >

你需要把所有的后斜杠换成正斜杠 所以改变< / p >

C:\my\folder:/mountlocation…

C:/my/folder:/mountlocation…

我通常调用docker从一个cmd脚本,我想文件夹挂载相对于脚本,我正在调用,所以在该脚本中,我这样做…

SETLOCAL


REM capture the path to this file so we can call on relative scrips
REM without having to be in this dir to do it.


REM capture the path to $0 ie this script
set mypath=%~dp0


REM strip last char
set PREFIXPATH=%mypath:~0,-1%


echo "PREFIXPATH=%PREFIXPATH%"
mkdir -p %PREFIXPATH%\my\folder\to\mount


REM swap \ for / in the path
REM because docker likes it that way in volume mounting
set PPATH=%PREFIXPATH:\=/%
echo "PPATH=%PPATH%"


REM pass all args to this script to the docker command line with %*
docker run --name mycontainername --rm -v %PPATH%/my/folder/to/mount:/some/mountpoint  myimage %*


ENDLOCAL

对于Git Bash For Windows(在ConEmu中),以下对我来说是有效的(对于Docker Windows容器):

docker run --rm -it -v `pwd -W`:c:/api microsoft/dotnet:2-runtime

注意pwd -W周围的引号/反 !

与所有其他PWD的变化,我已经尝试过,我收到:"Error response from daemon: invalid volume specification: ..."

< p >更新: 以上是Docker Windows容器,Linux容器使用:

docker run --rm -it -v `pwd -W`:/api -p 8080:80 microsoft/aspnetcore:2

下面是我的,它兼容Win10 docker-ce &Win7 docker-toolbox。最后在我写这篇文章的时候:)。

你可以注意到我更喜欢使用/host_mnt/c而不是c:/,因为我有时在docker-ce Win 10上使用c:/时会遇到麻烦

$WIN_PATH=Convert-Path .


#Convert for docker mount to be OK on Windows10 and Windows 7 Powershell
#Exact conversion is : remove the ":" symbol, replace all "\" by "/", remove last "/" and minor case only the disk letter
#Then for Windows10, add a /host_mnt/" at the begin of string => this way : c:\Users is translated to /host_mnt/c/Users
#For Windows7, add "//" => c:\Users is translated to //c/Users
$MOUNT_PATH=(($WIN_PATH -replace "\\","/") -replace ":","").Trim("/")


[regex]$regex='^[a-zA-Z]/'
$MOUNT_PATH=$regex.Replace($MOUNT_PATH, {$args[0].Value.ToLower()})


#Win 10
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 10,0)) {
$MOUNT_PATH="/host_mnt/$MOUNT_PATH"
}
elseif ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,1)) {
$MOUNT_PATH="//$MOUNT_PATH"
}


docker run -it -v "${MOUNT_PATH}:/tmp/test" busybox ls /tmp/test
  1. 在Docker Desktop上打开设置 (Docker for Windows)。
  2. 选择共享驱动器
  3. 选择要在容器中使用的驱动器(例如,C)。
  4. <李> < p >单击应用。您可能会被要求提供用户凭证。 李为Windows上的容器启用驱动器 < / p > < / >
  5. 下面的命令现在应该在PowerShell上工作(命令提示符不支持${PWD}):

    docker run --rm -v ${PWD}:/data alpine ls /data < / p >

重要的:如果/当你修改你的Windows域密码时,挂载将停止工作默默地,也就是说,-v将工作,但容器不会看到你的主机文件夹和文件。解决方案:返回“设置”,取消勾选共享驱动器,应用,再次勾选共享驱动器,应用,并根据提示输入新密码。

docker run --rm -v /c/Users/Christian/manager/bin:/app --workdir=/app  php:7.2-cli php  app.php

Git bash

 cd /c/Users/Christian/manager
docker run --rm -v  ${PWD}:/app  --workdir=/app  php:7.2-cli php  bin/app.php
< p > echo ${PWD} 结果:< / p >

/ c /用户/基督教/经理

cmdPowerShell

  cd C:\Users\Christian\manager
< p > echo ${PWD} 结果:< / p >
< p >路径 ——C:\Users\Christian\经理< / p >

正如我们在cmdPowerShell $ {PWD}中看到的那样,将不起作用

其他人为Git Bash提供的其他解决方案对我不起作用。显然,Git for Windows目前有一个bug/限制。参见

我终于设法让它在找到这个GitHub线程后工作(它提供了一些额外的解决方案,如果你感兴趣,这可能对你有用,但对我没有)。

我最终使用以下语法:

MSYS_NO_PATHCONV=1 docker run --rm -it -v $(pwd):/usr/src/project gcc:4.9

注意docker命令前面的MSYS_NO_PATHCONV=1$(pwd) -圆括号,小写pwd,没有引号,没有反斜杠。

此外,我在Windows上使用Linux容器,如果这很重要。

我在新的Windows终端、ConEmu和giitbash中测试了这个功能,它们都很适合我。

命令提示符(Cmd.exe)

当从Windows Cmd.exe使用Docker命令行时,使用%cd%挂载当前目录:

echo test > test.txt
docker run --rm -v %cd%:/data busybox ls -ls /data/test.txt

Git Bash (MinGW)

当从Git Bash (MinGW)使用Docker CLI时,由于POSIX路径转换:Docker挂载卷添加;C到windows路径的结束时,从linux风格的路径翻译,挂载当前目录可能会失败。

通过前缀/转义POSIX路径

要跳过路径转换,POSIX路径必须以斜杠(/)作为前缀,以具有前导双斜杠(//),包括/$(pwd)

touch test.txt
docker run --rm -v /$(pwd):/data busybox ls -la //data/test.txt

禁用路径转换

通过在命令级别设置MSYS_NO_PATHCONV=1环境变量,禁用Git Bash (MinGW)中的POSIX路径转换

touch test.txt
MSYS_NO_PATHCONV=1 docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt

或shell(系统)级

export MSYS_NO_PATHCONV=1
touch test.txt
docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt

如果你在2022年仍然有这个问题,你可以在带有WSL(windows Subsystem for Linux)的windows中安装docker。然后你可以去微软商店安装一个Linux项目,比如Ubuntu, Debian或Kali Linux。

在Docker Desktop上执行->WSL集成

.打开你的Linux版本

在VS Code上打开新的WSL终端并在那里执行Linux命令。

如果你想将带有DockerfileRunArguments属性的项目目录传递给调试容器,那么pwd将不起作用。

<PropertyGroup>
<!-- Will result in `` -->
<DockerfileRunArguments>-v "$(pwd):/data:ro"</DockerfileRunArguments>
</PropertyGroup>

使用$(MSBuildProjectDirectory)代替$(pwd)

<PropertyGroup>
<!-- Will result in the full path to your project directory -->
<DockerfileRunArguments>-v "$(MSBuildProjectDirectory):/data:ro"</DockerfileRunArguments>
</PropertyGroup>

参考:MSDocs - Visual Studio容器工具