dostic is a lightweight backup solution that combines Docker and Restic to provide seamless backups of Docker volumes, databases, and folders. The name reflects its primary purpose: Docker + Restic.
- Native Docker Volume Support - Directly backup named Docker volumes without stopping containers
- Automatic Volume Discovery - Finds and backs up all named volumes automatically
- Flexible Exclusion - Exclude volumes by exact name or regex pattern
- Individual Volume Snapshots - Each volume gets its own snapshot for selective restore
- PostgreSQL Support - Automatic
pg_dumpallwith multiple user fallback strategies - MySQL/MariaDB Support - Automatic
mysqldumpfor complete database exports - Container-Specific Dumps - Each database container is backed up separately
- Zero Downtime - Databases remain online during backup
- Folder Archiving - Backup any local directory (nice-to-have feature)
- S3-Compatible Storage - Support for AWS S3, Backblaze B2, MinIO, etc.
- Local Storage - Simple file-system based repositories
- Pure Restic Repository - Creates standard Restic repositories for maximum compatibility
- Tagged Snapshots - Organized tagging system for easy snapshot identification
Minimal Requirements:
- β Docker (for running containers)
- β Bash (for scripting)
- β No Restic installation required! (runs in Docker container)
Key Advantages:
- π³ Docker-Native - Built specifically for Docker environments
- πΎ Database-Aware - Proper dump handling, not just file copying
- π¦ Pure Restic - Standard Restic repository format, use any Restic client
- π§ Zero Dependencies - Only Docker and Bash needed
- π·οΈ Smart Tagging - Clear organization with
postgres/container-name,volume/volume-name, etc. - π Standard Workflows - Backup, restore, forget, prune - all familiar Restic commands
# Clone the repository
git clone https://github.com/yourusername/dostic.git
cd dostic
# Create configuration file
cp .dostic.env.example .dostic.env
chmod 600 .dostic.env
# Edit configuration
vim .dostic.envCreate a .dostic.env file in your working directory:
# Repository location (local path)
REPOSITORY="/mnt/backups/my-restic-repo"
# Password file (must have 0600 or 0700 permissions)
RESTIC_PASSWORD_FILE="/path/to/password-file"
# Cache volume name (optional, default: dostic_cache)
CACHE_VOLUME_NAME="dostic_cache"
# Backup configuration (optional)
BACKUP_BASEDIR="/tmp/backups"
HOST="$(hostname)"
# Folders to backup (optional, comma-separated)
# Format: /path/to/folder:tag-name or just /path/to/folder
BACKUP_FOLDERS="/etc:system-config,/home/user/data:user-data"
# Volume exclusions (optional)
EXCLUDE_VOLUMES="temp-volume,cache-volume"
EXCLUDE_VOLUMES_REGEX="^test-.*|.*-tmp$"
# Retention policy (optional, defaults shown)
KEEP_DAILY=14
KEEP_WEEKLY=12
KEEP_MONTHLY=12
KEEP_YEARLY=5# Repository location (S3)
REPOSITORY="s3:s3.amazonaws.com/my-bucket/restic-repo"
# AWS credentials
AWS_ACCESS_KEY_ID="your-access-key"
AWS_SECRET_ACCESS_KEY="your-secret-key"
# Password file
RESTIC_PASSWORD_FILE="/path/to/password-file"
# Other settings...# Repository location
REPOSITORY="s3:s3.us-west-002.backblazeb2.com/my-bucket/restic-repo"
# Backblaze credentials
AWS_ACCESS_KEY_ID="your-b2-key-id"
AWS_SECRET_ACCESS_KEY="your-b2-application-key"
# Password file
RESTIC_PASSWORD_FILE="/path/to/password-file"./dostic.sh initBacks up all PostgreSQL, MySQL databases, Docker volumes, and configured folders:
./dostic.sh backup# Only PostgreSQL databases
./dostic.sh backup-postgres
# Only MySQL databases
./dostic.sh backup-mysql
# Only Docker volumes
./dostic.sh backup-volumes
# Only folders
./dostic.sh backup-folders./dostic.sh snapshotsExample output:
ID Time Host Tags Paths
-------------------------------------------------------------------------
a1b2c3d4 2025-10-05 10:00:00 alice postgres/my-db /backups/postgres/my-db
e5f6g7h8 2025-10-05 10:01:00 alice mysql/app-db /backups/mysql/app-db
i9j0k1l2 2025-10-05 10:02:00 alice volume/app-data /backups/volumes/app-data
m3n4o5p6 2025-10-05 10:03:00 alice folders/etc-config /backups/folders/etc-config
# Restore latest snapshot
./dostic.sh restore latest /path/to/restore/target
# Restore specific snapshot
./dostic.sh restore a1b2c3d4 /path/to/restore/target./dostic.sh stats# Apply retention policy and prune in one step
./dostic.sh forget
# Manual prune (only if needed)
./dostic.sh prune./dostic.sh checkIf a backup was interrupted:
./dostic.sh unlockAll backups are organized under /backups/ in the container:
/backups/
βββ postgres/
β βββ container-name/
β βββ container-name.dump.sql
βββ mysql/
β βββ container-name/
β βββ container-name.dump.sql
βββ volumes/
β βββ volume-name/
β βββ [volume contents]
βββ folders/
βββ folder-tag/
βββ [folder contents]
- PostgreSQL:
postgres/container-name - MySQL:
mysql/container-name - Docker Volumes:
volume/volume-name - Folders:
folders/folder-tag
- PostgreSQL: Detects containers with port 5432 exposed
- MySQL: Detects containers with port 3306 exposed
- Docker Volumes: Lists all named volumes (excludes hash-only volumes)
PostgreSQL:
- Detects all PostgreSQL containers
- Tries multiple user strategies:
postgres,${POSTGRES_USER},$(whoami), default - Runs
pg_dumpallinside the container - Copies dump to host
- Creates Restic snapshot
MySQL:
- Detects all MySQL containers
- Runs
mysqldumpwith${MYSQL_ROOT_PASSWORD}from container environment - Copies dump to host
- Creates Restic snapshot
The password file must have strict permissions:
chmod 600 /path/to/password-filedostic validates this on startup and will refuse to run with insecure permissions.
- Database passwords are read from container environment variables
- No passwords are exposed in command line arguments
- All sensitive data is mounted read-only in backup containers
Create a cron job:
# /etc/cron.d/dostic-backup
0 2 * * * root cd /path/to/dostic && ./dostic.sh backup >> /var/log/dostic-backup.log 2>&1Edit your .dostic.env:
# Exclude test databases
EXCLUDE_VOLUMES_REGEX="^test-.*"# 1. Find the snapshot
./dostic.sh snapshots | grep postgres/my-db
# 2. Restore to temporary location
./dostic.sh restore a1b2c3d4 /tmp/restore
# 3. Import the dump
docker exec -i my-db psql -U postgres < /tmp/restore/backups/postgres/my-db/my-db.dump.sql# 1. Stop the container using the volume
docker stop my-app
# 2. Restore the snapshot
./dostic.sh restore e5f6g7h8 /tmp/restore
# 3. Copy data back to volume
docker run --rm -v my-volume:/volume -v /tmp/restore/backups/volumes/my-volume:/backup alpine cp -r /backup/. /volume/
# 4. Start the container
docker start my-appchmod 600 /path/to/password-fileInitialize the repository first:
./dostic.sh initCheck if the container is running and the database is accessible:
docker exec -it container-name psql -U postgres -c '\l' # PostgreSQL
docker exec -it container-name mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "SHOW DATABASES;" # MySQLIf a backup was interrupted:
./dostic.sh unlockContributions are welcome! Please feel free to submit issues or pull requests.
MIT License - see LICENSE file for details.
Copyright (c) 2025 Peter Kranz
- Restic - The excellent backup program that powers dostic
- Built with β€οΈ for the Docker community
Note: dostic creates standard Restic repositories. You can use the official Restic client to access, restore, or manage backups created by dostic. The Docker wrapper is only needed for the backup creation process.