Detailed instructions for configuring and using the Docker Stack Backup & Restore toolkit.
- Initial Setup
- Configuration
- Running Backups
- Restoring from Backup
- Verification & Maintenance
- Automation
# Verify Docker is installed and running
docker --version
docker compose version
# Check that Dockhand is managing your stacks
ls -la /path/to/dockhand/$(hostname)
# Ensure appdata directory exists
ls -la /mnt/datastor/appdata# Clone the repository
cd ~
git clone git@github.com:TadMSTR/docker-stack-backup.git
cd docker-stack-backup
# Make scripts executable
chmod +x *.sh
# Install to system
sudo cp *.sh /usr/local/bin/
# Create log directory (if it doesn't exist)
sudo touch /var/log/docker-backup.log
sudo touch /var/log/docker-backup-manual.log
sudo touch /var/log/docker-restore.logEdit each script and update these paths:
docker-stack-backup.sh:
DOCKHAND_BASE="/path/to/dockhand"
APPDATA_PATH="/mnt/datastor/appdata"
BACKUP_DEST="/mnt/backup/docker-backups"docker-stack-backup-manual.sh:
# Same settings as above
DOCKHAND_BASE="/path/to/dockhand"
APPDATA_PATH="/mnt/datastor/appdata"
BACKUP_DEST="/mnt/backup/docker-backups"docker-stack-restore.sh:
BACKUP_BASE="/mnt/backup/docker-backups"
DOCKHAND_BASE="/path/to/dockhand"
APPDATA_PATH="/mnt/datastor/appdata"If running on TrueNAS and backing up locally:
BACKUP_DEST="/mnt/pool/backup/docker-backups"# On Debian, mount TrueNAS share
sudo mkdir -p /mnt/backup
# Add to /etc/fstab
echo "truenas-ip:/mnt/pool/backup /mnt/backup nfs defaults 0 0" | sudo tee -a /etc/fstab
# Mount it
sudo mount /mnt/backup
# Set in script
BACKUP_DEST="/mnt/backup/docker-backups"# Install CIFS utils
sudo apt-get install cifs-utils
# Create credentials file
sudo cat > /root/.smbcredentials << EOF
username=your_username
password=your_password
EOF
sudo chmod 600 /root/.smbcredentials
# Add to /etc/fstab
echo "//truenas-ip/backup /mnt/backup cifs credentials=/root/.smbcredentials,uid=0,gid=0 0 0" | sudo tee -a /etc/fstab
# Mount it
sudo mount /mnt/backupSee NOTIFICATIONS.md for detailed configuration of:
- Ntfy
- Pushover
- Email (including Proton Mail Bridge)
# Run manually
sudo docker-stack-backup.sh
# Check the log
tail -f /var/log/docker-backup.logThis will:
- Scan all Dockhand stacks
- Backup only those with appdata bind mounts
- Preserve container run states
- Send notifications (if configured)
# Run interactive mode
sudo docker-stack-backup-manual.shExample session:
▶ Step 1: Select Stacks to Backup
1) plex (appdata: 45G, 3 running)
2) sonarr (appdata: 2.1G, 1 running)
3) nginx (no appdata, stopped)
4) radarr (appdata: 1.8G, 1 running)
Select stacks to backup: 1 2 4
✓ Selected 3 stack(s):
- plex
- sonarr
- radarr
▶ Step 2: Backup Summary
[Shows details and asks for confirmation]
▶ Step 3: Performing Backup
[Backs up each stack with progress]
Selection tips:
- Individual:
1 3 5 - Ranges:
1-3 5-7 - All with appdata:
all
# Run the restore wizard
sudo docker-stack-restore.shWizard flow:
Step 1: Select Host
Available hosts:
1) debian-docker
2) truenas-docker
Select host number [1]: 1
Step 2: Select Backup Date
Available backups (newest first):
1) December 03, 2024 at 02:00:15 (7 stacks)
2) December 02, 2024 at 02:00:12 (7 stacks)
Select backup number [1]: 1
Step 3: Select Stack
Available stacks:
1) plex (45G)
2) sonarr (2.1G)
3) radarr (1.8G)
Select stack number [1]: 1
Step 4: Preview Contents
Contents of backup:
─────────────────────────────────────────────
docker-compose.yml
.env
plex/...
─────────────────────────────────────────────
Proceed with restore? [y/N]: y
Step 5: Handle Conflicts
If stack already exists:
⚠ Conflicts detected!
Choose how to proceed:
1) Stop containers and overwrite everything (destructive)
2) Backup existing data first, then restore
3) Cancel restore
Select option [3]: 2
Step 6: Restore
Creating safety backup in /tmp/docker-restore-backup-...
Stopping existing stack
Restoring files...
✓ Files restored successfully
Start the stack now? [y/N]: y
✓ Stack started successfully
# List all backups
backup-verify.sh --list
# Verify all backup files
backup-verify.sh --verify
# Show statistics
backup-verify.sh --stats
# Filter by hostname
backup-verify.sh --list -h debian-docker# Remove backups older than 30 days (default)
sudo cleanup-old-backups.sh
# View what would be deleted first
find /mnt/backup/docker-backups -type d -mtime +30
# Adjust retention in the script
# Edit RETENTION_DAYS in cleanup-old-backups.sh# Edit root's crontab
sudo crontab -e
# Add daily backup at 2 AM
0 2 * * * /usr/local/bin/docker-stack-backup.sh
# Or with output logging
0 2 * * * /usr/local/bin/docker-stack-backup.sh >> /var/log/docker-backup-cron.log 2>&1# Add to root's crontab
# Weekly cleanup on Sunday at 3 AM
0 3 * * 0 /usr/local/bin/cleanup-old-backups.sh# Add to root's crontab
# Monthly verification on 1st at 4 AM
0 4 1 * * /usr/local/bin/backup-verify.sh --verify >> /var/log/backup-verify.log 2>&1sudo crontab -eAdd these lines:
# Docker Stack Backups
0 2 * * * /usr/local/bin/docker-stack-backup.sh
0 3 * * 0 /usr/local/bin/cleanup-old-backups.sh
0 4 1 * * /usr/local/bin/backup-verify.sh --verify >> /var/log/backup-verify.log 2>&1- Large appdata directories (50GB+) can take several minutes to backup
- Consider backing up large stacks during low-usage hours
- NFS is faster than SMB for large transfers
- Use local backups when possible, then sync to remote
- Always test restore on non-production stacks first
- Keep at least 7 days of backups before deleting
- Verify backups monthly
- Test notification delivery
- Document your stack configurations
- Use descriptive stack names in Dockhand
- Keep related containers in the same stack
- Document dependencies between stacks
- Maintain a recovery runbook
- Set up failure notifications (high priority)
- Monitor backup sizes for unexpected changes
- Check logs weekly:
tail -100 /var/log/docker-backup.log - Verify backup destinations have adequate space
Problem: "No stacks found"
# Verify Dockhand path
ls -la /path/to/dockhand/$(hostname)
# Check hostname matches directory name
hostnameProblem: "Permission denied"
# Ensure running as root
sudo -i
# Check file permissions
ls -la /usr/local/bin/docker-stack-backup.shProblem: "Stack won't restart"
# Check Docker status
systemctl status docker
# View stack logs
cd /path/to/dockhand/$(hostname)/stack-name
docker compose logs
# Check for port conflicts
docker compose psProblem: "Backup destination not writable"
# Check mount
df -h /mnt/backup
mount | grep backup
# Test write access
touch /mnt/backup/test && rm /mnt/backup/test- Check the logs:
/var/log/docker-backup.log - Run scripts with bash debug:
bash -x /usr/local/bin/docker-stack-backup.sh - Verify all paths in configuration
- Test individual components (Docker, mounts, notifications)
- Open an issue on GitHub with log excerpts
- ✅ Complete initial setup
- ✅ Configure backup destination
- ✅ Test manual backup
- ✅ Set up notifications
- ✅ Schedule automated backups
- ✅ Test restore procedure
- ✅ Configure cleanup automation
- ✅ Document your specific setup
For notification setup, see NOTIFICATIONS.md