A colleague asked how he might use a relative path e.g. ~/foobar or ../foobar instead of an absolute path e.g. /home/Dave or /tmp/foobar when mapping a path on the host to a path inside a container, using Docker for Mac.
Well, I had a play ....
For reference, Docker uses a concept known as bind mounting as evidenced by docker run --help
-v, --volume list Bind mount a volume
to make a file-system on the host available inside a running container.
I used BusyBox ( busybox ) : -
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6858809bf669 5 weeks ago 1.23MB
and tinkered with various options.
Scenario 1 - using a shortcut for /home/<user> specifically ~
echo "Hello World!" > ~/foo.txt
docker run --rm -it --volume ~:/tmp busybox:latest sh
and then validate from inside the container: -
cat /tmp/foo.txt
Hello World!
exit
so that works ....
Scenario 2 - using a shortcut / relative path such as ..
mkdir -p ~/foobar/snafu
echo "Hello World!" > ~/foobar/greeting.txt
docker run --rm -it --volume "..":/tmp busybox:latest sh
docker: Error response from daemon: create ..: ".." includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
See 'docker run --help'.
Erk, not so good .....
Whilst I can do this: -
docker run --rm -it --volume ~/foobar:/tmp busybox:latest sh
cat /tmp/greeting.txt
Hello World!
that kinda defeats the object ....
Enter .... realpath
which realpath
/usr/local/bin/realpath
realpath --version
realpath (GNU coreutils) 8.32
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Padraig Brady.
realpath --help
Usage: realpath [OPTION]... FILE...
Print the resolved absolute file name;
all but the last component must exist
-e, --canonicalize-existing all components of the path must exist
-m, --canonicalize-missing no path components need exist or be a directory
-L, --logical resolve '..' components before symlinks
-P, --physical resolve symlinks as encountered (default)
-q, --quiet suppress most error messages
--relative-to=DIR print the resolved path relative to DIR
--relative-base=DIR print absolute paths unless paths below DIR
-s, --strip, --no-symlinks don't expand symlinks
-z, --zero end each output line with NUL, not newline
--help display this help and exit
--version output version information and exit
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation <https://www.gnu.org/software/coreutils/realpath>
or available locally via: info '(coreutils) realpath invocation'
I'd heard about realpath from the colleague who'd asked the question in the first place ... so I installed it ....
and so back to Docker ....
docker run --rm -it --volume `realpath ..`:/tmp busybox:latest sh
cat /tmp/greeting.txt
Hello World
which works a treat - the trick is to use the shell-within-a-shell trick of enclosing one command inside another, via the double backpack ( ` ) symbol.
So I'm asking realpath where am I ....
realpath ..
/Users/hayd/foobar
and then using the results of that as the from for the Docker bind mount.
Scenario 3 - absolute paths that are absolutely horrible
So even though this wasn't something for which my colleague asked, I wanted to see what happened with horrible paths that include space characters .....
Personally I *HATE* spaces in paths - Microsoft did it with Windows a few decades back, with C:\Program Files\ etc. and that used to play havoc with Java and class paths.
Here's one that IBM Notes uses, for dumps etc.
cd ~/Library/Application\ Support/IBM\ Notes\ Data/IBM_TECHNICAL_SUPPORT/
Within that path, there's a subdirectory: -
SmartUpgrade
This entire path expands out to: -
/Users/hayd/Library/Application Support/IBM Notes Data/IBM_TECHNICAL_SUPPORT/SmartUpgrade
so we test it thusly: -
cd "/Users/hayd/Library/Application Support/IBM Notes Data/IBM_TECHNICAL_SUPPORT/SmartUpgrade
echo "Hello World!" > ./greeting.txt
docker run --rm -it --volume "/Users/hayd/Library/Application Support/IBM Notes Data/IBM_TECHNICAL_SUPPORT/SmartUpgrade":/tmp busybox:latest sh
cat /tmp/greeting.txt
Hello World!
Interestingly, the realpath "hack" didn't work: -
docker run --rm -it --volume `realpath .`:/tmp busybox:latest sh
docker: invalid reference format: repository name must be lowercase.
See 'docker run --help'.
docker run --rm -it --volume "`realpath .`":/tmp busybox:latest sh
cat /tmp/greeting.txt
Hello World!
So now we are wrapping the output of `realpath .` in double-quotes ... otherwise, the output of realpath throws back space characters to the upper shell, which breaks docker run .....
What fun!
No comments:
Post a Comment