How to detect Docker volume and mount backup coverage drift
Find Docker volumes and bind mounts that escaped backup coverage after deployments, Compose changes, renames, and one-off container fixes.

A green backup can protect yesterday’s Docker data
A successful Docker volume backup only proves that the backup command read the paths it was given. It does not prove that those paths still hold the application’s live state. The fastest safe way to detect coverage drift is to compare three inventories after meaningful changes: the mounts declared by the deployment, the mounts used by running or expected containers, and the sources or database artifacts your backup policy actually protects.
Consider a Compose project renamed during a server cleanup. The database starts on a newly named volume, while the backup job continues reading the old volume mountpoint. The old path remains readable, the scheduled job stays green, and a restore later produces a valid database that stopped receiving writes on deployment day. That is **backup coverage drift**: protected scope no longer matches the application’s current persistent state.
Drift commonly follows ordinary work: a Compose project-name change, a new uploads directory, a bind-mount source moved to another disk, a Docker data-root migration, a new service, or a one-off container launched outside the normal deployment. Command exit status cannot reliably catch these changes because the old source may still exist.
- Treat a newly observed persistent source with no coverage decision as urgent until an owner classifies it.
- Treat a covered source that is no longer in use as a review item, not proof that recovery is safe.
- Do not let an automatic discovery process silently add every path it finds to backups.
Start with the data that must survive a container replacement
Docker containers have a writable layer, but that layer is not a sound place to keep durable application state. Docker recommends mounts for data that must outlive a container, and that state can be held in named volumes, anonymous volumes, host bind mounts, or storage supplied by an external volume driver. Each has a different identity, lifecycle, and recovery path. See the official [Docker volumes documentation](https://docs.docker.com/engine/storage/volumes/) for the storage model.
Do not assume that images or a Compose file recover the application. They help recreate software and service wiring, but they do not recreate customer uploads, database records, application-generated keys, or other data in mounts. Docker also documents that data in attached volumes is not included when a container is committed to an image.
Classify every discovered mount by purpose before deciding how to protect it. Authoritative uploads and generated content may need direct filesystem coverage. Database data generally needs an engine-supported logical or physical backup. Read-only configuration may be version-controlled or backed up separately. Caches, transient queues, and scratch directories may be intentionally excluded. This prevents the noisy and incomplete habit of backing up everything below Docker’s internal directories.
- Authoritative application data: protect it and define how to validate it after restore.
- Database state: protect a consistent database artifact, not merely files that happen to sit in a volume.
- Configuration and deployment state: retain Compose files, environment-variable recovery information, and a secure recovery path for secrets.
- Rebuildable state: explicitly document why a cache, image layer, or temporary working directory is excluded.
Build a coverage map from Compose definitions and service ownership
Your Compose configuration is the useful starting point, not the final truth. Services declare mount type, source, target, and access mode; top-level declarations describe named or external volumes. Render the effective configuration after variable interpolation and overrides, then review it alongside the runtime Docker inventory. The official [Compose volumes reference](https://docs.docker.com/reference/compose-file/volumes/) explains the declaration layer.
For every persistent component, keep a small coverage map in the application repository or operations documentation. The map should identify the stable service owner and purpose rather than relying only on generated Docker resource names. It should also name the protection method, the backup set or repository, the intended restore target, and the evidence used to validate recovery.
This mapping is especially important when project names change. Compose can scope a volume name to the project, while explicit names, external volumes, overrides, and environment interpolation can produce different platform resource names. A backup rule that recognizes only yesterday’s generated volume name can continue to run long after the application moved.
- Service and owner: for example,
postgresowned by the payments application team. - Persistent purpose: database cluster, user uploads, generated reports, or a recoverable configuration directory.
- Protection method: database dump, database-native physical backup, direct filesystem backup, or an explicit exclusion.
- Recovery evidence: the date of the latest isolated restore and the smoke test that passed.
Compare declared mounts, runtime mounts, and backup scope
Runtime inspection answers what Docker is using now. docker inspect exposes each container mount’s type, source, destination, and read/write mode. docker volume inspect exposes a named volume’s driver, labels, and mountpoint. Compare those observations with the rendered Compose definition and your coverage map; none of the three lists is sufficient by itself.
Look for four difference types: an observed persistent mount without an owner, a declared mount absent at runtime, a covered source no longer used by an application, and an active source missing from the backup set. The active-but-uncovered case deserves immediate investigation. A stale-but-covered source also matters because it can make a restore test appear successful when the restored data is obsolete.
Include stopped but expected services when their state matters. A scheduled worker may be absent during a daytime inventory but still own a durable volume. Conversely, build containers may create anonymous mounts that are deliberately disposable. Ownership, purpose, and an explicit exclusion decision prevent the inventory from becoming an unreviewable list of Docker objects.
- Declared but not observed: confirm whether the service has been intentionally removed, is stopped, or failed to deploy.
- Observed but not declared: investigate one-off containers, deployment overrides, and manual incident fixes.
- Observed and persistent but not covered: add an appropriate protection method or document a conscious exclusion.
- Covered but not observed: confirm it is not a stale resource masking a changed live data source.
Use Docker inspection commands to create a reviewable inventory
The following commands are illustrative and read-only. Run them on the Docker host with permission to query the Docker daemon. They do not back up data and do not prove recoverability; they create an inventory you can compare with the paths or artifacts named in your backup policy. Test any automation derived from them in a non-production environment first.
Run the Compose command from the directory containing the relevant Compose file, using the same Compose files, profiles, and environment inputs used for deployment. Treat rendered output as sensitive if it includes resolved environment values. Do not paste credentials, tokens, or full environment files into tickets or monitoring output.
- Expected result: the first command renders intended services and mounts; the second prints the source, destination, type, and read/write state for current containers; the third lists named volumes and their mountpoints.
- Failure signal: a source in runtime output is not present in the coverage map, or a backup source has no matching runtime owner.
- Production caveat: Docker’s local volume mountpoint is host-specific implementation detail. Prefer stable volume identity and service ownership in policy, then resolve the current mountpoint when the backup process needs a host path.
Treat bind mounts as host paths with application meaning
Bind mounts can point anywhere on the Docker host, and their source is tied to that host’s directory layout. A migration from /srv/app/uploads to a directory on another disk can leave the original path behind. A backup of the old directory still succeeds while all new files land elsewhere. Review bind mounts as part of the server’s filesystem and mount layout, not as a Docker-only concern.
Check resolved absolute sources rather than only short syntax in a deployment file. Review symlinks, separate filesystems, network mounts, and paths Docker created automatically. A permissive mount declaration with a typo can create an empty host directory, let a container start, and hide historical content from the application.
The restore plan needs more than recovered bytes. Record the required owner, group, mode, security labels where applicable, container destination, and read/write mode. A restored host path is not useful coverage if the service cannot mount or read it correctly. The [Docker bind mounts documentation](https://docs.docker.com/engine/storage/bind-mounts/) is the primary reference for their host-coupled behavior.
- Compare filesystem device and mount information before and after a data migration; a familiar pathname can resolve to different storage.
- Restore to an intentional staging path first; do not overwrite a production bind-mount source merely to test backup content.
- After a staging restore, validate ownership and permissions using the service account or a disposable container configured with the expected mount.
Technical basis
First-party references
Technical claims and limitations in this guide were checked against these primary sources. Confirm version-specific behavior when designing a production recovery process.
Related from Rested
Common questions
Frequently asked questions
Should I back up all of /var/lib/docker?
Usually not as a default strategy. Docker’s internal data includes images, layers, caches, and engine-managed state, while bind mounts can live elsewhere. Inventory each application’s persistent mounts, protect direct file data intentionally, and use database-aware methods where required.
Are Docker images enough to recover a containerized app?
No. Images help recreate application software, but data in attached volumes is separate. You also need deployment configuration, persistent data, required secrets or a recovery path for them, and a tested recovery order.
What causes Docker volume names to change?
Compose project naming, explicit volume names, environment interpolation, stack renames, overrides, and recreation under another deployment context can change platform resource names. Map protection to stable application identity and verify runtime state after changes.
How do I know a Docker database volume is safely backed up?
Confirm the engine-specific consistency method, restore the resulting artifact into an isolated database, and validate recent application data. Finding database files in a volume snapshot does not by itself prove a coherent database restore.