How to mount a host directory in a Docker container
I am trying to mount a host directory into a Docker container so that any updates done on the host is reflected into the Docker containers.
Where am I doing something wrong. Here is what I did:
kishore$ cat Dockerfile FROM ubuntu:trusty RUN apt-get update RUN apt-get -y install git curl vim CMD ["/bin/bash"] WORKDIR /test_container VOLUME ["/test_container"]
kishore$ tree . ├── Dockerfile └── main_folder ├── tfile1.txt ├── tfile2.txt ├── tfile3.txt └── tfile4.txt
1 directory, 5 files kishore$ pwd /Users/kishore/tdock
kishore$ docker build --tag=k3_s3:latest .
Uploading context 7.168 kB Uploading context Step 0 : FROM ubuntu:trusty ---> 99ec81b80c55 Step 1 : RUN apt-get update ---> Using cache ---> 1c7282005040 Step 2 : RUN apt-get -y install git curl vim ---> Using cache ---> aed48634e300 Step 3 : CMD ["/bin/bash"] ---> Running in d081b576878d ---> 65db8df48595 Step 4 : WORKDIR /test_container ---> Running in 5b8d2ccd719d ---> 250369b30e1f Step 5 : VOLUME ["/test_container"] ---> Running in 72ca332d9809 ---> 163deb2b1bc5 Successfully built 163deb2b1bc5 Removing intermediate container b8bfcb071441 Removing intermediate container d081b576878d Removing intermediate container 5b8d2ccd719d Removing intermediate container 72ca332d9809
kishore$ docker run -d -v /Users/kishore/main_folder:/test_container k3_s3:latest
kishore$ docker run -i -t k3_s3:latest /bin/bash
[email protected]:/test_container# ls -al total 8 drwx------ 2 root root 4096 Apr 29 05:15 . drwxr-xr-x 66 root root 4096 Apr 29 05:15 ..
[email protected]:/test_container# exit exit
kishore$ docker -v Docker version 0.9.1, build 867b2a9
- I don't know how to check boot2docker version
Questions, issues facing:
- How do I need to link the main_folder to the test_container folder present inside the docker container?
- I need to make this automatically. How do I to do that without really using the
run -d -vcommand?
- What happens if the boot2docker crashes? Where are the Docker files stored (apart from Dockerfile)?
There are a couple ways you can do this. The simplest way to do so is to use the dockerfile
ADD command like so:
ADD . /path/inside/docker/container
However, any changes made to this directory on the host after building the dockerfile will not show up in the container. This is because when building a container, docker compresses the directory into a
.tar and uploads that context into the container permanently.
The second way to do this is the way you attempted, which is to mount a volume. Due to trying to be as portable as possible you cannot map a host directory to a docker container directory within a dockerfile, because the host directory can change depending on which machine you are running on. To map a host directory to a docker container directory you need to use the
-v flag when using docker run like so:
docker run -v /host/directory:/container/directory -other -options image_name command_to_run
Read more... Read less...
The user of this question was using
Docker version 0.9.1, build 867b2a9, I will give you an answer for docker version >= 17.06.
What you want, keep local directory synchronized within container directory, is accomplished by mounting the volume with type
bind. This will bind the source (your system) and the target (at the docker container) directories. It's almost the same as mounting a directory on linux.
According to Docker documentation, the appropriate command to mount is now
mount instead of
-v. Here's its documentation:
--mount: Consists of multiple key-value pairs, separated by commas. Each key/value pair takes the form of a
--mountsyntax is more verbose than
--volume, but the order of the keys is not significant, and the value of the flag is easier to understand.
typeof the mount, which can be
tmpfs. (We are going to use bind)
sourceof the mount. For bind mounts, this is the path to the file or directory on the Docker daemon host. May be specified as
destinationtakes as its value the path where the file or directory will be mounted in the container. May be specified as
So, to mount the the current directory (source) with
/test_container (target) we are going to use:
docker run -it --mount src="$(pwd)",target=/test_container,type=bind k3_s3
If these mount parameters have spaces you must put quotes around them. When I know they don't, I would use
docker run -it --mount src=`pwd`,target=/test_container,type=bind k3_s3
You will also have to deal with file permission, see this article.
2 successive mounts: I guess many posts here might be using two boot2docker, the reason you don't see anything is that you are mounting a directory from boot2docker, not from your host.
You basically need 2 successive mounts:
the first one to mount a directory from your host to your system
the second to mount the new directory from boot2docker to your container like this:
1) Mount local system on
sudo mount -t vboxsf hostfolder /boot2dockerfolder
boot2dockerfile on linux container
docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename
Then when you
ls inside the
containerfolder you will see the content of your
you can use -v option from cli, this facility is not available via Dockerfile
docker run -t -i -v <host_dir>:<container_dir> ubuntu /bin/bash
where host_dir is the directory from host which you want to mount. you don't need to worry about directory of container if it doesn't exist docker will create it.
If you do any changes in host_dir from host machine (under root privilege) it will be visible to container and vice versa.
Is it possible that you use docker on OS X via
boot2docker or something similar.
I've made the same experience - the command is correct but nothing (sensible) is mounted in the container, anyway.
As it turns out - it's already explained in the docker documentation. When you type
docker run -v /var/logs/on/host:/var/logs/in/container ... then
/var/logs/on/host is actually mapped from the
boot2docker VM-image, not your Mac.
You'll have to pipe the shared folder through your VM to your actual host (the Mac in my case).
[UPDATE] As of ~June 2017, Docker for Mac takes care of all the annoying parts of this where you have to mess with VirtualBox. It lets you map basically everything on your local host using the
/private prefix. More info here. [/UPDATE]
All the current answers talk about Boot2docker. Since that's now deprecated in favor of docker-machine, this works for docker-machine:
First, ssh into the docker-machine vm and create the folder we'll be mapping to:
docker-machine ssh $MACHINE_NAME "sudo mkdir -p \"$VOL_DIR\""
Now share the folder to VirtualBox:
WORKDIR=$(basename "$VOL_DIR") vboxmanage sharedfolder add "$MACHINE_NAME" --name "$WORKDIR" --hostpath "$VOL_DIR" --transient
Finally, ssh into the docker-machine again and mount the folder we just shared:
docker-machine ssh $MACHINE_NAME "sudo mount -t vboxsf -o uid=\"$U\",gid=\"$G\" \"$WORKDIR\" \"$VOL_DIR\""
Note: for UID and GID you can basically use whatever integers as long as they're not already taken.
This is tested as of docker-machine 0.4.1 and docker 1.8.3 on OS X El Capitan.