A set of Bash scripts to back up and fully restore all your running Docker containers: images, named volumes, bind-mounted host paths, and container configuration.
- Docker
jq— required for restore operations and bind-mount backup (apt install jq/brew install jq)- Sufficient permissions to read/write bind-mount host paths (may require
sudo)
| Flag | Description |
|---|---|
-m |
Required. Mode: backup or restore |
-p |
Backup directory path (default: /home/core/backups) |
-t |
Extra options passed to tar when compressing the backup dir (e.g. --exclude=/some/path) |
-B |
Enable bind-mount backup/restore (off by default — see note below) |
-u |
Upload backup to Dropbox after completing |
-f |
Force: overwrite non-empty backup dir on backup; replace existing volumes/containers/paths on restore |
-s |
Non-interactive mode — skips all prompts, enables all steps (use in cron jobs) |
| Artifact | Location in backup |
|---|---|
| Container images | <container>/<container>-image.tar (via docker save) |
| Named volumes | volumes/<volume-name>.tar.gz — one file per volume, shared volumes deduplicated |
| Container inspect data | <container>/<container>-data.txt — JSON used to recreate containers on restore |
Bind-mount host paths (opt-in with -B) |
<container>/binds/bind-N.tar.gz + manifest.json |
- Images —
docker loadfrom each image tar - Volumes — extracted back into named Docker volumes
- Bind mounts (only if
-Bwas used during backup) — host paths extracted to their original locations - Containers — recreated from inspect data (best-effort: covers name, image, env, ports, volumes, restart policy, network mode)
Container recreation is best-effort. Common configuration is reconstructed from the saved
docker inspectoutput. Unusual settings (custom capabilities, device mappings, secrets, etc.) may need to be applied manually.
Bind-mount host paths (
-v /host/path:/container/path) require the-Bflag. Without it, only the container config (the-vflag reference) is restored, but the actual host-side files are not touched. These paths often require root-level read/write access.
cd docker-backup-scripts
chmod +x *.sh backup/*.sh restore/*.sh./backup-manager.sh -p <output-path> -m backupInclude bind-mounted host paths:
./backup-manager.sh -p <output-path> -m backup -B./backup-manager.sh -p <backup-path> -m restoreRestore including bind-mounted host paths:
./backup-manager.sh -p <backup-path> -m restore -BForce-replace existing containers and volumes:
./backup-manager.sh -p <backup-path> -m restore -f./backup-manager.sh -p <output-path> -m backup -uYou must create a Dropbox App and place your generated access token in
config/dropbox_uploader.conf before using -u. See
https://www.dropbox.com/developers for details.
./backup-manager.sh -p <output-path> -m backup -sAll steps are enabled automatically in -s mode (bind mounts only if -B is
also passed).
crontab -e
# Daily backup at midnight:
0 0 * * * /path/to/backup-manager.sh -p <output-path> -m backup -sA systemd timer for CoreOS is provided in backup/coreos-timer/. Run the
installation script there to set up a daily backup service.
Two test tiers are provided.
Uses a docker stub to verify script logic in isolation. Requires
bats-core and jq.
bats test/*.batsCovers: volume backup layout and deduplication (issue #14), dotted volume-name parsing regression, full restore pipeline ordering (issue #18), container reconstruction from inspect JSON, bind-mount backup/restore skip/force logic.
Runs the full cycle inside an isolated Docker-in-Docker daemon so your host containers and volumes are never touched. Requires Docker with privileged container support.
bash test/integration/run.shVerifies end-to-end:
- Named volume data survives backup and restore
- Bind-mount host paths are backed up with
-Band restored in place - Container images are re-loaded after being deleted
- Restored container is running with correct env, restart policy, and port mapping