- Rust 70.8%
- Dockerfile 13%
- Shell 11.7%
- Python 3.6%
- Go Template 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
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
|
||
| .github/workflows | ||
| backup-sidecar | ||
| examples | ||
| mariadb | ||
| mariadb-backup | ||
| mariadb-entrypoint | ||
| scripts | ||
| security | ||
| .gitignore | ||
| .metadata.json | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
| test-backup.sh | ||
MariaDB Distroless
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
_FILEsuffix 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.3ssl_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
Runtime Hardening (Recommended)
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=65532to match the nonroot user. The volume must be mounted directly to/var/lib/mysql/{version}/datato 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.