Sign inSign up

christianmaier/hvergelmir-persistence2-backup

By christianmaier

•Updated about 13 hours ago

Backup job of persistence2: daily mariadb-dump of the catalogue's MariaDB to Backblaze B2.

Image
Databases & storage
0

90

christianmaier/hvergelmir-persistence2-backup repository overview

⁠hvergelmir-persistence2-backup

The backup job of the hvergelmir catalogue database: once a day it dumps the database from hvergelmir-persistence2-mariadb⁠ and uploads the dump to a Backblaze B2 bucket. It listens on nothing and publishes no port.

Built for one deployment. It is public because it holds no secrets, not because it is meant for general use.

⁠What a run does

  1. Pings <url>/start (healthchecks.io).
  2. mariadb-dump --single-transaction --quick --routines --events --triggers --hex-blob of one database, through gzip, into /scratch: one consistent snapshot of the InnoDB tables without locking them.
  3. Checks the file: gzip reads it to the end, and its last line is mariadb-dump's -- Dump completed, which a dump that stopped early lacks.
  4. Uploads it as <stage>/daily/<database>_<stage>_<UTC time>.sql.gz; rclone compares the checksum.
  5. Optionally copies the first dump of each month, inside the bucket, to <stage>/monthly/.
  6. Pings <url> on success or <url>/fail otherwise, each with the run's log, and removes the file.

A failed run uploads nothing. The job never deletes anything in the bucket: old dumps go by the bucket's lifecycle rules, and its key needs no right to delete (listBuckets,listFiles,readFiles,writeFiles).

The dump is a plain SQL file without CREATE DATABASE: gunzip -c <file> | mariadb <any database> loads it anywhere, with no tool from this image.

⁠What it is built from

  • The same MariaDB image as the server (mariadb:11.4.13-noble, pinned by digest), so mariadb-dump is exactly the server's version. Its server, entrypoint and port go unused.
  • rclone 1.75.1, rclone's own build; the download is checked against rclone's signed SHA256SUMS.
  • curl from Ubuntu, for the pings.
  • No root: runs as mysql (999). gosu is removed.

⁠Commands

backup schedulethe default command: run once a day at PERSISTENCE2_BACKUP_TIME, local time of TZ
backup runone backup now (docker exec <container> backup run)
backup checklogs in to MariaDB and lists the stage's prefix in the bucket; writes nothing
backup nextwhen the next scheduled run is
backup verify <file>the check every dump must pass before upload

⁠Configuration

PERSISTENCE2_STAGElower-case name; the prefix in the bucket and part of the file name
PERSISTENCE2_BACKUP_BUCKETthe bucket
PERSISTENCE2_BACKUP_TIMEHH:MM, local time of TZ
PERSISTENCE2_BACKUP_MONTHLYyes or no: keep the month's first dump under monthly/
PERSISTENCE2_BACKUP_PING_URLthe healthchecks.io ping URL; never logged
PERSISTENCE2_BACKUP_DB_PASSWORDpassword of the MariaDB user backup (host mariadb); never on a command line
RCLONE_CONFIG_TARGET_*the rclone remote target, e.g. TYPE=b2, ACCOUNT, KEY; RCLONE_CONFIG="" (no config file)
/scratch (volume)the dump of a running job only
/tmp, /var/lib/mysql (tmpfs)/var/lib/mysql covers the volume the MariaDB image declares

The MariaDB user needs only SELECT, SHOW VIEW, TRIGGER, EVENT, SHOW CREATE ROUTINE on the database.

backup:
  image: christianmaier/hvergelmir-persistence2-backup:<commit>@sha256:<digest>
  read_only: true
  cap_drop: [ALL]
  security_opt: ["no-new-privileges:true"]
  tmpfs:
    - /tmp:uid=999,gid=999,mode=0700,size=16m
    - /var/lib/mysql:uid=999,gid=999,mode=0700,size=1m
  environment:
    TZ: Europe/Berlin
    PERSISTENCE2_STAGE: prod
    PERSISTENCE2_BACKUP_BUCKET: "<bucket>"
    PERSISTENCE2_BACKUP_TIME: "03:30"
    PERSISTENCE2_BACKUP_MONTHLY: "yes"
    PERSISTENCE2_BACKUP_PING_URL: "<ping URL>"
    PERSISTENCE2_BACKUP_DB_PASSWORD: "<password>"
    RCLONE_CONFIG: ""
    RCLONE_CONFIG_TARGET_TYPE: b2
    RCLONE_CONFIG_TARGET_ACCOUNT: "<keyID>"
    RCLONE_CONFIG_TARGET_KEY: "<applicationKey>"
  volumes:
    - scratch:/scratch

Platform: linux/amd64. Each tag is the Git commit it was built from. Built and scanned (Trivy, gitleaks) by the project's pipeline.

Tag summary

Content type

Image

Digest

sha256:df3237626…

Size

130.9 MB

Last updated

about 13 hours ago

docker pull christianmaier/hvergelmir-persistence2-backup:1fe30451