- Shell 100%
| mariadb.conf.d | ||
| .gitignore | ||
| docker_db_backup.sh | ||
| LICENSE | ||
| README.md | ||
Docker Database Backup
A comprehensive Bash script for automating backups of MariaDB, MySQL, and PostgreSQL databases running in Docker containers. Features automatic compression, retention management, and detailed logging.
Features
- Multi-Database Support: Backup MariaDB, MySQL, and PostgreSQL databases
- Docker Integration: Uses
docker execto run backup commands in containers - Automatic Compression: Optional gzip compression of backup files (enabled by default)
- Retention Management: Automatically removes old backups based on configurable retention policy
- Session-Based Organization: Groups backups and logs by timestamp in subdirectories
- Comprehensive Logging: Timestamped console and file logging to track all backup activities
- Comprehensive Logging: Timestamped file logging for each session; console output is only shown when
--verboseis specified or when an error occurs - Dry-Run Mode: Test backups without actually executing Docker commands
- Flexible CLI Options: Override retention, specify backup directory, and enable dry-run mode
- Flexible CLI Options: Override retention, specify backup directory, enable dry-run mode, and enable verbose logging with
--verbose - Error Handling: Robust error handling with detailed error reporting
⚠️ Disclaimer
This script is provided as-is without any guarantees. Use at your own risk.
You MUST validate that backups are being created correctly and that data can be successfully restored before relying on this script for critical data. I cannot guarantee the correctness or integrity of backups created by this script. Always maintain multiple backup strategies and regularly test restore procedures to ensure your data is protected.
Directory Structure
docker-db-backup/
├── docker_db_backup.sh # Main backup script
├── README.md # This file
├── mariadb.conf.d/ # MariaDB database configurations
│ └── example.conf
├── mysql.conf.d/ # MySQL database configurations
│ └── example.conf
├── postgres.conf.d/ # PostgreSQL database configurations
│ └── example.conf
└── backups/ # Backup output directory (user-specified)
├── 20260204_232306/
│ ├── testdb.sql.gz
│ └── backup.log
└── 20260204_232307/
├── testdb.sql.gz
└── backup.log
Installation
- Clone or download the script to your desired location
- Make the script executable:
chmod +x docker_db_backup.sh
Configuration
Database Configuration Files
Create .conf files in the appropriate subdirectory (mariadb.conf.d/, mysql.conf.d/, or postgres.conf.d/) for each database you want to backup.
Each configuration file must define these variables:
# Docker container name running the database
DB_CONTAINER="my_mariadb_container"
# Database user for authentication
DB_USER="backup_user"
# Database password
DB_PASSWORD="secure_password"
# Database name to backup
DB_NAME="my_database"
# Prefix for backup filename (extension will be appended automatically)
DB_BACKUP_FILE_PREFIX="my_database"
Example Configurations
MariaDB Example (mariadb.conf.d/production.conf):
DB_CONTAINER="mariadb_prod"
DB_USER="root"
DB_PASSWORD="root_password"
DB_NAME="production_db"
DB_BACKUP_FILE_PREFIX="production_db"
MySQL Example (mysql.conf.d/staging.conf):
DB_CONTAINER="mysql_staging"
DB_USER="backup"
DB_PASSWORD="backup_pass"
DB_NAME="staging_db"
DB_BACKUP_FILE_PREFIX="staging_db"
PostgreSQL Example (postgres.conf.d/analytics.conf):
DB_CONTAINER="postgres_analytics"
DB_USER="postgres"
DB_PASSWORD="postgres_password"
DB_NAME="analytics"
DB_BACKUP_FILE_PREFIX="analytics"
Usage
Basic Backup
./docker_db_backup.sh --backup-dir ./backups
This will:
- Find all
.conffiles inmariadb.conf.d/,mysql.conf.d/, andpostgres.conf.d/ - Backup each configured database
- Compress backups with gzip (default)
- Keep the last 10 backup sessions (default)
- Create a timestamped subdirectory in
./backups/with all files from this run
Quick Examples
# Basic backup
./docker_db_backup.sh --backup-dir ./backups
# Dry-run (no Docker execution)
./docker_db_backup.sh --dry-run --backup-dir ./backups
# Verbose (print live logs to console)
./docker_db_backup.sh --verbose --backup-dir ./backups
# short form for verbose
./docker_db_backup.sh -v --backup-dir ./backups
# Use short form for backup directory
./docker_db_backup.sh -d /mnt/backups
# Show version (long and short)
./docker_db_backup.sh --version
./docker_db_backup.sh -V
# View help
./docker_db_backup.sh --help
Backup to Specific Directory
./docker_db_backup.sh --backup-dir /mnt/backups
Or use the short form:
./docker_db_backup.sh -d /mnt/backups
Test Backups (Dry-Run Mode)
Test the script without actually executing Docker commands:
./docker_db_backup.sh --dry-run --backup-dir ./backups
Output will show what would be backed up without creating the actual Docker connections.
Override Retention Policy
Keep only the 5 most recent backup sessions:
./docker_db_backup.sh --backup-dir ./backups --max-backups 5
Or use the = syntax:
./docker_db_backup.sh --backup-dir ./backups --max-backups=5
Combine Options
./docker_db_backup.sh --dry-run --backup-dir ./backups --max-backups 3
This will:
- Run in dry-run mode (no Docker execution)
- Use
./backupsas output directory - Keep only 3 most recent sessions
View Help
./docker_db_backup.sh --help
Display Version
Show the script name and version (short and long forms are supported):
./docker_db_backup.sh --version
# or (short form)
./docker_db_backup.sh -V
Example output:
docker_db_backup.sh 0.1.0
Verbose Output
Print live logs to the console while the script runs (otherwise logs are only written to the session backup.log). Also note that on error the script will dump the session log to stderr so failures are visible even when not running verbose.
./docker_db_backup.sh --verbose --backup-dir ./backups
# or short form
./docker_db_backup.sh -v --backup-dir ./backups
Environment Variables
You can also set configuration via environment variables:
# Enable/disable compression (default: true)
COMPRESS_BACKUPS=false ./docker_db_backup.sh --backup-dir ./backups
# Set retention policy (default: 10)
MAX_BACKUPS=7 ./docker_db_backup.sh --backup-dir ./backups
Note: CLI flags take precedence over environment variables.
Output Files
Each backup run creates a timestamped session directory containing:
- Backup Files:
{DB_BACKUP_FILE_PREFIX}.sql.gz(or.sqlif compression disabled) - Log File:
backup.logwith detailed backup operation logs
Example directory structure after 3 backups:
backups/
├── 20260204_232306/
│ ├── production_db.sql.gz
│ ├── staging_db.sql.gz
│ └── backup.log
├── 20260204_232307/
│ ├── production_db.sql.gz
│ ├── staging_db.sql.gz
│ └── backup.log
└── 20260204_232308/
├── production_db.sql.gz
├── staging_db.sql.gz
└── backup.log
Automatic Cleanup
The script automatically manages disk usage by:
- Creating timestamped session directories (YYYYMMDD_HHMMSS format)
- Keeping the
MAX_BACKUPSmost recent session directories - Removing older session directories entirely (including all files)
For example, with --max-backups 2, the script will keep only the 2 newest session directories and delete older ones.
Log Files
Each backup session creates a backup.log file in the session directory with timestamped entries:
[2026-02-04 23:23:06] [INFO] Script: docker_db_backup.sh Version: 0.1.0
[2026-02-04 23:23:06] [INFO] Session: 20260204_232306 Directory: /opt/db-backup/backup
s/20260204_232306
[2026-02-04 23:23:06] [INFO] Starting database backup process...
[2026-02-04 23:23:06] [INFO] Maximum backups per database: 3
[2026-02-04 23:23:06] [INFO] Processing MariaDB databases...
[2026-02-04 23:23:06] [INFO] Starting MariaDB backup for: production_db
[2026-02-04 23:23:06] [SUCCESS] MariaDB backup completed: /backups/20260204_232306/production_db.sql.gz
[2026-02-04 23:23:06] [INFO] Cleaning up old backup sessions...
[2026-02-04 23:23:06] [INFO] Backup Summary:
[2026-02-04 23:23:06] [INFO] Total: 1
[2026-02-04 23:23:06] [INFO] Successful: 1
[2026-02-04 23:23:06] [INFO] Failed: 0
Scheduling with Cron
Schedule daily backups at 2 AM:
0 2 * * * /path/to/docker-db-backup/docker_db_backup.sh --backup-dir /mnt/backups >> /var/log/db-backups.log 2>&1
Or with retention management (keep 30 days of daily backups):
0 2 * * * /path/to/docker-db-backup/docker_db_backup.sh --backup-dir /mnt/backups --max-backups 30 >> /var/log/db-backups.log 2>&1
Backup Strategy Recommendations
Daily Backups (Keep 14 Days)
0 2 * * * /path/to/docker-db-backup/docker_db_backup.sh --backup-dir /backups/daily --max-backups 14
Weekly Backups (Keep 12 Weeks)
0 3 * * 0 /path/to/docker-db-backup/docker_db_backup.sh --backup-dir /backups/weekly --max-backups 12
Monthly Backups (Keep 24 Months)
0 4 1 * * /path/to/docker-db-backup/docker_db_backup.sh --backup-dir /backups/monthly --max-backups 24
Compression
By default, backups are compressed with gzip to save disk space. To disable compression:
COMPRESS_BACKUPS=false ./docker_db_backup.sh --backup-dir ./backups
Compressed files: database.sql.gz
Uncompressed files: database.sql
Error Handling
The script includes comprehensive error handling:
- Missing Configuration: Reports missing required variables
- Docker Connection Failures: Logs specific errors and continues with other databases
- File Permission Issues: Handles backup directory creation and permissions
- Invalid CLI Arguments: Clear error messages for incorrect flags
Exit code 1 is returned if any backup fails.
Requirements
- Bash 4.0+ (uses
set -euo pipefail) - Docker CLI: Must be installed and have access to database containers
- Database Tools:
mariadb-dump(for MariaDB backups)mysqldump(for MySQL backups)pg_dump(for PostgreSQL backups)
- Standard Tools:
find,grep,sed,awk,date
Troubleshooting
Docker Connection Errors
Ensure the Docker container names in your .conf files are correct:
docker ps --filter "name=container_name"
Permission Denied
Ensure you have write permissions to the backup directory:
mkdir -p ./backups && chmod 755 ./backups
Backup File Not Created
Check the log file for details:
cat backups/YYYYMMDD_HHMMSS/backup.log
Compression Issues
If gzip is unavailable, disable compression:
COMPRESS_BACKUPS=false ./docker_db_backup.sh --backup-dir ./backups
License
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
Support
For issues, questions, or improvements, refer to the script comments and log files for debugging information. If that doesn't help then create an new issue!