Backup job of persistence2: daily mariadb-dump of the catalogue's MariaDB to Backblaze B2.
90
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.
<url>/start (healthchecks.io).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.-- Dump completed, which a
dump that stopped early lacks.<stage>/daily/<database>_<stage>_<UTC time>.sql.gz; rclone compares the checksum.<stage>/monthly/.<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.
mariadb:11.4.13-noble, pinned by digest), so mariadb-dump is
exactly the server's version. Its server, entrypoint and port go unused.SHA256SUMS.mysql (999). gosu is removed.backup schedule | the default command: run once a day at PERSISTENCE2_BACKUP_TIME, local time of TZ |
backup run | one backup now (docker exec <container> backup run) |
backup check | logs in to MariaDB and lists the stage's prefix in the bucket; writes nothing |
backup next | when the next scheduled run is |
backup verify <file> | the check every dump must pass before upload |
PERSISTENCE2_STAGE | lower-case name; the prefix in the bucket and part of the file name |
PERSISTENCE2_BACKUP_BUCKET | the bucket |
PERSISTENCE2_BACKUP_TIME | HH:MM, local time of TZ |
PERSISTENCE2_BACKUP_MONTHLY | yes or no: keep the month's first dump under monthly/ |
PERSISTENCE2_BACKUP_PING_URL | the healthchecks.io ping URL; never logged |
PERSISTENCE2_BACKUP_DB_PASSWORD | password 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.
Content type
Image
Digest
sha256:df3237626…
Size
130.9 MB
Last updated
about 13 hours ago
docker pull christianmaier/hvergelmir-persistence2-backup:1fe30451