Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single file volume mounted as directory in Docker

Docker documentation says that it's possible to mount a single file into a Docker container:

The -v flag can also be used to mount a single file - instead of just directories - from the host machine.

$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

This will drop you into a bash shell in a new container, you will have your bash history from the host and when you exit the container, the host will have the history of the commands typed while in the container.

When I try that however the file mounts as a directory:

tom@u ~/project $ docker run --rm -it -v file.json:/file.json test total 80K drwxr-xr-x  9 root root 4.0K Dec  7 12:58 . drwxr-xr-x 63 root root 4.0K Dec  7 12:58 .. drwxr-xr-x  2 root root 4.0K Dec  4 16:10 file.json 

My Dockerfile looks like this:

FROM ubuntu:14.04 MAINTAINER Tom CMD ["ls", "-lah", "/test"] 

Docker version is 1.9.1, build a34a1d5.

Is this a documentation issue, a misunderstanding on my side, or is there something else going on?

like image 874
TTT Avatar asked Dec 07 '15 13:12

TTT


People also ask

Can a Docker volume be a single file?

Docker volume and bind mounts are used to bind directories on the host OS to locations in the container's file system. While they're commonly used to mount entire directories, you can also use them to symlink individual files.

Is a directory Docker volume?

A Docker volume is a directory somewhere in your Docker storage directory and can be mounted to one or many containers. They are fully managed and do not depend on certain operating system specifics. Before removing the Docker volume, you can open your Docker GUI and inspect the volume by clicking on the data tab.

Does Docker volume create directory?

Docker automatically creates a directory for the volume on the host under the /var/lib/docker/volume/ path. You can now mount this volume on a container, ensuring data persistence and data sharing among multiple containers.

Where are Docker volumes mounted?

Volumes are stored in a part of the host filesystem which is managed by Docker ( /var/lib/docker/volumes/ on Linux).


2 Answers

Maybe that's clear in the answers above... but it took me some time to figure it out in my case.

The underlying reason causing the file being shared with -v to appear as a directory instead of a file is that Docker could not find the file on the host. So Docker creates a new directory in the container with the name being the name of the non existing file on the host as docker thinks that the user just want to share a volume/directory that will be created in the future.

So in the problem reported above, if you used a relative directory in the -v command and docker does not understand relative directories, that means that the file was not found on the host and so docker created a directory. And the answer above which suggests to use $(pwd) will be the correct solution when the problem is due to a relative directory.

But for those reading this page who are not using a relative directory and are having the same problem... then try to understand why the file is missing on the host.

It could just be a stupid typo...

It could be that you're running the "docker run" command from a client which spawns the docker container on a different host and the file being shared does not exist on that different host. The file being shared with -v must exist on the host where the docker agent will spawn the container... not necessarily on the client where the "docker run -v ..." command is executed (although they will be the same in many cases).

There are other possible explanations above for Mac and Windows... that could be it too.

So the file missing from the host is the problem... troubleshoot the problem in your setup... using $(pwd) could be the solution but not always.

like image 58
Nikopol Avatar answered Sep 17 '22 13:09

Nikopol


test is the name of your image that you have built with 'docker build -t test', not a /test folder.

Try a Dockerfile with:

CMD ["ls", "-lah", "/"] or CMD ["cat", "/file.json"] 

And:

docker run --rm -it -v $(pwd)/file.json:/file.json test 

Note the use of $(pwd) in order to mount a file with its full absolute path (relative paths are not supported)

By using $(pwd), you will get an absolute path which does exists, and respect the case, as opposed to a file name or path which might not exist.
An non-existing host path would be mounted as a folder in the container.

like image 24
VonC Avatar answered Sep 20 '22 13:09

VonC