A comprehensive 3-stage backup solution for Docker compose stacks using restic for local backups and rclone for cloud synchronization. The tool uses docker compose down/up -d for robust container management, ensuring data consistency during backups. Only containers that were running before backup are restarted afterward. Supports backing up stacks from your main Docker directory as well as external paths anywhere on your filesystem.
# 1. Build the binary
go build -o bin/backup-tui ./cmd/backup-tui
# 2. Configure (edit config/config.ini)
cp config/config.ini.template config/config.ini
nano config/config.ini
# 3. Select directories for backup
./bin/backup-tui # Launch TUI
# 4. Run backup (dry-run first)
./bin/backup-tui backup --dry-run -v
# 5. Run actual backup
./bin/backup-tui backup -v
# 6. (Optional) Cloud sync
./bin/backup-tui sync # Upload to cloud
./bin/backup-tui restore # Restore from cloudStage 1: Local Restic Backup → Stage 2: Cloud Sync → Stage 3: Disaster Recovery
All three stages are managed by a single unified binary: backup-tui
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Docker Stacks │ │ Restic Repository │ │ Cloud Storage │
│ (DOCKER_STACKS_DIR)│ │ (RESTIC_REPOSITORY)│ │ (RCLONE_REMOTE:PATH)│
└──────────┬──────────┘ └──────────┬──────────┘ └──────────┬──────────┘
│ │ │
│ Stage 1: backup │ Stage 2: sync │
│ (restic backup) │ (rclone sync) │
├──────────────────────────►├──────────────────────────►│
│ │ │
│ │ Stage 3: restore │
│ │◄──────────────────────────┤
│ │ (rclone sync) │
│ │ │
└──────────────────────────────────────┴───────────────────────────┘
- Stage 1: Uses
docker compose downto stop containers, backs up stack directories to local restic repository, usesdocker compose up -dto restart containers - Stage 2: Syncs the entire restic repository to cloud storage (preserves deduplication and snapshots)
- Stage 3: Restores the restic repository from cloud to a local path for disaster recovery
The backup-tui binary provides both an interactive TUI and headless CLI commands:
# Interactive TUI mode (default)
./bin/backup-tui
# Headless CLI commands
./bin/backup-tui backup # Stage 1: Local backup
./bin/backup-tui backup --dry-run # Preview backup
./bin/backup-tui sync # Stage 2: Cloud sync
./bin/backup-tui sync --dry-run # Preview sync
./bin/backup-tui restore [PATH] # Stage 3: Restore from cloud
./bin/backup-tui status # Show system status
./bin/backup-tui validate # Validate configuration
./bin/backup-tui list-backups # List backup snapshots
./bin/backup-tui health # Run health diagnostics
# Common flags
-v, --verbose Enable verbose output
-n, --dry-run Perform dry run (no changes)
-c, --config Path to config file
-h, --help Show help message├── bin/ # Executables
│ └── backup-tui # Unified backup tool (Go binary)
├── cmd/
│ └── backup-tui/ # Main entry point source
├── internal/ # Go packages
│ ├── config/ # INI config parser
│ ├── backup/ # Docker + restic operations
│ ├── cloud/ # rclone sync/restore
│ ├── dirlist/ # Directory management
│ ├── tui/ # TUI screens
│ └── util/ # Utilities (exec, lock, log)
├── config/ # Configuration files
│ ├── config.ini # Main configuration
│ └── config.ini.template # Template with comments
├── locks/ # Lock files
├── logs/ # Runtime logs
├── dirlist # Directory enable/disable list
└── go.mod # Go module
The configuration uses INI-style sections:
# config/config.ini
[docker]
DOCKER_STACKS_DIR=/opt/docker-stacks
DOCKER_TIMEOUT=300
[local_backup]
RESTIC_REPOSITORY=/mnt/backup/restic-repo
RESTIC_PASSWORD=your-password
KEEP_DAILY=7
KEEP_WEEKLY=4
AUTO_PRUNE=true
[cloud_sync]
RCLONE_REMOTE=backblaze
RCLONE_PATH=/backup/restic
TRANSFERS=4-
Copy the template:
cp config/config.ini.template config/config.ini chmod 600 config/config.ini
-
Edit with your settings:
nano config/config.ini
-
Configure rclone for cloud storage (optional):
rclone config
-
Validate configuration:
./bin/backup-tui validate
- Unified Binary - Single tool for all backup operations
- Interactive TUI - Menu-driven interface with Bubbletea
- Headless CLI - Full scripting/cron support
- Selective Backup - Choose which Docker stacks to backup
- External Paths - Add Docker stacks from anywhere on your filesystem
- Robust Container Management - Uses
docker compose down/up -dfor clean container lifecycle - Smart State Tracking - Only restarts containers that were running before backup
- Defensive StateUnknown Handling - Restarts containers when state is uncertain
- Process Group Timeout - Kills entire process tree on timeout (no hung processes)
- Verification with Retry - Confirms containers stopped/started with automatic retries
- Retry Logic - Automatic retries for cloud operations
- File Locking - Prevents concurrent operations
- Signal Handling - Graceful shutdown with container recovery
- Dry Run Mode - Preview operations before execution
- Comprehensive Logging - Detailed logs to file and console
Note: The installation commands below are for Debian-based distributions (Ubuntu, Debian, etc.) using the
aptpackage manager. For other distributions, use your system's package manager or install from source.
Restic is the backup engine that creates deduplicated, encrypted snapshots.
📖 Documentation: restic.readthedocs.io
# Install restic (Debian/Ubuntu)
sudo apt-get install restic
# Initialize your restic repository (first time only)
export RESTIC_PASSWORD="your-secure-password"
restic init -r /path/to/your/restic-repo
# Verify it works
restic -r /path/to/your/restic-repo snapshotsImportant restic configuration:
RESTIC_REPOSITORY- Path to your restic repo (local path, SFTP, S3, etc.)RESTIC_PASSWORD- Repository encryption password (store securely!)- Alternatively use
RESTIC_PASSWORD_FILEorRESTIC_PASSWORD_COMMAND
# Debian/Ubuntu
sudo apt-get install docker.io docker-compose-v2Rclone enables Stage 2 (upload) and Stage 3 (restore) cloud operations.
📖 Documentation: rclone.org/docs
# Install rclone (Debian/Ubuntu)
sudo apt-get install rclone
# Configure a cloud remote (interactive wizard)
rclone config
# Example: Configure Backblaze B2
# 1. Run: rclone config
# 2. Choose 'n' for new remote
# 3. Name it (e.g., 'backblaze')
# 4. Choose provider (e.g., 'b2' for Backblaze)
# 5. Enter your account ID and application key
# 6. Accept defaults for remaining options
# Verify your remote works
rclone lsd backblaze:
# Test connectivity to your backup bucket
rclone ls backblaze:your-bucket-nameCommon rclone remotes:
- Backblaze B2:
rclone config→ typeb2 - AWS S3:
rclone config→ types3 - Google Drive:
rclone config→ typedrive - SFTP:
rclone config→ typesftp
go build -o bin/backup-tui ./cmd/backup-tui/MAIN MENU
├── 1. Backup (Stage 1: Local)
│ ├── Quick Backup
│ ├── Dry Run
│ └── List Snapshots
├── 2. Cloud Sync (Stage 2: Upload)
│ ├── Quick Sync
│ ├── Dry Run
│ └── Test Connectivity
├── 3. Cloud Restore (Stage 3: Download)
│ ├── Restore Repository
│ └── Test Connectivity
├── 4. Directory Management
│ ├── Toggle directories on/off
│ ├── Add external paths (X key)
│ └── Remove external paths (D key)
├── 5. Status & Logs
├── Q. Quick Backup (shortcut)
├── S. Quick Status (shortcut)
└── 0. Exit
The tool automatically discovers Docker stacks in your DOCKER_STACKS_DIR. You can also add external paths - Docker compose stacks located anywhere on your filesystem.
- Open the TUI:
./bin/backup-tui - Go to Directory Management (option 4)
- Press X to open the file picker
- Navigate to your Docker stack directory (must contain
docker-compose.yml) - Press A to add the current directory
Alernatively, manually add full paths to directories containing docker compose files to your dirlist file. See below.
File picker controls:
↑/↓- Navigate file listEnter- Enter directoryBackspace- Go up a directory levelA- Add current directory as external pathESC- Cancel
In the Directory Management screen:
↑/↓- Navigate listEnter/Space- Toggle backup on/offS- Save changesA- Enable allN- Disable allX- Add external pathD- Remove external path (external paths only)
External paths are marked with [EXT] in the directory list.
The dirlist file stores your backup selections.
This file is auto-generated/updated when you use the directory management tool in the TUI:
# Discovered directories (relative to DOCKER_STACKS_DIR)
my-stack=true
another-stack=false
# External directories (absolute paths)
/home/user/projects/docker-app=true
/opt/custom-stack=true# Daily backup at 2 AM
0 2 * * * /path/to/backup-tui backup -v >> /var/log/backup.log 2>&1
# Weekly cloud sync on Sundays at 3 AM
0 3 * * 0 /path/to/backup-tui sync -v >> /var/log/backup-sync.log 2>&1For detailed reference, see:
- Configuration Guide - All config options, password methods, example configs
- Usage Guide - CLI commands, workflows, troubleshooting
- Architecture - Technical internals, container management, security model
Self-Contained Design: All configuration and data files are kept within this directory for complete portability.