If you’ve ever worked with Docker Compose and encountered a situation where your container suddenly can’t see any files in a previously working mounted folder, you’re not alone. This issue can be especially frustrating when everything seems to work fine on the initial deployment, only to break inexplicably after redeploy.
The Problem
When a folder is bind-mounted into a Docker container using Docker Compose, it works correctly during the initial deployment. However, after a redeploy — particularly when triggered by automation tools like Portainer — the mounted folder inside the container becomes empty.
This problem affects directory mounts only. Individual file mounts continue to work normally. The issue also appears specifically during redeployment, not during the initial container startup.
Symptoms
- On first deployment: the mounted folder’s contents are visible inside the container.
- After redeployment: the same folder appears empty in the container.
Root Cause
This behavior comes from how Docker bind mounts work at the kernel level, especially in combination with how deployment tools handle file staging.
When a volume like the following is declared in docker-compose.yml:
volumes:
- ./some-folder:/app/data
Docker sets up a bind mount:
mount --bind /host/some-folder /container/app/data
This binds the container path to the current inode of /host/some-folder. Here’s what can go wrong:
- During redeploy, some tools (like Portainer Agent) delete and recreate the host folder used for staging compose files.
- Even though the path stays the same, the newly created folder has a different inode.
- Docker doesn’t remount the volume. The container continues to point to the now-nonexistent inode.
- As a result, the container sees an empty folder, because it is still referencing the deleted inode.
File Mounts vs Folder Mounts
- ✅ File Mounts (e.g.
./file.txt:/app/file.txt): continue to work, as files are usually replaced directly. - ❌ Folder Mounts (e.g.
./configs:/app/configs): can break if the folder is deleted and recreated.
The Solution
To fix this issue, you must ensure that Docker recognizes the updated inode by remounting the folder. This means the container should be fully recreated.
✅ Recommended: Recreate the Container
Use --force-recreate to ensure Docker discards the stale mount reference:
docker-compose up --force-recreate
Or, in automation tools like Portainer, ensure your deployment pipeline triggers a full container recreation instead of a soft restart. For example, in Portainer, you can toggle on “Re-pull image and redeploy” to ensure the container is fully recreated.
🛠️ Alternative: Avoid Recreating the Folder
If you control the deployment scripts or agent logic, avoid deleting the folder entirely. Instead, clear the contents and repopulate it:
rm -rf /host/folder/*
This keeps the inode intact and prevents the container from losing access to the folder.
Final Thoughts
This issue stems from a subtle interaction between Docker, the Linux filesystem, and inode-based mount references. When containers mysteriously stop seeing mounted folder contents after redeploy, it is often due to this inode mismatch.
By understanding the mechanism behind bind mounts and being careful with folder recreation, you can avoid this frustrating bug in future deployments.
Enjoyed this article? Support my work with a coffee ☕ on Ko-fi.