No description
  • Rust 70.8%
  • Dockerfile 13%
  • Shell 11.7%
  • Python 3.6%
  • Go Template 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Clément BREISCH 0969493fbe
All checks were successful
Build and Test MariaDB Backup Images / Load Configuration (push) Successful in 6s
Build and Test MariaDB Backup Images / Build Backup (MariaDB 11) (push) Successful in 4m20s
Build and Test MariaDB Backup Images / Build Backup (MariaDB 12) (push) Successful in 3m6s
Build and Test MariaDB Backup Images / Verify all image builds (push) Successful in 1s
Build and Test MariaDB Backup Images / Backup Tests (MariaDB 11) (push) Successful in 53s
Build and Test MariaDB Backup Images / Backup Tests (MariaDB 12) (push) Successful in 52s
Build and Test MariaDB Backup Images / Security Scan (MariaDB 11) (push) Successful in 2m59s
Build and Test MariaDB Backup Images / Compliance Scan (MariaDB 11) (push) Successful in 34s
Build and Test MariaDB Backup Images / Security Scan (MariaDB 12) (push) Successful in 2m22s
Build and Test MariaDB Backup Images / Compliance Scan (MariaDB 12) (push) Successful in 14s
Build and Test MariaDB Backup Images / Push Backup (MariaDB 12) (push) Successful in 7s
Build and Test MariaDB Backup Images / Push Backup (MariaDB 11) (push) Successful in 8s
Build and Test MariaDB Backup Images / Tag Backup Latest (push) Successful in 6s
fix: drain backup-list output in CI (#8)
2026-09-25 17:39:20 +00:00
.github/workflows fix: drain backup-list output in CI (#8) 2026-09-25 17:39:20 +00:00
backup-sidecar add retention cleanup debug logging 2026-01-05 13:02:18 +00:00
examples fix: restore daily upstream database builds (#1) 2026-09-25 13:37:52 +00:00
mariadb fix: include and validate MariaDB upgrade tools (#5) 2026-09-25 15:33:28 +00:00
mariadb-backup fix: restore authenticated database image publication (#2) 2026-09-25 14:23:24 +00:00
mariadb-entrypoint fix: authenticate automatic MariaDB upgrades (#6) 2026-09-25 16:35:20 +00:00
scripts fix: qualify upstream-fixed MariaDB scanner findings (#7) 2026-09-25 17:14:53 +00:00
security fix: qualify upstream-fixed MariaDB scanner findings (#7) 2026-09-25 17:14:53 +00:00
.gitignore Initial MariaDB distroless image implementation 2025-12-21 23:39:18 +00:00
.metadata.json fix: restore daily upstream database builds (#1) 2026-09-25 13:37:52 +00:00
LICENSE Initial commit 2025-12-21 23:15:32 +00:00
README.md fix: restore authenticated database image publication (#2) 2026-09-25 14:23:24 +00:00
SECURITY.md fix: restore daily upstream database builds (#1) 2026-09-25 13:37:52 +00:00
test-backup.sh fix: restore daily upstream database builds (#1) 2026-09-25 13:37:52 +00:00

MariaDB Distroless

Build

Minimal, secure MariaDB container images based on Google's distroless base.

Features

  • Minimal footprint: ~80MB per image (vs ~400MB for official mariadb)
  • Multi-architecture: linux/amd64 and linux/arm64
  • Distroless base: No shell, no package manager, reduced attack surface
  • Multiple versions: MariaDB 11 and 12
  • Security-first: Runs as non-root (UID 65532), binaries owned by root
  • TLS support: Auto-detection of SSL certificates
  • Docker secrets: Support for _FILE suffix environment variables

Quick Start

# Basic usage
docker run -d \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

# With persistent data
docker run -d \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -v mariadb-data:/var/lib/mysql \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

Available Tags

Tag MariaDB Version Notes
12, latest 12.1.x Latest stable
11 11.8.x LTS (until 2028)

Environment Variables

Variable Default Description
MARIADB_ROOT_PASSWORD (required*) Root password
MARIADB_DATABASE - Create database on init
MARIADB_USER - Create user on init
MARIADB_PASSWORD - Password for MARIADB_USER
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD - Set to yes to allow empty root password
MARIADB_RANDOM_ROOT_PASSWORD - Set to yes to generate random password
MARIADB_AUTO_UPGRADE - Set to yes to auto-upgrade on version change
DATADIR /var/lib/mysql/{version}/data Data directory

*One of MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD, or MARIADB_RANDOM_ROOT_PASSWORD is required.

Performance & Limits

Variable Default Description
MARIADB_MAX_CONNECTIONS 151 Maximum concurrent connections
MARIADB_STATEMENT_TIMEOUT - Query timeout (e.g., 30, 300)
MARIADB_INNODB_BUFFER_POOL_SIZE 128M InnoDB buffer pool size

Logging

Variable Default Description
LOG_LEVEL info Log level for entrypoint and MariaDB: error, warn, info, debug

The log level controls both entrypoint verbosity and MariaDB's log_warnings setting.

Security & Audit

Variable Default Description
MARIADB_LOG_CONNECTIONS on Log connection attempts
MARIADB_LOG_DISCONNECTIONS on Log disconnections

Docker Secrets

All MARIADB_* variables support the _FILE suffix for Docker secrets:

docker run -d \
  -e MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db_password \
  -v /path/to/secrets:/run/secrets:ro \
  git.bexsys.fr/images/mariadb:12

TLS/SSL Configuration

SSL certificates are read from /var/lib/mysql/ssl/. You can provide them via environment variables or volume mounts.

Option 1: Environment Variables / Docker Secrets

Pass certificates directly via environment variables or use _FILE suffix for secrets:

# Direct environment variables
docker run -d \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -e MARIADB_SSL_CERT="$(cat server-cert.pem)" \
  -e MARIADB_SSL_KEY="$(cat server-key.pem)" \
  -e MARIADB_SSL_CA="$(cat ca.pem)" \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

# Docker secrets (with _FILE suffix)
docker run -d \
  -e MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db_password \
  -e MARIADB_SSL_CERT_FILE=/run/secrets/ssl_cert \
  -e MARIADB_SSL_KEY_FILE=/run/secrets/ssl_key \
  -v /path/to/secrets:/run/secrets:ro \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

Option 2: Volume Mounts

Mount certificates to /var/lib/mysql/ssl/:

docker run -d \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -v $(pwd)/ca.pem:/var/lib/mysql/ssl/ca.pem:ro \
  -v $(pwd)/server-cert.pem:/var/lib/mysql/ssl/server-cert.pem:ro \
  -v $(pwd)/server-key.pem:/var/lib/mysql/ssl/server-key.pem:ro \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

SSL Environment Variables

Variable Default Description
MARIADB_SSL_CERT - Server certificate (PEM content)
MARIADB_SSL_KEY - Server private key (PEM content)
MARIADB_SSL_CA - CA certificate (PEM content, optional)
MARIADB_SSL off Set to on to warn if certs not found
MARIADB_SSL_REQUIRE off Set to on to require SSL for all connections

All variables support the _FILE suffix for Docker secrets.

When MARIADB_SSL_REQUIRE=on, all connections must use SSL (require_secure_transport=ON).

Generate Test Certificates

openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365 -key ca-key.pem -out ca.pem -subj "/CN=MariaDB-CA"
openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem -subj "/CN=mariadb"
openssl x509 -req -in server-req.pem -days 365 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

TLS Hardening

When SSL is enabled, the following hardening is applied automatically:

  • tls_version = TLSv1.2,TLSv1.3
  • ssl_cipher = HIGH:!aNULL:!MD5:!3DES:!RC4

Security

File Ownership

Path Owner Permissions
/usr/bin/mariadb* root Execute only
/usr/lib/mariadb/* root Read only
/var/lib/mysql/* 65532 (nonroot) Read/Write
/var/run/mysqld/ 65532 (nonroot) Read/Write

The MariaDB process cannot modify its own binaries.

Default Hardening

The image applies these security settings by default:

[mysqld]
local_infile=0
symbolic-links=0
skip-name-resolve
log_warnings=2

For maximum security, run with these Docker flags:

docker run -d \
  --read-only \
  --tmpfs /tmp:uid=65532,gid=65532 \
  --tmpfs /var/run/mysqld:uid=65532,gid=65532 \
  --cap-drop=ALL \
  --security-opt=no-new-privileges:true \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -v mariadb-data:/var/lib/mysql/12/data \
  -p 3306:3306 \
  git.bexsys.fr/images/mariadb:12

Note

: The tmpfs mounts require uid=65532,gid=65532 to match the nonroot user. The volume must be mounted directly to /var/lib/mysql/{version}/data to avoid directory creation issues with --read-only.

Flag Purpose
--read-only Immutable root filesystem
--tmpfs /tmp:uid=65532,gid=65532 Writable temp directory (nonroot user)
--tmpfs /var/run/mysqld:uid=65532,gid=65532 Writable socket directory (nonroot user)
--cap-drop=ALL Drop all Linux capabilities
--security-opt=no-new-privileges Prevent privilege escalation

For Kubernetes, use equivalent securityContext:

securityContext:
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]
  runAsNonRoot: true
  runAsUser: 65532

Volumes

Path Description
/var/lib/mysql Data directory (mount for persistence)
/var/run/mysqld Unix socket directory

Ports

Port Description
3306 MariaDB

Healthcheck

The image includes a built-in healthcheck using mariadb-admin ping. Since this is a distroless image without a shell, the healthcheck uses the entrypoint with the --health-check flag:

HEALTHCHECK CMD ["/entrypoint", "--health-check"]

The healthcheck uses MARIADB_USER and MARIADB_PASSWORD environment variables for authentication. Make sure these are set for the healthcheck to work properly.

To check the health status:

docker inspect --format='{{.State.Health.Status}}' container_name

You can also run the healthcheck manually:

docker exec container_name /entrypoint --health-check && echo "Healthy" || echo "Unhealthy"

Upgrading

When upgrading between major versions (e.g., 11 to 12), set MARIADB_AUTO_UPGRADE=yes to automatically run mariadb-upgrade:

docker run -d \
  -e MARIADB_ROOT_PASSWORD=mysecretpassword \
  -e MARIADB_AUTO_UPGRADE=yes \
  -v mariadb-data:/var/lib/mysql \
  git.bexsys.fr/images/mariadb:12

Backup Sidecar

A companion mariadb-backup image is available for scheduled backups with:

  • Cron-based scheduling
  • Multiple compression algorithms (gzip, zstd, xz, lzma)
  • Proxmox-style retention policies
  • Age encryption support
  • Webhook notifications
  • Built-in restore utility

See mariadb-backup/README.md for full documentation.

Quick example:

services:
  mariadb:
    image: git.bexsys.fr/images/mariadb:12
    environment:
      MARIADB_ROOT_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mariadb-data:/var/lib/mysql

  backup:
    image: git.bexsys.fr/images/mariadb-backup:12
    environment:
      MARIADB_HOST: mariadb
      MARIADB_PASSWORD: ${DB_PASSWORD}
      BACKUP_SCHEDULE: "0 2 * * *"
      BACKUP_KEEP_DAILY: "7"
    volumes:
      - backup-data:/backups
    depends_on:
      - mariadb

License

MIT License (image build scripts) / GPL v2 (MariaDB)

Maintained image branches

The 11 server and backup-client tags use MariaDB 11.8 LTS; 12 uses MariaDB 12.3 LTS. Both fetch the current upstream patch release on each build. Server and backup-client branches are matched explicitly. Production tags are promoted only after functional, security and compliance checks.

Registry publication credential

Workflows use the repository Actions secret BEXSYS_REGISTRY_TOKEN for the clement registry account, scoped to package publication. The automatic repository token is not used to publish packages. No registry credential is stored in Git. Historical package versions are retained for recovery.