docker-volume-backup: a companion container that stops your app to take the backup
Backup Docker volumes locally or to any S3, WebDAV, Azure Blob Storage, Dropbox, Google Drive or SSH compatible storage
At a glance
- What is it?
- A single-image tool that backs up Docker volumes to local disk or six kinds of remote storage, rotates old copies, encrypts and notifies, and talks to the Docker daemon to stop a container while it copies. The example configuration warns against the tag it uses.
- Who is it for?
- Take this if you back up Docker volumes and want one small container rather than a restore script per volume, and if you can accept that the tool needs to talk to the Docker daemon to stop a container during a copy. Check three things first.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- offen/docker-volume-backup4,073 ★ · +54
| Repository | 2026-09-24 | 2026-11-13 |
|---|---|---|
| offen/docker-volume-backup | 4k | 4.1k |
54 Stars in the last 50 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The stop-during-backup label is a consistency choice
The recurring-backup quickstart is a compose file with two services, and the interesting part is a label on the consumer rather than on the backup container. The label asks the backup tool to stop that container while it copies the volume, and the comment gives the reason: to ensure backup integrity. It also says the label can be omitted if stopping during backup is not required, which makes the default decision visible: a backup of a running database's volume is a copy of files that are being written underneath it, and whether that matters is your call. The tool does not decide for you. Two related details sit in the same snippet. The volumes are mounted under a path inside the backup container rather than being enumerated, so what gets backed up is what you mount. And the image line is paired with a comment advising that in production you lock the image tag to a proper release version instead of using the floating tag, which is advice the example is not itself following, and that image line is the part of the snippet cut off on this page.
One image, six remote targets, and combinations of them
The destination list is the feature. Backups can go to a local directory, or to any S3-compatible store, WebDAV, Azure Blob Storage, Dropbox, Google Drive, or any SSH-compatible storage, and the page is explicit that you can use any combination of these. That last clause is the one that matters operationally: the tool is not choosing between local and remote but treating them as simultaneous destinations. S3 compatibility is why two entries in the dependency list are there, an S3 client library and an SSH file transfer library, since a home NAS or a storage provider that speaks one of those is a target without writing a plugin. The same list explains two more targets you would not guess from the names: a Dropbox SDK and a WebDAV client library. So the remote matrix is broad because it is assembled from existing protocol clients rather than from a bespoke integration per provider, which is also why adding a new kind of destination is a different kind of work here.
It talks to the Docker daemon, which is why the file lock matters
Two dependencies reveal how the tool is built to fit into a running system rather than sit beside it. One is a Docker API client library, which is what lets the backup container stop a container and start it again afterwards when that label is set. The other is a file locking library, which is the reason two backup runs do not fight over the same volume: a lock file is taken and released, so a manual one-off run started by a human while the scheduled run fires will wait rather than interleave. That combination is the whole integration story, and it has a security consequence worth stating plainly: the tool needs permission to control the Docker daemon, which is effectively root-equivalent access to the host. So the image being small and single-purpose buys you nothing against a configuration mistake, and the daemon access has to be scoped deliberately rather than granted by default. For scale, the one-off invocation looks like this, with the volume mounted at the backup path and the entrypoint overridden to the backup command:
docker run --rm \
-v data:/backup/data \
--env AWS_ACCESS_KEY_ID="<xxx>" \
--env AWS_SECRET_ACCESS_KEY="<xxx>" \
--env AWS_S3_BUCKET_NAME="<xxx>" \
--entrypoint backup \
offen/docker-volume-backup:v2Encryption is described as GPG, and the module ships two toolkits
The feature list advertises encrypting backups using GPG, and the dependency list supports that: an OpenPGP implementation for Go is there. Next to it is a different library entirely, a modern file encryption tool built on well-understood cryptography primitives, which is not the same thing and is not interchangeable with GPG. The page does not explain when each is used, so from the dependency list alone you cannot tell whether the second library backs the same feature, a newer default, or an unrelated code path. What you can tell is that a backup tool advertising encryption carries two cryptographic stacks. Before you rely on it, verify which one encrypts the artefact you are about to restore, because the failure mode of getting that wrong is a restore that cannot be decrypted at the moment you need it, and that is not a failure a test will catch unless the test includes a restore.
Rotation, notifications, and a cron dependency
The two operational features are the ones that turn a copy script into something you leave running. Rotation is described as rotating away old backups if configured, which means retention is a setting rather than an assumption, and the phrase if configured is doing work: nothing is kept a bounded number of copies unless you say so, so a volume that grows will fill whatever you point it at. Notifications are for failed backup runs specifically, sent through a general-purpose notification library that supports many channel types, and the schedule itself is driven by a cron library rather than by an external timer. That combination has one consequence: the container is the scheduler, so a stopped container means no backups and no notification that it stopped. Pairing this with the stop-during-backup behaviour from the first section means the tool can be both the thing that keeps your data safe and the thing that silently stops backing it up, so monitoring the monitoring is worth doing.
One-off runs mount a volume and pass three credentials
The one-off path is a single container invocation with no compose file, and it is the shape most people will try first. You mount the volume you want into the backup container at a fixed backup path, pass the credentials as environment variables for the destination, override the entrypoint to the backup command rather than the foreground mode, and name a specific major version of the image. So the credentials are three variables whose names follow the S3 convention, which means the same invocation works against any S3-compatible endpoint by also passing an endpoint. The alternative the page offers is an environment file, passed with a flag, which is how you supply a full configuration rather than three values. That distinction matters because the full configuration is where rotation, notification, and encryption settings live, and a one-off run with three variables takes none of them. It also names a specific major version of the image rather than a floating tag, which is the one place in the documentation that does what the compose comment recommends.
Two build stages, and a flag that distinguishes the two run modes
The container definition is compact and tells you two things about the design. The build stage is a Go toolchain image that downloads the module dependencies first, copies the source, changes into a single command directory and builds only that one binary. So the image ships exactly one program, the backup command, which is how it stays small enough to describe as a lightweight companion. The runtime stage is a bare Alpine with certificate authorities and timezone data, and one unusual permission change: the lock directory is made world-writable. That line is the file lock from the dependency list showing up in the image, and it is needed because the lock file is created at runtime by a container that may not share a user with whatever else is running. The entrypoint passes a foreground flag, which is what distinguishes running as a long-lived container from running as a one-off command, and that is the only difference between the two modes the documentation describes.
Editorial conclusion
Take this if you back up Docker volumes and want one small container rather than a restore script per volume, and if you can accept that the tool needs to talk to the Docker daemon to stop a container during a copy. Check three things first. The documented configuration uses a floating image tag in a comment that advises pinning to a release, so pin it yourself. The remote targets include a share-your-life storage service, which is fine for a small backup set but not for anything you would mind exposing. And the encryption path is described as GPG while the module also carries a modern file encryption library, so check which mechanism you are actually getting before assuming it is the one you tested.
Frequently asked questions
how to take docker volume backup
Add a backup service to your compose setup and mount the volumes you want copied, or run one-off by mounting the volume into the container and overriding the entrypoint to the backup command with your destination credentials as environment variables. A label on the consuming container asks the tool to stop it during the copy so the backup is consistent.
Where can docker-volume-backup send backups?
A local directory, or any S3-compatible store, WebDAV, Azure Blob Storage, Dropbox, Google Drive, or any SSH-compatible storage, and the page states you can use any combination of these rather than choosing one.
Does docker-volume-backup stop running containers?
Only if you ask. A label on the consuming container requests that it be stopped during the backup to ensure integrity, and the page says you can omit that label if stopping during backup is not required. That capability comes from a Docker API client in the module.
Does docker-volume-backup encrypt its backups?
It advertises encrypting backups using GPG, and the module carries an OpenPGP implementation alongside a separate modern file encryption library. The page does not say which is used when, so verify the mechanism before depending on a restore.
How does docker-volume-backup handle old backups and failures?
It rotates away old backups when configured, sends notifications for failed backup runs, and drives its own schedule with a cron library, so the container is the scheduler and a stopped container means no backups and no alert about it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/offen-docker-volume-backup)Star history chart for your README
[](https://hysenlabs.com/projects/offen-docker-volume-backup)Was this useful?