Container image for creating cron-scheduled backups with borg backup based on Alpine Linux.

toastie89 ba84dbd11c set hostname in PROM_URL as variable 2 months ago
build 504924e297 initial 2 months ago
scripts 1e3065804d added more comments 2 months ago
.env.template ba84dbd11c set hostname in PROM_URL as variable 2 months ago
.gitignore 504924e297 initial 2 months ago
README.md 06726ed8f8 fixed spelling mistakes 2 months ago
docker-compose.restore.yml 504924e297 initial 2 months ago
docker-compose.yml ba84dbd11c set hostname in PROM_URL as variable 2 months ago

README.md

Borg Backup

Container image for creating cron-scheduled backups with borg backup based on Alpine Linux.

Borg key features

  • Space efficient storage through deduplication and compression.
  • Fast backup runs and pruning of old backups.
  • Encryption to allow backup storage in insecure offsite-locations.
  • FUSE mount support for easy recovery.
  • Focus on local backups. For cloud backups, restic might be an alternative.

Installation & Setup

  1. Clone this repository
  2. Build the container image from ./build/Dockerfile:
    • docker compose build
  3. Configure backup in .env. Copy and adapt .env.template which describes all variables:
    • cp .env.template .env && vi .env
  4. Borg needs an initial init of the backup archive. To create an encrypted archive run:
    • docker exec --rm -it borg bash -c "borg init --encryption repokey-blake2"
  5. Finally, start the container and wait for cron to start the backup:
    • docker compose up -d
  6. (Optional) Run an unscheduled backup:
    • docker exec borg bash -c 'do-backup.sh'
  7. Upgrade:
    • Alpine and Borg versions are hard-coded in docker-compose.yml.
    • Borg Release Notes should be consulted for breaking changes.

Preparation for disaster recovery

Very IMPORTANT! The following files MUST be stored along with the backup to enable decryption of the backup data:

  • .env-file containing the passphrase
  • Keyfile(s), stored in ./data/.config/borg/keys/

Backup restore

  1. Stop the backup container
    • docker compose down
  2. Run the container with FUSE-support and enter an interactive shell:
    • docker compose -f docker-compose.yml -f docker-compose.restore.yml run borg bash
  3. Fuse-mount the backup:
    • borg mount $BORG_REPO <mount_point>
  4. Restore your files
  5. Unmount and exit:
    • borg umount <mount_point> && exit.
  6. Start the backup container again:
    • docker-compose up -d

Monitoring

Simple bash scripts sent the backup status and statistics using curl to a Prometheus Pushgateway defined in .env.

Security considerations

  • This container runs with root privileges to allow backup of all data independent of permissions.
  • The backup source-volume is mounted read-only to avoid altering data by mistake.
  • This image has a reduced feature set for the sake of simplicity.
    • If necessary, borgmatic offers more features such as notifications and backup of databases.
    • py3-llfuse and bash are included for comfort during backup restore and could be potentially removed
    • curl is included to push Promethous metrics and could be removed if this functionality is not used

Program flow

  • docker-compose.yml sets variables .env as environment variables in the container
  • /scripts/entry.sh is called during container startup and installs the cronjob defined in the $CRON
  • crond starts /scripts/do-backup.sh which
    • executes borg backup
    • prunes and compacts old backups
    • notifies Prometheus about the backup start/stop/fail and stats

Failure handling

  • Break the lock in case Borg has been interrupted and fails to create/acquire a new lock:
    • docker exec borg bash -c 'borg break-lock'