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. I couldn't succeed after googling and reading the Docker volume links.

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 c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea

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:

  1. How do I need to link the main_folder to the test_container folder present inside the docker container?
  2. I need to make this automatically. How do I to do that without really using the run -d -v command?
  3. What happens if the boot2docker crashes? Where are the Docker files stored (apart from Dockerfile)?


answered 4 years ago nhjk #1

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

answered 4 years ago user3680997 #2

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).

answered 4 years ago mattes #3

boot2docker together with VirtualBox Guest Additions
How to mount /Users into boot2docker

tl;dr Build your own custom boot2docker.iso with VirtualBox Guest Additions (see link) or download and save it to ~/.boot2docker/boot2docker.iso.

answered 4 years ago rgaut #4

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.

answered 4 years ago Emile #5

How do I link the main_folder to the test_container folder present inside the docker container?

Your command below is correct, unless your on a mac using boot2docker(depending on future updates) in which case you may find the folder empty. See mattes answer for a tutorial on correcting this.

docker run -d -v /Users/kishore/main_folder:/test_container k3_s3:latest

I need to make this run automatically, how to do that without really using the run -d -v command.

You can't really get away from using these commands, they are intrinsic to the way docker works. You would be best off putting them into a shell script to save you writing them out repeatedly.

What happens if boot2docker crashes? Where are the docker files stored?

If you manage to use the -v arg and reference your host machine then the files will be safe on your host.

If you've used 'docker build -t myimage .' with a Dockerfile then your files will be baked into the image.

Your docker images, i believe, are stored in the boot2docker-vm. I found this out when my images disappeared when i delete the vm from VirtualBox. (Note, i don't know how Virtualbox works, so the images might be still hidden somewhere else, just not visible to docker).

answered 4 years ago louis V #6

2 successive mounts : I guess many posts here might be using two boot2docker , the reason you don't see anything is because 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 and the second to mount the new directory from boot2docker to your container like this:

1. mount local system on boot2docker

sudo mount -t vboxsf hostfolder /boot2dockerfolder

2. mount boot2docker file on linux container

docker run -v /boot2dockerfolder:/root/containerfolder -i -t  imagename

then when you ls inside containerfolder you will see the content of your hostfolder

answered 3 years ago Tal #7

Jul 2015 update - boot2docker now supports direct mounting. You can use -v /var/logs/on/host:/var/logs/in/container directly from your Mac prompt, without double mounting

answered 3 years ago Eli #8

[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.

answered 2 years ago Sven #9

I'm just experimenting with getting my SailsJS app running inside a Docker container to keep my physical machine clean.

I'm using the following command to mount my SailsJS/NodeJS application under /app:

cd my_source_code_folder
docker run -it -p 1337:1337 -v $(pwd):/app my_docker/image_with_nodejs_etc

answered 2 years ago matthaeus #10

Had the same problem. Found this in the docker documentation:

Note: The host directory is, by its nature, host-dependent. For this reason, you can’t mount a host directory from Dockerfile, the VOLUME instruction does not support passing a host-dir, because built images should be portable. A host directory wouldn’t be available on all potential hosts.

So, mounting a read/write host directory is only possible with the -v parameter in the docker run command, as the other answers point out correctly.

answered 2 years ago Ali #11

docker run -v /host/directory:/container/directory -t IMAGE-NAME /bin/bash

docker run -v /root/shareData:/home/shareData -t kylemanna/openvpn /bin/bash

In my system I've corrected the answer from nhjk, it works flawless when you add the -t flag.

answered 11 months ago Mansur Ali #12

I found that any directory laying under system directive like /var, /usr, /etc could not be mount under the container.

The directive should be at user's space -v switch instructs docker daemon to mount local directory to the container, for example:

docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}

answered 10 months ago Eduardo Santana #13

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 <key>=<value> tuple. The --mount syntax is more verbose than -v or --volume, but the order of the keys is not significant, and the value of the flag is easier to understand.

  • The type of the mount, which can be bind, volume, or tmpfs. (We are going to use bind)

  • The source of the mount. For bind mounts, this is the path to the file or directory on the Docker daemon host. May be specified as source or src.

  • The destination takes as its value the path where the file or directory will be mounted in the container. May be specified as destination, dst, or target.

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 `pwd` instead:

    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.

answered 2 months ago Sunil Chauraha #14

I had the same requirement to mount host directory from container and I used volume mount command. But during testing noticed that it's creating files inside container too but after some digging found that they are just symbolic links and actual file system used form host machine.

answered 1 month ago rainabba #15

As of Docker 18-CE, you can use docker run -v /src/path:/container/path to do 2-way binding of a host folder.

There is a major catch here though if you're working with Windows 10/WSL and have Docker-CE for Windows as your host and then docker-ce client tools in WSL. WSL knows about the entire / filesystem while your Windows host only knows about your drives. Inside WSL, you can use /mnt/c/projectpath, but if you try to docker run -v ${PWD}:/projectpath, you will find in the host that /projectpath/ is empty because on the host /mnt means nothing.

If you work from /c/projectpath though and THEN do docker run -v ${PWD}:/projectpath and you WILL find that in the container, /projectpath will reflect /c/projectpath in realtime. There are no errors or any other ways to detect this issue other than seeing empty mounts inside your guest.

You must also be sure to "share the drive" in the Docker for Windows settings.

comments powered by Disqus