ChatGPT解决这个技术问题 Extra ChatGPT

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

描述

我通过 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 存在一个根本性的缺陷。该框架的全部意义在于充当开发人员的独立于平台的框架。您需要针对不同平台进行不同配置的事实反而破坏了该原则。

E
ETL

在 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

您的 CMD 示例是正确的并且效果很好! Power Shell 变体不起作用,尽管 $pwd.path 本身是正确的,但在脚本中使用时无法解析为正确的值:gist.github.com/McGo/8924cc5b0609f13c39092554a0bef183
${PWD} 也适用于 Unix 系统(Linux、macOS)。 注意pwd = 当前工作目录
@cjsimon 它实际上看起来可能有......似乎PowerShell支持$(pwd)这也可以在Linux上运行(我认为 - 未经测试)
对于 Git Bash,它可以是 winpty docker run -it -v "/$(pwd -W):/usr/src/project" gcc:4.9winpty docker run -it -v "/$(cmd //c cd):/usr/src/project" gcc:4.9
在 Windows 10 上不适合我,安装成功但目标目录为空
f
friism

这在 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'.
@mistalaba 如果您使用的是 Windows 10,请尝试使用 Docker for Windows 而不是 Toolbox
@finlay-roelofs 谢谢,但 Docker for Win 仅适用于 Win Pro。
E
Eugene Khyst

命令提示符 (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

P
Paulo Merson

打开 Docker 桌面上的设置(适用于 Windows 的 Docker)。选择共享驱动器。选择要在容器内使用的驱动器(例如 C)。单击应用。可能会要求您提供用户凭据。下面的命令现在应该可以在 PowerShell 上运行(命令提示符不支持 ${PWD}): docker run --rm -v ${PWD}:/data alpine ls /data

重要提示:如果/当您更改 Windows 域密码时,挂载将停止工作静默,也就是说,-v 将工作但容器不会< /strong> 查看您的主机文件夹和文件。 解决方案:返回设置,取消选中共享驱动器,应用,再次检查它们,应用,并在出现提示时输入新密码。


T
ToastedSoul

对于 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

从 cmder docker run -v 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
我做到了,包括反引号,并且使用 gitbash for windows 运行良好
我可以确认这适用于超级 gitbash 以及第一个选项
反引号是执行嵌入式命令的一种效率较低的方式。更好的方法是使用 $(command) 而不是 `command`
j
jseguillon

这是我的兼容 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

想评论并确认这是对 Windows Server 2012 上的 Docker Toolbox 的一百万美元答案!!!!很棒的工作!出于好奇,${MOUNT_PATH} 解析为 /c/Program Files/Docker Toolbox
t
tkit

其他人提供的其他 Git Bash 解决方案对我不起作用。显然,Windows 的 Git 目前存在错误/限制。请参阅 thisthis

在找到 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”
B
Blue Clouds

这个命令应该修复它。

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

{PWD} 是主机当前文件夹。 : 之后是容器文件夹。如果安装正确,则文件将列在容器的目录 c:\data 中。


K
Karl

您需要将所有反斜杠交换为正斜杠,以便更改

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

我的解决方案类似,但更短,可以直接在控制台中运行:set pwd=%cd:C:\=//c/% & set pwd=%pwd:\=/% docker run -v %pwd%: /app 阿尔卑斯山 ls /app
很好,我会借那个:-)
h
happyy

如果您在 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} 将不起作用


另外,请用英文写下您的解决方案的解释。这将有助于消除 StackOverflow 是免费代码编写服务的误解。