描述
我通过 Hyper-V 在 Windows 10 上使用 Docker 版本 1.12.5,并希望将容器可执行文件用作当前路径中的命令。我构建了一个运行良好的 Docker 映像,但是我在挂载当前路径时遇到了问题。这个想法是创建一个别名并执行 docker run --rm [...]
命令,以便它可以在当前目录中的系统范围内使用。
设置
我有一个带有文件夹“test”的驱动器 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 中将当前目录挂载为卷的正确语法是什么?
%cd%
或恢复为 PowerShell 而不是标准的 Windows 控制台。然而,它确实突出了一个事实,即 Docker 存在一个根本性的缺陷。该框架的全部意义在于充当开发人员的独立于平台的框架。您需要针对不同平台进行不同配置的事实反而破坏了该原则。
在 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
PS C:\Users\X\Projects\docker_django> docker run --rm -v ${PWD}:/data alpine ls /data C:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: invalid mode: /data. See 'C:\Program Files\Docker Toolbox\docker.exe run --help'.
Docker for Windows
而不是 Toolbox
。
命令提示符 (Cmd.exe)
从 Windows Cmd.exe
使用 Docker CLI 时,使用 %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 mounted volume adds ;C to end of windows path when translating from linux style path,挂载当前目录可能会失败。
通过前缀 / 转义 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
或外壳(系统)级别
export MSYS_NO_PATHCONV=1
touch test.txt
docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt
打开 Docker 桌面上的设置(适用于 Windows 的 Docker)。选择共享驱动器。选择要在容器内使用的驱动器(例如 C)。单击应用。可能会要求您提供用户凭据。下面的命令现在应该可以在 PowerShell 上运行(命令提示符不支持 ${PWD}): docker run --rm -v ${PWD}:/data alpine ls /data
重要提示:如果/当您更改 Windows 域密码时,挂载将停止工作静默,也就是说,-v
将工作但容器不会< /strong> 查看您的主机文件夹和文件。 解决方案:返回设置,取消选中共享驱动器,应用,再次检查它们,应用,并在出现提示时输入新密码。
对于 Windows 的 Git Bash(在 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: ..."
更新:以上适用于 Docker Windows 容器,对于 Linux 容器使用:
docker run --rm -it -v `pwd -W`:/api -p 8080:80 microsoft/aspnetcore:2
pwd -W
:/usr/share/data atomgraph/fuseki --file=/usr/share/data/Mokyklu_sarasas.ttl /mokyklos 对我不起作用 找不到文件:C:/tools/ cmder/vendor/git-for-windows/usr/share/data/Mokyklu_sarasas.ttl
`command`
这是我的兼容 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
${MOUNT_PATH}
解析为 /c/Program Files/Docker Toolbox
其他人提供的其他 Git Bash 解决方案对我不起作用。显然,Windows 的 Git 目前存在错误/限制。请参阅 this 和 this。
在找到 this GitHub thread 后,我终于设法让它工作(如果您有兴趣,它会提供一些额外的解决方案,这可能对您有用,但对我没有用)。
我最终使用了以下语法:
MSYS_NO_PATHCONV=1 docker run --rm -it -v $(pwd):/usr/src/project gcc:4.9
注意 docker
命令和 $(pwd)
前面的 MSYS_NO_PATHCONV=1
- 圆括号、小写密码、无引号、无反斜杠。
另外,如果这很重要,我会在 Windows 上使用 Linux 容器。
我在新的 Windows 终端、ConEmu 和 GitBash 中对此进行了测试,所有这些都为我工作。
MSYS_NO_PATHCONV=1
命令选项吗?否则我的目标挂载目录充满了“c:/tools/cmder/vendor/git-for-windows”
这个命令应该修复它。
docker run --rm -it -v ${PWD}:c:\data
mirkohaaser/docker-clitools
{PWD} 是主机当前文件夹。 :
之后是容器文件夹。如果安装正确,则文件将列在容器的目录 c:\data
中。
您需要将所有反斜杠交换为正斜杠,以便更改
docker -v C:\my\folder:/mountlocation ...
至
docker -v C:/my/folder:/mountlocation ...
我通常从 cmd 脚本调用 docker,在该脚本中我希望要挂载的文件夹与我正在调用的脚本相关,所以在该脚本中我这样做...
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
如果您在 2022 年仍然遇到此问题,您可以使用 WSL(适用于 Linux 的 Windows 子系统)在 windows 中安装 docker。然后你可以去微软商店安装一个 Linux 项目,比如 Ubuntu、Debian 或 Kali Linux。
在 Docker 桌面上,转到设置 -> WSL 集成并启用您的 Linux 版本。
在 VS Code 上打开新的 WSL 终端并在那里执行 Linux 命令。
docker run --rm -v /c/Users/Christian/manager/bin:/app --workdir=/app php:7.2-cli php app.php
重击
cd /c/Users/Christian/manager
docker run --rm -v ${PWD}:/app --workdir=/app php:7.2-cli php bin/app.php
echo ${PWD}
结果:
/c/Users/Christian/经理
cmd 或 PowerShell
cd C:\Users\Christian\manager
echo ${PWD}
结果:
路径 ---- C:\Users\Christian\manager
正如我们在 cmd 或 PowerShell 中看到的 $ {PWD} 将不起作用
不定期副业成功案例分享
${PWD}
也适用于 Unix 系统(Linux、macOS)。 注意:pwd
= 当前工作目录$(pwd)
这也可以在Linux上运行(我认为 - 未经测试)winpty docker run -it -v "/$(pwd -W):/usr/src/project" gcc:4.9
或winpty docker run -it -v "/$(cmd //c cd):/usr/src/project" gcc:4.9
。