Got struck in docker run command in windows [duplicate] - docker

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?

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

This works for me in PowerShell:
docker run --rm -v ${PWD}:/data alpine ls /data

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

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.

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

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

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.

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.

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

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.

If you want to pass your project directory with the DockerfileRunArguments property to your debug container, then pwd won't work.
<PropertyGroup>
<!-- Will result in `` -->
<DockerfileRunArguments>-v "$(pwd):/data:ro"</DockerfileRunArguments>
</PropertyGroup>
Use $(MSBuildProjectDirectory) instead of $(pwd)
<PropertyGroup>
<!-- Will result in the full path to your project directory -->
<DockerfileRunArguments>-v "$(MSBuildProjectDirectory):/data:ro"</DockerfileRunArguments>
</PropertyGroup>
Reference: MSDocs - Visual Studio Container Tools

PowerShell on Windows 10 Pro
The above solutions did not work for me as plain pwd gives a description in the response:
Path
----
C:\Users\barnaby
It needs outputting as a variable in the script $(pwd) but then docker complains invalid reference format
The solution is to wrap the whole switch parameters in double quotes and this works for me:
docker run --rm -v "$(pwd):/app" php:7.4-cli php /app/hello.php

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

Related

Cannot mount volume for drive d:\ or e:\ in Docker Desktop for Windows

Searched internet & stackoverflow for this but no success
Using Docker for Desktop version 4.12.0 on Windows 10 with WSL2 as backend.
In window's command prompt window, following works and lists files in c:/data
docker run --rm -v c:/data:/target alpine ls /target
But none of following works. /target directory is always empty!
docker run --rm -v d:/data:/target alpine ls /target
docker run --rm -v "d:/data:/target" alpine ls /target
docker run --rm -v "d:/data":/target alpine ls /target
docker run --rm -v /mnt/d/data:/target alpine ls /target
docker run --rm -v /run/desktop/host/d/data:/target alpine ls /target
docker run --rm -v "/run/desktop/host/d/data:/target" alpine ls /target
However, within WSL 2 terminal window following works and lists files under /target directory !
docker run --rm -v /mnt/d/data:/target alpine ls /target
But I want to use Docker Desktop for Windows and use windows command prompt. Ultimately want to mount volume inside docker-compose.yml.
Some of above commands seems to have been working for different people based on stackoverflow answers in past. Don't know if it's because of different version of Docker for Desktop or not clear if they were trying in WSL2 terminal window or Windows command prompt window.
TIA
You are facing a Microsoft limitation regarding Docker volumes:
"We support mapping a whole second drive letter, but for now, not
portions of it. "
You have to just mount the complete d drive, as d:
Other options such as root (d:\), or paths (d:\somefolder) won't work with the second drive.
In your case, that means doing something like:
docker run -it -v d: alpine ls /d/data
If that creates an empty d folder inside your container, that means you're hitting permission issues within the drive.
Note that even if the issue comment is from 2016, seems like the limitation is still kicking in...

Docker volume bind is not working with current directory

I am Docker 20.10.17, build 100c701. Whenever I bind a local directory to a volume it doesn't show the volume using ls.
(base) hell#Dell-Precision-T7910:~/Desktop/PhD/PHD/Nvidia Modulus/Modulus v22.03$ pwd
/home/hell/Desktop/PhD/PHD/Nvidia Modulus/Modulus v22.03
(base) hell#Dell-Precision-T7910:~/Desktop/PhD/PHD/Nvidia Modulus/Modulus v22.03$ ls
'Key features.txt' Modulus_examples Modulus_examples.tar.gz modulus_image_v22.03.tar.gz Modulus_source Modulus_source.tar.gz
(base) hell#Dell-Precision-T7910:~/Desktop/PhD/PHD/Nvidia Modulus/Modulus v22.03$ docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 -v ${pwd}:/examples -it modulus:22.03 bash
=============
== PyTorch ==
=============
root#b880211ba2ca:/examples# ls -a
. ..
root#b880211ba2ca:/examples# ls
My pwd contains spaces and uppercase, I don't think there should a problem with spaces.
However, when I bind /home/ it works fine.
(base) hell#Dell-Precision-T7910:~/Desktop/PhD/PHD/Nvidia Modulus/Modulus v22.03$ docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 -v /home/hell/:/examples -it modulus:22.03 bash
=============
== PyTorch ==
=============
root#67b5dbfa0e10:/examples# ls
'2022-06-10 09-50-30.mkv' '2022-06-10 10-02-08.mkv' '2022-06-11 01-54-01.mkv' Documents MATLAB Pictures Templates Videos Zotero libreoffice
'2022-06-10 09-59-18.mkv' '2022-06-11 01-51-17.mkv' Desktop Downloads Music Public Untitled.ipynb 'VirtualBox VMs' anaconda3 snap
root#67b5dbfa0e10:/examples#
Please help me. BTW I am using Ubuntu 20.04 with RTX A5000 24GB.
When your command uses -v ${pwd}:/examples, the syntax ${pwd} expands to an environment variable named pwd. This probably expands to an empty string; you either need the environment variable PWD (all uppercase, the case matters) or the output of the shell command pwd. You say the path includes spaces; this makes it important to put the argument in double-quotes as well.
# using the $PWD environment variable
docker run -v "${PWD}:/example" ...
# using the `pwd` command
docker run -v "$(pwd):/example" ...

Docker mounted volume adds ;C to end of windows path when translating from linux style path

I've found some interesting weirdness when trying to mount a docker image on windows.
I created a .sh script that does a mount of the project folder to run our developer environment image. I want one script that every dev can run, regardless of their machine. All it does is runs docker with the current project folder.
#!/usr/bin/env bash
docker run -it --rm -v D:\my\project\folder:/wkDir $IMAGE_TAG yarn dev
Runs okay. Now the plan is to call this script from npm, so I'd like this to work relative to the current folder. Let's try another version.
docker run -it --rm -v $PWD:/wkDir $IMAGE_TAG yarn dev
Fails with:
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from
daemon: Mount denied:
The source path "D:/my/project/folder;C"
doesn't exist and is not known to Docker.
Wat. What's ;C and where did it come from?
So I do echo $PWD which gives me /d/my/project/folder.
Interesting, so $PWD resolves to the correct path in linux path format, and it seems like docker is trying to translate from that to the correct windows path, except there's this ;C that appears out of nowhere. And the \ are /...
What exactly is going on here?
I get the same result in VSCode's terminal git bash and powershell.
Update: I noticed that running the .sh in VSCode's powershell terminal, opens a separate cmd.exe console window which seems to run the script in git bash. So this might be a git bash issue.
So with some extra digging I found these three threads, related to git-bash mucking up docker mount:
https://forums.docker.com/t/weird-error-under-git-bash-msys-solved/9210
https://github.com/moby/moby/issues/24029#issuecomment-250412919
When I look up mingw's documentation on the path conversion git-bash is using, I find this table of syntax:
http://www.mingw.org/wiki/Posix_path_conversion
One of which outputs in the format: x;x;C:\MinGW\msys\1.0\x. Note the ;C in it. If git-bash is trying to be clever, stuffing up the syntax and outputting a path with this format, this would explain it.
Solution is to escape the path conversion, using by prefixing with /. So the working docker command to run docker from git-bash with present working directory:
docker run -it --rm -v /${PWD}:/wkDir $IMAGE_TAG yarn dev
Mounting the current directory into a Docker container in Windows 10 from Git Bash (MinGW) may fail due to a POSIX path conversion. Any path starting with / is converted to a valid Windows path.
touch test.txt
docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt
# ls: C:/Git/data/test.txt: No such file or directory
Escape the POSIX paths by prefixing with /
To skip the path conversion, all POSIX paths have to be prefixed with the extra leading slash (/), including /$(pwd).
touch test.txt
docker run --rm -v /$(pwd):/data busybox ls -la //data/test.txt
# -rwxr-xr-x 1 root root 0 Jun 22 23:45 //data/test.txt
In Git Bash the path //data/test.txt is not converted and in Linux shells // (leading double slash) is ignored and treated the same way as /.
Disable the path conversion
Disable the POSIX path conversion in Git Bash (MinGW) using MSYS_NO_PATHCONV environment variable.
The path conversion can be disabled at the command level:
touch test.txt
MSYS_NO_PATHCONV=1 docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt
# -rwxr-xr-x 1 root root 0 Jun 22 23:45 /data/test.txt
The path conversion can be disabled at the shell (or system) level:
export MSYS_NO_PATHCONV=1
touch test.txt
docker run --rm -v $(pwd):/data busybox ls -la /data/test.txt
# -rwxr-xr-x 1 root root 0 Jun 22 23:45 /data/test.txt
For me the solution was simply to include a closing slash / at end of any paths.
E.g. instead of
/opt/apache-atlas-2.0.0/bin/atlas_start.py
...use
/opt/apache-atlas-2.0.0/bin/atlas_start.py/
I had the same issue on git bash and not command prompt.
You can instead
docker run -it --rm -v "/${PWD}/D:\my\project\folder":/wkDir $IMAGE_TAG yarn dev
Can you try below command -
docker run -it --rm -v %cd%:/wkDir $IMAGE_TAG yarn dev
I've actually had the same issue. Depending on if you are using Git Bash this command works(using nginx as an example):
docker container run --name container-name -v `pwd -W` /html:/usr/share/nginx/html -p 8000:80 -d nginx
of course you can specify the port and directory as you desire.
Straight worked for me below. just don't use dynamic variable.
docker run --rm -u root -p 8080:8080 -v jenkins-data/:/var/jenkins_home -v /var/run/docker.sock/:/var/run/docker.sock -v /Users/<YOUR USER NAME>/:/home jenkinsci/blueocean

docker : can't mount some directory from host

I have the latest centos image for docker and the host machine is ubuntu.
i'm having some script at my host machine, with the path:
/home/username/untitled1/preReq.sh
i'm trying to execute this script, inside my centos docker.
while i'm mounting the directory of the script, i can't see anything and it appears that i'm mounting the root directory.
i'm using this command (from ~)
docker run --rm -it -v ${PWD}:/untitled1 centos
someone know how to fix it?
either use the pwd command (without caps) if you're in the directory:
docker run --rm -it -v ${pwd}:/untitled1 centos
or use $HOME environment variable if you're running with that user:
docker run --rm -it -v ${HOME}:/untitled1 centos
I would suggest
docker run --rm -it -v `pwd`:/untitled1 centos
At least that works for me.
${X}
evaluates the environment variable X. PWD is typically set by your shell:
$ export
[...]
declare -x PWD="/home/user"
[...]
pwd on the other hand is a program producing the current working directory to STDOUT:
$ whereis pwd
pwd: /bin/pwd /usr/include/pwd.h /usr/share/man/man1/pwd.1.gz
$ pwd
/home/user
With the previous docker command the program is executed and its STDOUT is inserted producing:
docker run --rm -it -v /home/user:/untitled1 centos

How to run application from docker container from host OS?

I'm using docker container with ubuntu:14.04 and some C++ application that I compiled inside docker container.
Is it possible to run application that is inside container from host OS(in my case Win 7)?
Something like:
docker run <path-to-binary>/mybinary -f 10 -o output.txt
UPDATE:
Yes, it's possible
docker run -it <my-image> <path-to-binary>/mybinary
So ideally I want application inside docker will be just like native applications on Windows host OS.
Also is it possible to specify files and folder in host OS as input arguments to application that docker container can't see?
UPDATE:
I tried to mount shared folder at container start
docker run -v C:\shared_with_VM:/temp my_image
and also
docker run -v "C:\shared_with_VM":/temp my_image
But I get error:
C:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: Invalid
bind mount spec "C:\\shared_with_VM:/temp": invalid mode: /temp.
See 'C:\Program Files\Docker Toolbox\docker.exe run --help'.
As said here right path format on Windows should be
docker run -v /c/shared_with_VM:/temp my_image
I am not sure if I correctly understand your question...
You can mount folders from your host to the container to make it accessible from within your container:
docker run -v /host/folder:/container/ -it <image> <executable> <arguments>
For example:
docker run -v /tmp:/tmphost -it ubuntu ls -al /tmphost
# or in Windows
docker run -v //c/Users/mrgloom/Desktop/data:/tmphost -it ubuntu ls -al /tmphost
This creates the folder /container/ in your container and links it with /host/folder. You can then bidirectonally read / write files inside these folders. Your binary has to point to the input file, which might be located in /container/input.txt

Resources