How to mount external volume for mongoDB using docker-compose and docker-machine
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When MongoDB runs in a container, its data directory must live outside the container filesystem or you will lose the database when the container is removed. With docker-compose and docker-machine, the important detail is that mounts are resolved on the Docker daemon host, not on the machine where you type the command. Once you understand that distinction, MongoDB persistence becomes straightforward.
Understand Where the Volume Actually Lives
docker-machine talks to a remote Docker daemon, often a small VM created with VirtualBox or another driver. That means a path in your Compose file is interpreted on that remote machine.
If you write a bind mount like this:
the left side refers to /data/mongo on the docker-machine host, not on your laptop shell session. This is the source of most confusion.
Choose Between a Named Volume and a Host Bind Mount
You have two persistence options:
- a named Docker volume managed by the remote Docker daemon
- a bind mount to a specific directory on the remote machine
A named volume is simpler:
This is often enough if you only care that the data survives container recreation. If you want the data in a known host path for inspection, backup, or migration, use a bind mount instead.
Prepare the Remote Directory on the Docker Machine
For a bind mount, create the directory on the remote machine first. The exact path depends on the machine driver, but with the old VirtualBox-based default machine, /mnt/sda1 was commonly used for persistent storage.
MongoDB in the official container typically runs as user ID 999, so setting ownership avoids permission errors at startup.
You can verify the directory exists:
Mount the Directory in docker-compose
Once the remote directory exists, reference it in the Compose file:
Then start the service with the Docker environment pointed at your machine:
If you are using the older standalone Compose binary, the second command may be docker-compose up -d.
Verify That MongoDB Data Persists
It is worth testing persistence instead of assuming the mount worked. Insert a document, remove the container, and recreate it.
If the document still exists, MongoDB is writing to the mounted storage rather than the ephemeral container layer.
When an External Named Volume Makes Sense
Sometimes "external volume" means a Docker volume created outside the Compose file. In that case, create it first on the remote daemon:
Then declare it as external:
This keeps Compose from trying to create or remove the volume itself. It is useful when multiple stacks share the same persistent storage or when infrastructure provisions volumes separately.
Common Pitfalls
The biggest mistake is assuming the host path in Compose refers to the local workstation rather than the docker-machine VM. Another common issue is creating the remote directory but forgetting the container user needs write access to it. Some setups also use paths that are not actually persistent on the machine driver, so data appears to work until the VM restarts. Developers also mix up named volumes and bind mounts, even though they solve slightly different problems. Finally, it is easy to trust the configuration without testing persistence by recreating the container, which is the fastest way to catch a bad mount.
Summary
- MongoDB data must be mounted outside the container if you want persistence.
- With
docker-machine, bind-mount paths are resolved on the remote Docker host. - Use a named volume for simplicity or a bind mount when you need a specific host path.
- Create and permission the remote directory before starting MongoDB.
- Verify persistence by writing data, recreating the container, and reading it back.
- If needed, declare a pre-created Docker volume as
external: true.

