Bash script for creating scheduled backups, and performing (backed-up) guided updates on Docker compose stacks.
Because I needed a tool that was...
- Simple by design
- Doesn't require changes inside my
compose.yaml
files - Works with both bind mounts and named volumes
- Can be used to create 🕑scheduled backups
- Can also create ad-hoc backups alongside guided container ⬆️updates
- Not trying to replace existing cloud backup tools (like rclone)
The core focus of backupdate is in creating archived backups of your Docker compose stacks.
- 🛑Stop any running containers in the Docker compose stack
- 📁Create a .tar.gz backup of the stacks working directory
- 📁Create .tar.gz backups of any associated named volumes
- ⬇️Ask to pull any new container images (
-u
) - 🔁Recreate the Docker compose stack containers
- 🗑️Ask to prune any unused container images (
-u
)
Read the official Docker documentation for more details on Back up, restore, or migrate data volumes.
Warning
This script is provided as-is, without any warranty. Use it at your own risk.
Important
The install command and the script must be run with root permissions.
bash -c 'curl -fsSL -o /bin/backupdate https://raw.githubusercontent.com/hazzuk/compose-backupdate/refs/heads/release/backupdate.sh && chmod +x /bin/backupdate'
The script expects your docker compose working directory to be located at $docker_dir/$stack_name
:
docker/
├─ nginx/
│ └─ compose.yaml
├─ wordpress/
│ └─ compose.yaml
└─ nextcloud/
└─ compose.yaml
-b ""
,--backup-dir ""
: Backup directory-d ""
,--docker-dir ""
: Docker compose directory parent-s ""
,--stack-name ""
: Docker compose stack name
-l ""
,--backup-blocklist ""
: Volumes/paths to ignore-u
,--update
: Update the stack containers-v
,--version
: Check the script version for updates
# backup directory
export BACKUP_DIR="/path/to/your/backup"
# docker compose directory parent
export DOCKER_DIR="/path/to/your/docker"
# docker compose stack name
export STACK_NAME="nginx"
# volumes/paths to ignore
export BACKUP_BLOCKLIST="plex_media,/plex-cache"
backupdate -s "nginx" -d "/path/to/your/docker" -b "/path/to/your/backup"
backupdate --stack-name "nginx" \
--docker-dir "/very/long/path/to/docker" \
--backup-dir "/very/long/path/to/the/backup"
Note
Stack updates can only be performed manually. This is by design.
backupdate -u -s "nginx" -d "/path/to/your/docker" -b "/path/to/your/backup"
Tip
backupdate automatically searches for a compose.yaml
/ docker-compose.yaml
file inside your current directory (subsequently this won't require -d
or -s
).
cd /path/to/your/docker/nginx
backupdate -u -b "/path/to/your/backup"
You can create a cron job or use another tool like Cronicle to run the following example script periodically to backup your docker compose stacks:
#!/bin/bash
# set environment variables
export DOCKER_DIR="/path/to/your/docker"
export BACKUP_DIR="/path/to/your/backup"
# set stack names
stack_names=(
"nginx"
"portainer"
"ghost"
"home-assistant"
)
# create backups
for stack in "${stack_names[@]}"; do
backupdate -s "$stack"
done
# upload backups to cloud storage
rclone sync $BACKUP_DIR dropbox:backup
By default, backupdate will backup all related named volumes and the stacks full working directory. You can use either -l
or --backup-blocklist
if you want to explicitly exclude certain volumes or paths from the backup.
# ignore the plex_media volume and the /plex-cache directory
backupdate -s "plex" \
-d "/path/to/your/docker" \
-b "/path/to/your/backup" \
-l "plex_media,/plex-cache"
# you'll likely want to set the backup blocklist as an environment variable
# when you need to ignore volumes/paths for multiple stacks
export BACKUP_BLOCKLIST="\
plex_media,\
/plex-cache,\
/nginx.conf,\
nginx_logs,\
/data/ghost.yml"
Tip
To avoid being recognised as a volume, paths must start with a /
. Note that paths are interpreted as glob(3)-style wildcard patterns.
Restoring backups isn't currently a process automated by the script. But as backupdate is just executing standard Docker commands, all you'd need to do is follow the official Docker guide on 'Restoring volumes from backups'.
Nope, backupdate does that for you. All containers are stopped automatically before a backup to ensure the data saved is reliable.
The script treats all containers and their volumes the same. Shut them down, back them up, then restart them.
There are alternative tools that do specifically handle database backups with Docker. This would probably be most useful if you don't want any downtime. Or want to create a lot more backups each day, then use another tool with deduplication abilities to save on storage space.