Have you ever built a Dockerized backend application that worked flawlessly while you were using it,
only to discover that all your data vanished once you shut down your local machine or remote server?
That frustrating moment of having to recreate everything makes you wonder:
Isn’t there a way to store data permanently?
Enter Docker Compose volumes the lifesavers that make your data persistent,
shareable, and resilient in a containerized world.
In this five-minute read, I will demystify Docker Compose volumes: what they are, why they are
indispensable, and how to use them in your docker-compose.yml file.
A Docker volume is a way to persist data generated or used by containers. It is a dedicated storage location that lives outside the container’s ephemeral filesystem (temporary filesystem that only exists as long as the container is running). When you use volumes in Docker Compose, you are basically telling Docker: “Take this folder from my computer (or a special storage space managed by Docker) and make it available inside the container at a specific location.” It’s like plugging a USB stick into the container so it can read and write files there.
You will typically use two types of volumes:
Imagine you building a blog platform with a database container like PostgreSQL or MySQL. Without volumes, all your posts, user data, likes and comments would vanish every time you restart or remove the container. Volumes solve this by enabling:
docker-compose.ymlUsing volumes in your Compose file is quite straightforward.
db_data at the top level under
volumes:.
db service, we map db_data to PostgreSQL’s data directory
(/var/lib/postgresql/data). Now your database data persists even after restarting
or removing the container.
./app is mounted to /usr/src/app inside the
container.
app directory are reflected instantly inside the
container.
/var/lib/docker/volumes/.
./data:/var/lib/mysql).
docker volume prune.When working with volumes, one common challenge is file and folder permissions. Since a container
often runs processes as a specific user (for example: postgres in a PostgreSQL image,
ornode in a Node.js image). Those processes need the right permissions to read and
write to the mounted volume. On the other hand, the files on your host machine are owned by your
local user. If the user IDs don’t match, you may run into issues such as “Permission denied”
when your container tries to access the volume. There are a few ways to handle this. You can adjust
permissions on the host with chmod or chown. Run the container with a
matching user ID (--user flag), or configure your Dockerfile to create a dedicated user
inside the container that aligns with your host setup. For development bind mounts usually works
fine after a quick chmod 777 on the mounted folder. In production, it is better to
adopt a stricter principle of the least privilege approach to avoid security risks.
If your local user has UID 1000 (user id) and GID 1000 (group id), you can run a container so it
uses the same user and group as your host system. Files created inside the container will belong to
your local user and permission issues are avoided.
Bash example:
In case you are using Docker Compose, you can add a user entry directly in your service definition:
Docker Compose volumes are essential for building durable, flexible, and developer-friendly containerized applications. Whether you are persisting database data or hot-reloading your app during development, volumes are a powerful tool that saves both time and resources.
I hope you enjoyed this blog post and feel inspired to make Docker Compose volumes your data’s best friend!
Find answers to common questions about Docker Compose volumes
A Docker Compose volume is a way to store and share data outside of a container’s temporary filesystem. It allows you to persist data even if a container is stopped, restarted, or rebuilt.
Containers have ephemeral filesystems, meaning all data is lost once the container is removed. Volumes solve this by keeping the data on the host machine (or in Docker-managed storage), ensuring your data persists across restarts and deployments.
A named volume is managed by Docker and stored in Docker’s internal storage, ideal for production environments and databases. A bind mount maps a specific folder from your host machine into a container, which is especially useful during development to instantly reflect local code changes.
Yes. You can attach the same volume to multiple services. This is useful when different containers (for example, a web app and a worker service) need access to the same files or shared data.
Over time, unused volumes can accumulate and take up space. You can safely remove them with
the
command docker volume prune, which deletes all volumes not currently used by
any
container.