Backup and restore image for a MariaDB server. https://git.openso.de/openso/mariadb-maintenance
  • Shell 57.5%
  • Python 39.9%
  • Dockerfile 2.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Marcel Henneke ad2df8d736
All checks were successful
ci / compose (push) Successful in 13s
ci / shellcheck (push) Successful in 2s
ci / conventions (push) Successful in 2s
ci / image (push) Successful in 44s
Fix backup chaining, optional dump database, and restore guard (#1)
2026-11-03 11:24:44 +01:00
.forgejo Publish the MariaDB backup and restore image. 2026-11-03 10:39:33 +01:00
.githooks Publish the MariaDB backup and restore image. 2026-11-03 10:39:33 +01:00
.openso/scripts Drop the copied Python cache from the image repository. 2026-11-03 10:39:45 +01:00
.dockerignore Publish the MariaDB backup and restore image. 2026-11-03 10:39:33 +01:00
.gitignore Drop the copied Python cache from the image repository. 2026-11-03 10:39:45 +01:00
AGENTS.md Publish the MariaDB backup and restore image. 2026-11-03 10:39:33 +01:00
backup.mariadb-maintenance.sh Fix backup chaining, optional dump database, and restore guard (#1) 2026-11-03 11:24:44 +01:00
Dockerfile Fix backup chaining, optional dump database, and restore guard (#1) 2026-11-03 11:24:44 +01:00
entrypoint.mariadb-maintenance.sh Fix backup chaining, optional dump database, and restore guard (#1) 2026-11-03 11:24:44 +01:00
LICENSE Publish the MariaDB backup and restore image. 2026-11-03 10:39:33 +01:00
README.md Fix backup chaining, optional dump database, and restore guard (#1) 2026-11-03 11:24:44 +01:00

mariadb-maintenance

Scheduled backups and on-demand restore for a MariaDB server. The server image stays in docker-templates. This repository is the tools image only. It is not the database server.

The process runs as the vendor mysql user, UID 999 and GID 999. Compose sets a read-only root filesystem.

Image

git.openso.de/openso/mariadb-maintenance:main

docker-templates uses git.openso.de/openso/mariadb-maintenance with no tag. Docker resolves that reference to :latest. :latest is the same build as :main.

Runtime

  1. The entrypoint reads MARIADB_ROOT_PASSWORD_FILE.
  2. When /restore contains a mariabackup chain (full_<id>.zst and incremental_<id>_*.zst in that directory, not in a dated subdirectory), it prepares that chain and copies it into /var/lib/mysql, then exits. MARIADB_RESTORE_DRY_RUN=true prepares the chain and does not copy it back. A logical dump is not restored by this path.
  3. Otherwise it execs Supercronic with /usr/local/bin/backup.cron. The image does not contain that schedule. Compose bind-mounts it read-only. /backup and /restore are bind mounts. /var/lib/mysql is the shared server volume. /tmp is a tmpfs, because the scripts take their lock there and the root filesystem is read-only.

backup.sh accepts full, incremental, or dump. The mounted cron file chooses the schedule. full and incremental land in /backup/<yyyymmdd>/. An incremental uses the newest full backup in that tree, including one from an earlier day. A dump is a logical backup of MARIADB_DATABASE only.

Environment

These values are runtime switches. They do not install packages and they do not select another image.

Variable Default Purpose
MARIADB_ROOT_PASSWORD_FILE Docker secret file for the account in MARIADB_ROOT_USER. Required.
MARIADB_DATABASE Database name for a logical dump. Required by backup.sh dump.
MARIADB_ROOT_USER root Account that owns the root secret.
MARIADB_DB_HOST mariadb Server hostname.
MARIADB_BACKUP_RETENTION_DAYS 7 Delete backup days older than this count.
MARIADB_BACKUP_DEBUG false Verbose backup logs.
MARIADB_RESTORE_DRY_RUN false Prepare a restore and do not copy it into the data directory.
MARIADB_RESTORE_DEBUG false Verbose restore logs.

Compose

services:
  mariadb-maintenance:
    image: git.openso.de/openso/mariadb-maintenance
    user: "999:999"
    read_only: true
    cap_drop:
      - ALL
    cap_add:
      - SETUID
      - SETGID
      - CHOWN
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /tmp
    volumes:
      - database:/var/lib/mysql:rw
      - ./scripts/backup.cron:/usr/local/bin/backup.cron:ro
      - ./backup:/backup:rw
      - ./restore:/restore:rw
    secrets:
      - MARIADB_ROOT_PASSWORD
    environment:
      TZ: Europe/Berlin
      MARIADB_DATABASE: app
      MARIADB_DB_HOST: app-mariadb
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/MARIADB_ROOT_PASSWORD
    healthcheck:
      test: ["CMD", "sh", "-c", "pgrep supercronic >/dev/null 2>&1"]

secrets:
  MARIADB_ROOT_PASSWORD:
    file: ./secrets/MARIADB_ROOT_PASSWORD

volumes:
  database:

Contents

Pin Value
Base image mariadb:13.0.2@sha256:f4054da26e3a9dd6c8b5cc97363e544408b15c0fb369d7359c25dc04826eb6e1
Supercronic v0.2.51 amd64 sha256:cc232108374e8e2b537045f2d5eaa1229f619db314c3ba6a14d38b35dc0aa123

ca-certificates, zstd, and procps come from that base image. curl is installed for the Supercronic download and removed in the same build step. A version bump changes one of the pins above.

Build

A push to main publishes git.openso.de/openso/mariadb-maintenance:main and :latest. A tag v* publishes that tag and :latest. The first commit on main is that push.