Docker-compose volume mount before run
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Docker Compose, volumes are mounted when the container is created, before the container process starts running. That timing matters because mounted data can replace files that were baked into the image, and startup scripts will see the mounted view of the filesystem, not the original image contents. Understanding that order prevents many confusing development and deployment bugs.
What Happens Before the Container Starts
When Compose creates a container, Docker performs several steps in order:
- Creates the container from the image.
- Attaches networks.
- Attaches volume mounts and bind mounts.
- Starts the container command.
That means your entrypoint or application starts only after the mount is already in place.
Basic Compose Volume Example
Here is a simple bind mount from host to container:
When the container starts, /app will reflect the host directory ./src, not whatever the image originally had at /app.
Why This Surprises People
The most common surprise is that a mount hides files from the image at the same path.
Example:
- Image contains
/app/package.json. - Compose bind-mounts an empty host directory to
/app. - Container starts and now
/appappears empty.
That looks like Docker deleted files, but it did not. The mount simply obscured the image content at that path.
Named Volumes Versus Bind Mounts
Compose supports both named volumes and bind mounts, but their behavior differs in important ways.
Bind mount:
Named volume:
Bind mounts expose a host path directly. Named volumes are managed by Docker and are usually the better choice for persistent container data.
First-Run Copy Behavior with Named Volumes
Named volumes have an important detail: if the target path in the container image already contains files and the volume is empty on first use, Docker may copy the existing image contents into the new volume.
That behavior does not apply to bind mounts in the same way. With a bind mount, the host path simply becomes the visible content immediately.
This difference matters a lot when images include default configuration or seeded data.
Startup Scripts and Mount Timing
Because mounts are attached before the command runs, entrypoint scripts can rely on mounted files being present.
Example:
The command will read the mounted /config directory, not image-layer files that used to exist there.
This is why mounted configuration is a common pattern for local development and environment-specific startup.
Typical Development Workflow
Bind mounts are especially useful when you want live code editing without rebuilding the image:
Edits on the host become visible in the container immediately. That is convenient, but it also means host filesystem state controls what the process sees.
Debugging Mount Problems
If a container does not see expected files, inspect the mount first.
Check:
- Whether the host path exists.
- Whether the mounted path is correct.
- Whether a bind mount is hiding files you expected from the image.
Most volume bugs turn out to be path mistakes or image-content masking.
Common Pitfalls
- Expecting image files to remain visible at a path that is bind-mounted from the host.
- Mounting an empty host directory over a non-empty image directory.
- Assuming named volumes and bind mounts behave identically on first use.
- Debugging app startup without checking what the filesystem actually looks like inside the container.
- Using bind mounts in production where named volumes or image-based config would be safer.
Summary
- Compose attaches volume mounts before the container process starts.
- A mount can hide files that were baked into the image at the same path.
- Bind mounts and named volumes have different first-run behavior.
- Startup scripts see the mounted filesystem, not the original image layer at that path.
- Most mount-related bugs come from path confusion or hidden image content.

