rancher-desktop
rancher-desktop copied to clipboard
Mounts with type bind will not bind single files correctly in wsl
Actual Behavior
I expect docker -v and docker --mount to both be able to mount "single files" from the host.
However right now this only works with the "-v" option. A script I have to use, does single file mounting within a composer file.
OS: windows container-engine: docker wsl: ubuntu rancher-desktop version: 1.5.1
Steps to Reproduce
#! /bin/bash
cat <<EOT > echo.sh
#! /bin/bash
echo "Sucessfull bind mount!"
EOT
chmod 777 echo.sh
docker run -it -d \
--name 'bind-v' \
-v $PWD/echo.sh:/echo.sh \
ubuntu sleep infinity
docker run -it -d \
--name 'bind-mount' \
--mount type=bind,source=$PWD/echo.sh,target=/echo.sh \
ubuntu sleep infinity
# wrong behavior; shows a directory
docker exec -it bind-mount sh -c "ls -lha /echo.sh"
#shows the file which is identical to the file from the host
docker exec -it bind-v sh -c "ls -lha /echo.sh"
docker rm --force bind-mount
docker rm --force bind-v
Result
A single file gets mounted as directory
+ docker exec -it bind-mount sh -c 'ls -lha /echo.sh'
total 4.0K
drwx------ 2 root root 40 Aug 19 13:05 .
drwxr-xr-x 1 root root 4.0K Aug 19 13:05 ..
+ docker exec -it bind-v sh -c 'ls -lha /echo.sh'
-rwxrwxrwx 1 1000 1000 43 Aug 19 13:05 /echo.sh
Expected Behavior
I want that the single file gets mounted as the file from my host environment.
Additional Information
Also reproducible via docker-compose file:
version: '3.9'
services:
file-mount-test:
image: ubuntu
volumes:
- type: bind
source: ./echo.sh
target: /echo.sh
command: /echo.sh
Here is the complete file I used for analyzing and reproducing the issue:
#!/bin/bash
docker rm --force bind-mount
docker rm --force bind-v
cat <<EOT > echo.sh
#! /bin/bash
echo "Sucessfull bind mount!"
EOT
chmod 777 echo.sh
docker run -it -d \
--name 'bind-v' \
-v $PWD/echo.sh:/echo.sh \
ubuntu sleep infinity
docker run -it -d \
--name 'bind-mount' \
--mount type=bind,source=$PWD/echo.sh,target=/echo.sh \
ubuntu sleep infinity
# Bind Mount
echo 'bind-v Binds'
docker inspect bind-v | jq '.[].HostConfig.Binds'
echo 'bind-mount Binds'
docker inspect bind-mount | jq '.[].HostConfig.Binds'
# Volume Mount
echo 'bind-v Binds'
docker inspect bind-v | jq '.[].Mounts'
echo 'bind-mount Binds'
docker inspect bind-mount | jq '.[].Mounts'
set -x
docker exec -it bind-mount sh -c "ls -lha /echo.sh"
docker exec -it bind-v sh -c "ls -lha /echo.sh"
#docker rm --force bind-mount
#docker rm --force bind-v
Rancher Desktop Version
1.5.1
Rancher Desktop K8s Version
I dont know
Which container engine are you using?
moby (docker cli)
What operating system are you using?
Windows
Operating System / Build Version
Windows 10
What CPU architecture are you using?
x64
Linux only: what package format did you use to install Rancher Desktop?
No response
Windows User Only
Not relevant to this issue I think. VPN was not running,while I was testing it.
Thanks for the helpful and detailed bug report! I was able to reproduce this on my Windows 10 machine. We'll work on it when we get a chance - PRs are also welcome :)
Confirming. -v /run/docker.sock:/run/docker.sock
works every time, --mount source=/run/docker.sock,target=/run/docker.sock,type=bind
never works and mounts an empty directory (owned by root.root, mode 700) instead. Also --mount
sometimes fails randomly with the same problem, mounting an empty directory instead.
Workaround
I wrote this hacky bash script that translates --mount
to -v
when they are binds without extra options. Dropped it into my WSL install as /usr/local/bin/docker
(fortunately rancher-desktop adds itself to the end of PATH) and devcontainers started through WSL now get their docker sockets and docker configs all right.
#!/bin/bash
set -eu
nextdocker=$(which -a docker|tail +2|head -1)
args=()
was_mount=''
for arg in "$@"; do
if [[ "$arg" == '--mount' ]]; then
was_mount=yes
else
if [[ "$was_mount" == yes ]]; then
declare -A parts=()
unset s t
typ=''
ro=''
ifs="$IFS"
IFS=,
for part in $arg; do
case $part in
src=*|source=*) s="${part#*=}";;
dst=*|destination=*|target=*) t="${part#*=}";;
type=bind) typ="${typ}bind";;
readonly|readonly=true|readonly=1|ro|ro=true|ro=1) ro=':ro';;
*) typ=unknown;;
esac
done
IFS="$ifs"
if [[ "$typ" == bind ]]; then
args+=('-v')
args+=("$s:$t$ro")
else
args+=('--mount')
args+=($arg)
fi
else
args+=("$arg")
fi
was_mount=''
fi
done
exec "$nextdocker" "${args[@]}"