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
c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea
kishore$ docker run -i -t k3_s3:latest /bin/bash
root@0f17e2313a46:/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 ..
root@0f17e2313a46:/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 -v
command? - 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
, e.g.,:
# Run a container using the `alpine` image, mount the `/tmp`
# directory from your host into the `/container/directory`
# directory in your container, and run the `ls` command to
# show the contents of that directory.
docker run \
-v /tmp:/container/directory \
alpine \
ls /container/directory
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 bebind
,volume
, ortmpfs
. (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 assource
orsrc
.The
destination
takes as its value the path where the file or directory will be mounted in the container. May be specified asdestination
,dst
, ortarget
.
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.
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.