I'm running an application in a Docker container and expose its entire app-data
directory to the host. The app-data
directory inside the container contains many files and directories, also a logs
subdirectory which I want to treat differently and map it to another disk partition on the host. My docker-compose.yml
now contains this:
volumes:
- /mnt/app:/var/app-data
- /tmp/logs:/var/app-data/logs
While this seems to work, I encountered a side-effect that I don't understand. After starting the application, the /tmp/logs
directory correctly contains the application logs, but the /mnt/app
directory now contains an empty logs
directory:
drwxr-xr-x. 2 root root 4096 Dec 1 10:47 logs
Where does this empty directory come from? Is that just expected Docker behavior and totally safe to deploy this way?
CodePudding user response:
That empty directory is needed as the mount point for the nested mount.
The first important detail is that Docker internally sorts all mounts by their container path, and mounts them in order. So, the /var/app-data
mount is completed before Docker starts to consider the /var/app-data/logs
directory.
When Docker does the bind mount, it uses the Linux mount(2) system call. Docker needs to tell the kernel what to mount and where to mount it. If the mount point doesn't exist, Docker creates it first.
In your scenario, after /var/app-data
is mounted, the directory /var/app-data/logs
doesn't exist, so Docker creates it before doing the actual mount. But, when it does create the directory, the outer directory is already mounted, so when it creates the directory it creates it on the host system too.
This is a normal consequence of using nested mounts and it's nothing to worry about.