Manage persistent data in Docker
Choose volumes or bind mounts, back up databases consistently, restore into a fresh volume, and review cleanup scope.
Use a named volume for application data that must survive container replacement. Mount it at the application's actual data directory before it starts writing. A bind mount can also provide durable storage; the essential requirement is that important state lives outside the container's disposable writable layer.
Create and use a named volume
Supply MYSQL_ROOT_PASSWORD through your deployment environment, then run:
docker volume create mysqldata
docker run -d --name mysql \
--mount type=volume,source=mysqldata,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD \
mysql:8.4
docker volume ls
docker volume inspect mysqldata
Use an appropriately managed secret for a real deployment. Environment variables are visible to users with sufficient Docker access. The official image's initialization variables apply when initializing a new database, not as a general password-change mechanism for existing data.
Docker creates a missing named volume when you reference it. A typo can therefore create an empty volume instead of attaching the intended data. Inspect the mount before treating an empty database as data loss.
| Storage | Example | Suitable use |
|---|---|---|
| Named volume | --mount type=volume,src=mysqldata,dst=/var/lib/mysql |
Application data managed through Docker |
| Bind mount | --mount type=bind,src=/srv/app,dst=/app/data |
A specific host path that other tools also use |
| tmpfs | --tmpfs /run/work |
Temporary state, not persistent data |
The default local volume lives in storage managed by the daemon. On Docker Desktop that storage is normally inside its Linux VM; other volume drivers may use remote storage. An inspect path is not an invitation to edit Docker's internal files directly. Linux tmpfs can be swapped to disk, so it is not an absolute guarantee that sensitive bytes never reach storage.
Back up and restore deliberately
Use database-native backup tools, such as mysqldump or pg_dump, with the consistency options appropriate to the database. A tar archive of live database files is not automatically a valid backup.
For a cold filesystem backup, first stop all writers cleanly. This example assumes the local CLI directory is also accessible to the daemon as a bind-mount source:
docker stop mysql
docker run --rm \
--mount type=volume,source=mysqldata,target=/data,readonly \
--mount "type=bind,source=$(pwd),target=/backup" \
alpine:3.22 tar -czf /backup/mysqldata.tar.gz -C /data .
docker start mysql
Verify the archive and retain it outside the original host. Restore trusted archives into a new, empty volume while no database is using it:
docker volume create mysql-restored
docker run --rm \
--mount type=volume,source=mysql-restored,target=/data \
--mount "type=bind,source=$(pwd),target=/backup,readonly" \
alpine:3.22 tar -xzf /backup/mysqldata.tar.gz -C /data
Check ownership, database-version compatibility, and a real restore before relying on this procedure. A volume survives container deletion; it does not by itself survive disk failure or guarantee a compatible database upgrade.
Cleanup and common questions
Use docker volume ls -f dangling=true to investigate volumes not referenced by containers. Unused does not mean unneeded. Current docker volume prune targets unused anonymous volumes by default; --all includes unused named volumes. Review exact names and backups before deleting data.
Does deleting a container delete its volume? Named volumes normally remain. Explicit volume removal, relevant prune operations, and docker compose down -v can remove them. Anonymous volumes have additional cleanup rules, including docker run --rm.
Can several containers share a volume? Yes, but the application must support concurrent access. Do not start independent database servers against the same data directory without a database-supported arrangement.
How does Compose declare a volume? Add it under top-level volumes and reference it from the service. Compose normally scopes its name by project; explicit name or external settings change that behavior.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan