How to Mount Host Directory Into a Docker Container

Isaac Tony Feb 02, 2024
  1. Use Bind Mounts to Mount Host Directory Into a Docker Container
  2. Conclusion
How to Mount Host Directory Into a Docker Container

Besides other functionalities, Docker provides tools to work with the host operating system and the container file system. Among these functionalities is the ability to persist data in containers and share data between containers through mounting directories to Docker containers.

Mounting directories to Docker containers is helpful in a development environment and production. Besides creating services that depend on host system directories, this ensures that the entire file system is not destroyed if a Docker container is destroyed.

Suppose we would like to build a new version of the container. In this case, directly mounting a directory to a Docker container enables hot-reloading.

This article requires that Docker is correctly set up and has a Docker image and container. This will work regardless of whether we’re running Docker on wsl or Linux.

Use Bind Mounts to Mount Host Directory Into a Docker Container

Bind mounts are one of the earliest solutions that allow us to persist data through mounting our Docker containers to directories on our host system. These will enable us to reference a directory by referring to the absolute file path of the target directory.

In this case, Docker is not in control of this directory, unlike the case with Docker volumes. Docker volumes create a directory within the Docker storage system managed by Docker.

In addition to this, unlike Docker volumes, we cannot directly manage directories mounted to our containers through the Docker CLI or Docker API. However, Docker mounts are highly performant in hosts like MAC or windows, where Docker volumes are slightly performant.

We should also note that using bind mounts to mount a container to a directory will surely inflate the size of the container.

We can use two flags to mount a directory to a container while launching the container. These include the -v and --mount flags.

Mount Host Directory Into a Docker Container Using the -v or --volume Flag

It consists of three fields that should always be in the correct order and separated by a colon. These include:

  • The path to the directory on the host machine that we want to mount.
  • The path to the directory in the container where we should mount this directory.
  • Other optional options such as ro specify the read-only mode.
docker run -t -i -v <host_dir>:<container_dir

Once we have identified the host and container directory we want to mount together, we can implement the above command. However, we must not make modifications to sensitive files.

This is because mounts give us access to sensitive files, which, if tampered with, can lead to a fatal failure of our system.

In this case, we will use the official ruby images to create a container and mount a directory. We named scripts with a directory name, the same with the Docker container.

isaac@DESKTOP-HV44HT6:~/isaac$ docker run -it --rm -v$HOME/Desktop/scripts:/scripts --name scripts ruby bash
Unable to find image 'ruby:latest' locally
latest: Pulling from library/ruby
e4d61adff207: Pull complete
4ff1945c672b: Pull complete
ff5b10aec998: Pull complete
12de8c754e45: Pull complete
ada1762e7602: Pull complete
f8f0dec0b2ef: Pull complete
7109f2ab3080: Pull complete
fe1e1dda18a5: Pull complete
Digest: sha256:a1ebc64daa170324dde5b668829de85487575eaa2bdea5216b4c983b1822f9df
Status: Downloaded newer image for ruby:latest

If we do not have the image locally, Docker will automatically download it. Once the container building process is complete, Docker will open the container for us.

root@9d057cf9e33d:/#
root@9d057cf9e33d:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  scripts  srv  sys  tmp  usr  var
root@9d057cf9e33d:/# cd scripts
root@9d057cf9e33d:/scripts# ls

We can see that the scripts directory in the container is empty.

Now, let’s go to the scripts directory in our host machine and create a new file in that directory. It will automatically reflect in the Docker container directory scripts.

isaac@DESKTOP-HV44HT6:~/Desktop$ cd scripts
isaac@DESKTOP-HV44HT6:~/Desktop/scripts$ touch new_file.txt
touch: cannot touch 'new_file.txt': Permission denied
isaac@DESKTOP-HV44HT6:~/Desktop/scripts$ sudo touch new_file.txt
[sudo] password for isaac:
isaac@DESKTOP-HV44HT6:~/Desktop/scripts$ ls
new_file.txt
isaac@DESKTOP-HV44HT6:~/Desktop/scripts$

Once we have created a file in the local directory, it will be shown in the container directory below.

root@913609933be2:/scripts# ls
new_file.txt

Mount Host Directory Into a Docker Container Using the --mount Flag

This is a more straightforward method than the -v tag and consists of multiple key-value pairs, separated by commas. For these tags, the order of the fields is not of concern.

However, it is more verbose when compared to the -v tag.

These methods consist of the following commands:

  • The type of mount such as Bind, volume, or tmpfs.
  • The source, i.e., the path to the directory on the host that we want to mount, is usually denoted with src.
  • The destination, i.e., the path to the directory on the container where we want to mount the directory.
  • We also have other options such as the read-only option and the bind propagation that may specify this directory as private or shared.

Once we have taken note of all the needed fields, especially the source and the destination, we can run the command as shown below.

In this case, we use the official Nginx image to build the container and map the local directory name new_scripts to a directory located in etc/nginx.

$ docker run -d \
> -it \
> --mount type=bind,source=$HOME/Desktop/scripts/new_scripts,target=/etc/nginx \
> nginx \
> bash
e079e3254970e290ae68473239e101c6aa8ba4ba56482c75cd21f9bb9f49600b

Now that we successfully mapped the two directories, any changes made to the directory on the host will automatically reflect on the directory in the container.

isaac@DESKTOP-HV44HT6:~/Desktop/scripts/new_scripts$ sudo touch new_file.txt
[sudo] password for isaac:
isaac@DESKTOP-HV44HT6:~/Desktop/scripts/new_scripts$ ls
new_file.txt

This file will reflect in the docker directory mapped to this directory, showing that we’ve successfully mapped the two directories.

root@e079e3254970:/etc# cd nginx
root@e079e3254970:/etc/nginx# ls
new_file.txt

Conclusion

We have successfully demonstrated how to mount directories using the Docker -v and -mount tags.

However, we should also note that when using the -v tags to mount a non-existing directory, Docker will automatically create it; this is not the same case when using the Docker --mount tag.

We should consider using Docker volumes instead when developing a new application.

Author: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn

Related Article - Docker Container