August 12, 2017

Mounting Files vs Mounting Directories

We dive into an important difference in behavior when mounting a single file vs whole directories.

To test out the difference between file vs directorying mounting, we'll create an Nginx configuration file on a host file system (Linux) and try out both methods to mount in a server configuration.


First I pull the official Nginx image:

docker pull nginx:alpine

cd /opt
sudo mkdir conf.d
sudo vim conf.d/default.conf

We'll make it proxy, as site with no SSL certificate that won't redirect us to a different location. I create file /opt/conf.d/default.conf on a Linux host's local file system:

upstream app {

server {
    listen 80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    charset utf-8;

    location / {
        proxy_set_header Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://app;
        proxy_redirect off;

        # Handle Web Socket connections
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

Start Nginx, mounting that configuration file to where Nginx will be looking for configuration files:

docker run -d \
    --name=nginx \
    -v /opt/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
    -p 80:80 \

It works in the browser, goes to!

Changing the Mounted File

Let's change the conf file. We'll have it proxy instead of with the following two changes:

# Upstream

# Host
proxy_set_header Host;

Reload Nginx:

docker kill -s HUP nginx

We'll see in the browser that Nginx is still proxying the site! It didn't suck in the configuration file change.

We can see that the file in the container was not updated:

# On our local system
cat conf.d/default.conf

# In the container
docker exec nginx cat /etc/nginx/conf.d/default.conf

It still proxys!

Nginx did see the reload command, but it didn't see the file being changed.

This is related to Linux, vim, and how it sees file changes (replace vs edit in place):

The Fix:

Mount directories instead of files!

Let's kill the original Nginx container and start a new one with a directory mounted:

docker stop nginx
docker rm -v nginx

# Mount the directories instead of a file
docker run -d \
    --name=nginx \
    -v /opt/conf.d:/etc/nginx/conf.d \
    -p 80:80 \

It now shows the results of!

And we can change it back it to make sure:

# Upstream

# Host
proxy_set_header Host;

And reload nginx:

docker kill -s HUP nginx

...and we'll see this now proxying the site - the change was propogated into the container, and reloading Nginx worked.

Looking for a deeper dive into Docker?

Sign up here to get a preview of the Shipping Docker course! Learn how to integrate Docker into your applications and develop a workflow to make using Docker a breeze!

All Topics