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
Normally, when finding a bind-mount path for the overlay2 driver with Docker-in-Docker, I can do it via the following:
$ docker run --rm -it --entrypoint bash \
-v /var/run/docker.sock:/var/run/docker.sock \
gcr.io/cloud-builders/docker
$ apt-get install jq -y
$ mount_point=$(docker inspect $HOSTNAME | jq -r '.[0].GraphDriver.Data.MergedDir')
$ echo "$mount_point"
/var/lib/docker/overlay2/c68a6fc53a27d6347e691a52bdd792094a7a4fdc65041b387d1ea38607ba999d/merged
$ mkdir hello && cd hello
$ echo "sample contents" > file
$ docker run --rm -it --entrypoint bash \
-v "$mount_point/hello":/hello \
-w /hello \
gcr.io/cloud-builders/docker
$ ls
# nothing
For everything besides WSL2, this will properly mount my files. However, for WSL2, it seems the bind mounts are present under a different location. If my attached WSL2 distro name is Ubuntu-22.04, I can find a list of unique IDS under /mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04/:
$ ls /mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04/
13a7bc88b63d361f5752d7ef3f5c96cd262ef580e6f435cced6bd10ec82842b0 692b88d87549cc6cb71d70e56b24d64d46c6e4f3b54611d635e407941a34d5da
21241f82d3c1e170eae05d87ed4fe9493165603a5f20f4decc5da0695296a22b 71329c4cc6e32171553fa81d044eb31d1a3aac52ba9376c4a99f4505c494cf5b
2af2028475f25893cbe6ae56fd41a5060323a05cf2de361ca5cd788882ab124e 9f9cdad793414edd07516ebe0fef99bea77a67d7033bcce9e6e2636fc52d206f
40072ee5313e41a68b132298796cbec4d044881a473056704dbaf45732b96709 e9b0d5f175dde593817759ef48c2ea4be074dd6fd7dde1e5ee0051f1cbbb36e7
449de67da5b95f36f74bf415852073e587a6f2f5acffecd8470687a065aa9a24 fd27f4eaa94fe2d4e43106f3751004bf816189bf06237c658a0c8e7aec6e54c8
67aa8dec46ea42423b4090c10503d733f4ff4c1eb43cb8e31f040c84cafba60c
Now, if I use a bindmount for the initial load, I can find the file as the mount point in the container, so at least I can get files relative to a mount point (but not very reliably). Run on the WSL2 host:
$ find /mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04 -name clippy.toml
/mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04/b7371a7ca29bc7acbea2f7cebdf0d5b452a4fadd8af16a733896e7dccbd49e3a/clippy.toml
/mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04/0157aea7f7f54b90e62c5810422a2535f5513005a8db7001cf10c7753d3dc6fb/clippy.toml
This isn't straightforward if more than 1 container or bind mount exists with that file, however. Also, none of the hashes for the container match the Docker inspect or the hostname. Now, run on the container:
$ correct_id=b7371a7ca29bc7acbea2f7cebdf0d5b452a4fadd8af16a733896e7dccbd49e3a
$ echo $HOSTNAME
dadd6ab5f853
$ docker inspect $HOSTNAME| grep b737
# nothing
So there doesn't seem to be a reliable way to find that file. Also, for any files outside a bind mount, there doesn't seem to be a way to find their path. At least, however, the correct WSL2 bind mount location does work if passed into the container:
$ docker run --rm -it --entrypoint bash \
-v /mnt/wsl/docker-desktop-bind-mounts/Ubuntu-22.04/b7371a7ca29bc7acbea2f7cebdf0d5b452a4fadd8af16a733896e7dccbd49e3a/:"$PWD" \
-w "$PWD" gcr.io/cloud-builders/docker
$ ls
CHANGELOG.md Cargo.lock LICENSE-APACHE README.md ci crosstool-ng docker rustfmt.yml target
CODE_OF_CONDUCT.md Cargo.toml LICENSE-MIT assets clippy.toml deny.toml docs src xtask
But how do I find say, a file in the container at /hello/file, which was created inside the container run within WSL2?
I should also mention this is Docker Desktop for Windows being shared into the WSL Ubuntu distro. Docker was not installed inside the distro and then used without iptables.
I try to backup my unhealthy database from a docker container volume to my local host. I didn't found any functional script. Here is my container structure.
docker-desktop:/var/lib/docker# ls
builder containers overlay2 swarm volumes
buildkit image plugins tmp
containerd network runtimes trust
docker-desktop:/var/lib/docker/volumes# ls
ba41a7f8c8b68619709139ec396363be7f40a3e6da2c4efafeb7a01e408a5dcc
cfarchitecture_data_appserver
cfarchitecture_data_database
cfarchitecture_data_pma
cfarchitecture_home_appserver
cfarchitecture_home_database
cfarchitecture_home_pma
landocasetupkenobi38ahsoka60a2ffd2ada01dc9cbe426cbf7999bb8297ec6a0_data_ca
landocasetupkenobi38ahsoka60a2ffd2ada01dc9cbe426cbf7999bb8297ec6a0_home_ca
landoproxyhyperion5000gandalfedition_data_proxy
landoproxyhyperion5000gandalfedition_home_proxy
metadata.db
docker-desktop:/var/lib/docker/volumes/cfarchitecture_data_database# ls
_data
docker-desktop:/var/lib/docker/volumes/cfarchitecture_data_database/_data# ls
auto.cnf ib_buffer_pool performance_schema
ca-key.pem ib_logfile0 private_key.pem
ca.pem ib_logfile1 public_key.pem
client-cert.pem ibdata1 server-cert.pem
client-key.pem mysql server-key.pem
drupal8 mysql_upgrade_info sys
docker-desktop:/var/lib/docker# ls
builder containers overlay2 swarm volumes
buildkit image plugins tmp
containerd network runtimes trust
docker-desktop:/var/lib/docker/containers# ls
05d2cb8982e61a621a38d0443c8c067cc6585aa3275312dadc56ea972d12bb99
70b77f688c6552181044c76326e90dfcf906c2ddae25ee8450c1c1b09ea2029c
c00e38c7acc03545723ba126537cba08a8fb553b274fc5ba9fa2635a8883e370
Here is the latest attempts to backup my folder :
macpro-10:~ Yom$ docker run --rm --volumes-from c00e38c7acc03545723ba126537cba08a8fb553b274fc5ba9fa2635a8883e370 -v ~/backup:/backup ubuntu bash -c 'cd /drupal8 && tar cvf /backup/ghost-site.tar .'
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Image is up to date for ubuntu:latest
docker: Error response from daemon: No such container: c00e38c7acc03545723ba126537cba08a8fb553b274fc5ba9fa2635a8883e370.
See 'docker run --help'.
macpro-10:~ Yom$ c00e38c7acc03545723ba126537cba08a8fb553b274fc5ba9fa2635a8883e370
-bash: c00e38c7acc03545723ba126537cba08a8fb553b274fc5ba9fa2635a8883e370: command not found
macpro-10:~ Yom$ docker run --rm --volumes-from cfarchitecture_database_1 -v ~/backup:/backup ubuntu bash -c 'cd /data/drupal8 && tar cvf /backup/ghost-site.tar .'
bash: line 0: cd: /data/drupal8: No such file or directory
macpro-10:~ Yom$ docker run --rm --volumes-from cfarchitecture_database_1 -v ~/backup:/backup ubuntu bash -c 'cd /_data/drupal8 && tar cvf /backup/ghost-site.tar .'
bash: line 0: cd: /_data/drupal8: No such file or directory
macpro-10:~ Yom$ docker run --rm --volumes-from cfarchitecture_database_1 -v ~/backup:/backup ubuntu bash -c 'cd /var/lib/docker/volumes/cfarchitecture_data_database/_data/drupal8 && tar cvf /backup/ghost-site.tar .'
bash: line 0: cd: /var/lib/docker/volumes/cfarchitecture_data_database/_data/drupal8: No such file or directory
I am completely lost, I really need to backup this database (1 week of work)
thanks a lot
how many containers are you running?
Can you do a list?
docker ps -aq
I hope your containers are not removed along with images before your back up operation.
Also, if the containers are running. Please stop them using docker stop and then try.
Please post above command outputs.
This command
echo 1 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6
when run inside a CentOS docker container (running on Mac), gives:
echo 1 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6
tee: /proc/sys/net/ipv6/conf/all/disable_ipv6: Read-only file system
1
When run inside a CentOS virtual machine, it succeeds and gives no error.
The directory permissions inside docker container and VM are exactly the same:
VM:
$ ls -ld /proc/sys/net/ipv6/conf/all/disable_ipv6
-rw-r--r-- 1 root root 0 Jan 4 21:09 /proc/sys/net/ipv6/conf/all/disable_ipv6
docker:
$ ls -ld /proc/sys/net/ipv6/conf/all/disable_ipv6
-rw-r--r-- 1 root root 0 Jan 5 05:05 /proc/sys/net/ipv6/conf/all/disable_ipv6
This is a fresh, brand new container.
Docker version:
$ docker --version
Docker version 18.09.0, build 4d60db4
What am I missing?
Try hackish solution and add extended privileges to the container with --privileged:
$ docker run --rm -ti centos \
bash -c "echo 1 | tee /proc/sys/net/ipv6/conf/all/disable_ipv6"
tee: /proc/sys/net/ipv6/conf/all/disable_ipv6: Read-only file system
1
vs
$ docker run --privileged --rm -ti centos \
bash -c "echo 1 | tee /proc/sys/net/ipv6/conf/all/disable_ipv6"
1
You can use --cap-add to add precise privilege instead of --privileged.
However --sysctl looks like the best solution, instead of hacking networking in the container with --privileged:
$ docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 \
--rm -ti centos bash -c "cat /proc/sys/net/ipv6/conf/all/disable_ipv6"
1
I'm trying to run this command in my Powershell:
docker run -u postgres --net host -v /`pwd`/file.sql://tmp/setup.sql --rm postgres:9.4 psql -h localhost -U postgres -f //tmp/setup.sql my_db;
which is giving me this error:
psql:/tmp/setup.sql:0: could not read from input file: Is a directory
I tried running a bash in that docker container via this command:
docker run -it -u postgres --net host -v /`pwd`/file.sql://tmp/setup.sql --rm postgres:9.4 bash
and then did a simple ls -l /tmp inside the docker tty, and it's showing that setup.sql file is actually a directory!
drwxr-xr-x 2 root root 40 Jan 13 08:39 setup.sql
How do I go about doing this? I've also tried the bash shell supplied by msysgit with the same results.