Sign inSign up

williarin/secure-mysql-backups

By williarin

Updated about 4 years ago

Long-term retention for secure MySQL backups

Image
0

5.0K

williarin/secure-mysql-backups repository overview

Long-term retention for secure MySQL backups

Gihub repo: https://github.com/williarin/secure-mysql-backups

This Docker image will backup your MySQL/MariaDB databases following the Grandfather-Father-Son (GFS) retention scheme.

Features

  • GFS backups retention scheme
  • AES256 encryption/decryption
  • Single or multiple databases backups
  • Grouped or individual archives
  • Parallelized compression

GFS retention scheme

This means that you'll always have:

  • A backup for every day of the last week (6)
  • A backup for every week of the last month (4)
  • A backup for every month of the last year (12)
  • A backup for every previous year (unlimited)

For a 100MB backup, it will cost you around 2GB for the current year + 100MB for each previous year.

In SuperSafe mode, you'll have:

  • A backup for every day of the last month (28~31)
  • A backup for every week of the last year (48)
  • A backup for every previous year (unlimited)

For a 100MB backup, backups will cost you around 8GB for the current year + 100MB for each previous year.

Backups are run by default every day at 00:00 UTC.

Usage

docker run -d \
    --network mysql \
    -e MYSQL_USER=root \
    -e MYSQL_PASSWORD=password \
    -e CHOWN_FILES='1000:1000' \
    -e MAX_CPU=4 \
    -v /path/to/backups:/backup \
    williarin/secure-mysql-backups:1

Variables

All variables can be appended with _FILE in case you want to populate them from secrets.

As an example, you can use: MYSQL_PASSWORD_FILE=/run/secret/mysql-root-password

VariableDescriptionDefault
SUPERSAFE_MODERun backups in SuperSafe mode. This means many more backups (see details).false
MYSQL_HOSTThe host of your MySQL/MariaDB database.mysql
MYSQL_PORTThe port number of your MySQL/MariaDB database.3306
MYSQL_USERThe username of your MySQL/MariaDB database.root
MYSQL_PASSWORDThe username of your MySQL/MariaDB database.empty
MYSQL_DATABASEThe database name to dump, or a space separated list of databases to dump.all user databases
CRON_MINUTEThe minute interval of cron job to dump database. Don't use CRON_TIME if you use this.0
CRON_HOURThe hour interval of cron job to dump database. Don't use CRON_TIME if you use this.0
CRON_TIMEThe interval of cron job to dump database. Use it to override the cron job. Warning: overriding this variable my lead to inconsistent GFS backups.0 0 * * *
BACKUP_NAMEThe name of the backup. It will produce files like main-backup.day1-Monday.tgzmain-backup
INDIVIDUAL_BACKUPSSet to true if you want to create one archive per database, instead of a global archive for all databases. It will produce files like main-backup.my_db.day1-Monday.tgzfalse
MAX_CPUMaximum CPU count to use while compressing the archive.all CPUs
CHOWN_FILESSet permissions to the created archives and files within them.root:root
AES_PASSPHRASEIf set, all archives will be encrypted with AES-256-CBC algorithm.empty

Manually run a backup

If you want to bypass the cron and run a manual backup, run this command:

docker run --rm \
    --network mysql \
    -e MYSQL_USER=root \
    -e MYSQL_PASSWORD=password \
    -e CHOWN_FILES='1000:1000' \
    -e MAX_CPU=4 \
    -v /path/to/backups:/backup \
    williarin/secure-mysql-backups:1 \
    backup

This will create a new file named main-backup.day3-Wednesday.tgz which you can untar normally.

Decrypting encrypted backup

Currently there's not yet an automatic backup restoration command.

In the meantime, use this script to decrypt an archive:

docker run --rm \
    -e AES_PASSPHRASE=my_passphrase \
    -e CHOWN_FILES='1000:1000' \
    -v /path/to/backups:/backup \
    williarin/secure-mysql-backups:1 \
    decrypt main-backup.day3-Wednesday.tgz.aes

This will create a new file named main-backup.day3-Wednesday.tgz which you can untar normally.

Usage with Docker Compose

version: '3.8'

services:
    database:
        image: mysql:8
        restart: 'no'
        environment:
            - MYSQL_DATABASE=my_db
            - MYSQL_ROOT_PASSWORD=root

    backup:
        image: williarin/secure-mysql-backups:1
        restart: 'no'
        volumes:
            - ./backup:/backup
        environment:
            MYSQL_HOST: database
            MYSQL_USER: root
            MYSQL_PASSWORD: root
            CHOWN_FILES: '1000:1000'
            MAX_CPU: 4
            AES_PASSPHRASE: my_passphrase

Then you can run a manual backup like this:

docker compose run --rm backup backup

Or decrypting an archive:

docker compose run --rm backup decrypt main-backup.day3-Wednesday.tgz.aes

Available tags

Use a numbered tag if you want to avoid BC breaks.

Tag summary

Content type

Image

Digest

sha256:9471cc6dd

Size

13.7 MB

Last updated

about 4 years ago

docker pull williarin/secure-mysql-backups