Manage persistent data in Docker

Choose volumes or bind mounts, back up databases consistently, restore into a fresh volume, and review cleanup scope.

Best practices
Illustration of container operations and troubleshooting

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.

See Docker volumes, Docker tmpfs mounts, Volume pruning.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting