ChatGPT解决这个技术问题 Extra ChatGPT

Mount current directory as a volume in Docker on Windows 10

Description

I am using Docker version 1.12.5 on Windows 10 via Hyper-V and want to use container executables as commands in the current path. I built a Docker image that is running fine, but I have a problem to mount the current path. The idea is to create an alias and do a docker run --rm [...] command so that it could be used system-wide in the current directory.

Setup

I have a drive E with a folder "test" and in there a folder called "folder on windows host" to show that the command is working. The Dockerfile create the directory /data, defines it as VOLUME and WORKDIR.

Having E:\test as the current directory in PowerShell and executing the Docker command with an absolute path, I can see the content of 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

Problem

I want to use the current directory and not an absolute notation. I could not use pwd in the volume because of different error messages:

Trying with ($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'.

Trying with /($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'.

Trying with \´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'.

Trying with `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'.

What is the correct syntax of mounting the current directory as a volume in Docker on Windows 10?

As described by others, the solution is either to use %cd% or to revert to PowerShell rather than standard windows console. However, it does highlight the fact that there is a fundamental shortcoming in Docker. The whole point of the framework is to act as a platform-independent framework for developers. The fact that you need different configurations for different platforms, rather undermines that principle.

E
ETL

In Windows Command Line (cmd), you can mount the current directory like so:

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

In PowerShell, you use ${PWD}, which gives you the current directory:

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

On Linux:

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

Cross Platform

The following options will work on both PowerShell and on Linux (at least 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

Your example for CMD is correct and works great! The Power Shell variant does not work, although $pwd.path itself is correct, it is not resolved to the correct value when used in the script: gist.github.com/McGo/8924cc5b0609f13c39092554a0bef183
${PWD} works on Unix systems too (Linux, macOS). Note: pwd = present working directory
@cjsimon It actually looks like there may be... seems like PowerShell supports $(pwd) which would also work on Linux (I think - untested)
With Git Bash it can be either winpty docker run -it -v "/$(pwd -W):/usr/src/project" gcc:4.9 or winpty docker run -it -v "/$(cmd //c cd):/usr/src/project" gcc:4.9.
not working for me on windows 10, mounting success but target directory are empty
f
friism

This works for me in PowerShell:

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

Is this still valid? I get the following when trying: 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 If you're using Windows 10, try using Docker for Windows instead of Toolbox.
@finlay-roelofs Thanks, but Docker for Win only works with Win Pro.
E
Eugene Khyst

Command prompt (Cmd.exe)

When the Docker CLI is used from the Windows Cmd.exe, use %cd% to mount the current directory:

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

Git Bash (MinGW)

When the Docker CLI is used from the Git Bash (MinGW), mounting the current directory may fail due to a POSIX path conversion: Docker mounted volume adds ;C to end of windows path when translating from linux style path.

Escape the POSIX paths by prefixing with /

To skip the path conversion, POSIX paths have to be prefixed with the slash (/) to have leading double slash (//), including /$(pwd)

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

Disable the path conversion

Disable the POSIX path conversion in Git Bash (MinGW) by setting MSYS_NO_PATHCONV=1 environment variable at the command level

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

or shell (system) level

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

P
Paulo Merson

Open Settings on Docker Desktop (Docker for Windows). Select Shared Drives. Select the drive that you want to use inside your containers (e.g., C). Click Apply. You may be asked to provide user credentials. The command below should now work on PowerShell (command prompt does not support ${PWD}): docker run --rm -v ${PWD}:/data alpine ls /data

IMPORTANT: if/when you change your Windows domain password, the mount will stop working silently, that is, -v will work but the container will not see your host folders and files. Solution: go back to Settings, uncheck the shared drives, Apply, check them again, Apply, and enter the new password when prompted.


T
ToastedSoul

For Git Bash for Windows (in ConEmu), the following works for me (for Docker Windows containers):

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

Note the backticks/backquotes around pwd -W!

With all other variations of PWD I've tried I've received: "Error response from daemon: invalid volume specification: ..."

Update: The above was for Docker Windows containers, for Linux containers use:

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

Didn't work for me from cmder docker run -v pwd -W:/usr/share/data atomgraph/fuseki --file=/usr/share/data/Mokyklu_sarasas.ttl /mokyklos File not found: C:/tools/cmder/vendor/git-for-windows/usr/share/data/Mokyklu_sarasas.ttl
I did, including the backticks, and it worked fine using gitbash for windows
I can confirm that this works with hyper gitbash as well on first option
The backticks are a less efficient way of executing an embedded command. The better way is to use $(command) rather than `command`
j
jseguillon

Here is mine which is compatible for both Win10 docker-ce & Win7 docker-toolbox. At las at the time I'm writing this :).

You can notice I prefer use /host_mnt/c instead of c:/ because I sometimes encountered trouble on docker-ce Win 10 with 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

Would like to comment and confirm that this is a million dollar answer for Docker Toolbox on Windows Server 2012!!!! Excellent job! For anyone's curiosity, ${MOUNT_PATH} resolves as /c/Program Files/Docker Toolbox
t
tkit

Other solutions for Git Bash provided by others didn't work for me. Apparently there is currently a bug/limitation in Git for Windows. See this and this.

I finally managed to get it working after finding this GitHub thread (which provides some additional solutions if you're interested, which might work for you, but didn't for me).

I ended up using the following syntax:

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

Note the MSYS_NO_PATHCONV=1 in front of the docker command and $(pwd) - round brackets, lower-case pwd, no quotes, no backslashes.

Also, I'm using Linux containers on Windows if that matters..

I tested this in the new Windows Terminal, ConEmu and GitBash, and all of them worked for me.


Hello, this helped me finally get this working. Do you know why we need the MSYS_NO_PATHCONV=1 command option? Otherwise my destination mount dir got filled with "c:/tools/cmder/vendor/git-for-windows"
B
Blue Clouds

This command should fix it.

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

{PWD} is the host current folder. after the : is the container folder. If the mounting is correct then files will be listed in the director c:\data in the container.


K
Karl

You need to swap all the back slashes to forward slashes so change

docker -v C:\my\folder:/mountlocation ...

to

docker -v C:/my/folder:/mountlocation ...

I normally call docker from a cmd script where I want the folder to mount to be relative to the script i'm calling so in that script I do this...

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

My solution is similar, but shorter and can be run directly in the console: set pwd=%cd:C:\=//c/% & set pwd=%pwd:\=/% docker run -v %pwd%:/app alpine ls /app
nice, I'll borrow that :-)
h
happyy

If you are still having this issue in 2022, you can install docker in windows with WSL(Windows Subsystem for Linux). Then you can go on Microsoft Store and install one of the Linux project like Ubuntu, Debian or Kali Linux.

On Docker Desktop go to setting -> WSL integration and enable your version of Linux.

On VS Code open new WSL terminal and execute the Linux command there.


А
Александр Рыкованов
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

echo ${PWD} result:

/c/Users/Christian/manager

cmd or PowerShell

  cd C:\Users\Christian\manager

echo ${PWD} result:

Path ---- C:\Users\Christian\manager

as we see in cmd or PowerShell $ {PWD} will not work


Also, in English, please write an explanation of your solution. That would help fighting the misconception that StackOverflow is a free code writing service.