Sign inSign up

bfren/mariadb

By bfren

•Updated 44 minutes ago

MariaDB image based on Alpine Linux, with automated backups and optional SSL support.

Image
0

100K+

bfren/mariadb repository overview

⁠MariaDB

GitHub release (latest by date) Docker Pulls Docker Image Size GitHub Workflow Status

Docker Hub⁠ - Quay.io⁠ - bfren ecosystem⁠

⁠Introduction

MariaDB⁠ server with the jobs around it built in: the database and user are created on first start, every database is backed up every eight hours, the data is upgraded automatically when you move to a newer MariaDB version, and SSL certificates can be generated for you.

It is built on Debian + S6⁠ with MariaDB's own packages, so you can choose any supported MariaDB version. Versions before 9.0.0 also had Alpine variants - see the FAQs⁠ if you used one.

⁠Quickstart

docker-compose.yml:

services:
  db:
    image: quay.io/bfren/mariadb:mariadb11.8-9.0
    restart: unless-stopped
    environment:
      - BF_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - BF_DB_APPLICATION=myapp
      - BF_DB_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./v/data:/data
      - ./v/backup:/backup

.env (keep it out of version control):

DB_ROOT_PASSWORD=change-me
DB_PASSWORD=change-me-too

Run docker compose up -d. On first start a database and user called myapp are created, and your app (in the same compose file) connects to db:3306. To open a MariaDB shell:

docker compose exec db db-user     # as myapp
docker compose exec db db-root     # as root

See compose⁠ for examples that allow access from the host or other machines.

⁠Features

  • 🐬 MariaDB 10.11 to 13.0 - choose with the image tag
  • 🚀 Root password, application database(s) and user created on first start
  • 💾 Every database backed up every eight hours, optionally compressed, with old backups deleted automatically
  • ♻️ Restore, export and import with one command
  • ⬆️ Data upgraded automatically after moving to a newer MariaDB version
  • 🔒 Optional SSL, with CA, server and client certificates generated for you
  • 🧩 Add your own MariaDB configuration files
  • 🩺 Health check that the application user can query the server
  • 👤 MariaDB runs as dbadm (UID 1000), not root

⁠Tags

Images are published to Docker Hub (bfren/mariadb) and Quay.io (quay.io/bfren/mariadb). There is no latest tag - choose a MariaDB version.

TagExampleUse when
mariadbX.Ymariadb11.8You want the latest image for a MariaDB version
mariadbX.Y-MAJORmariadb11.8-9You want updates, but not breaking changes
mariadbX.Y-MINORmariadb11.8-9.0You want fixes only - recommended
mariadbX.Y-VERSIONmariadb11.8-9.0.0You want to pin this image exactly
mariadbX.Y.Zmariadb11.8.9You want an exact MariaDB release
mariadbX.Y.Z-VERSIONmariadb11.8.9-9.0.0You want to pin both
MariaDBReleaseBasePlatformsLTS
13.013.0.2Debian 13 (trixie)linux/amd64, linux/arm64No
12.312.3.3Debian 13 (trixie)linux/amd64, linux/arm64Yes
11.811.8.9Debian 13 (trixie)linux/amd64, linux/arm64Yes
11.411.4.13Debian 12 (bookworm)linux/amd64, linux/arm64Yes
10.1110.11.19Debian 12 (bookworm)linux/amd64, linux/arm64Yes

13.0 is a short-term release - use an LTS version for anything long-lived. See MariaDB's release dates⁠ for support periods.

⁠Configuration

⁠Ports
PortPurpose
3306MariaDB

You only need to publish it to reach the database from outside Docker - containers on the same network connect directly.

⁠Volumes
VolumePurpose
/dataThe database files.
/backupAutomatic backups, and the files used by db-export, db-import and db-restore.
/sslGenerated SSL certificates and keys (when BF_DB_SSL_ENABLE=1).

Everything in the volumes is owned by dbadm (UID / GID 1000), and only readable by its owner. On the host, read the files as UID 1000 or with sudo.

⁠Environment Variables

Database - these are only used the first time the container starts (see First start⁠):

VariableValuesDescriptionDefault
BF_DB_ROOT_PASSWORDstringRequired. Password for root (also used by backups, so keep it set).
BF_DB_APPLICATIONstringDefault for BF_DB_DATABASE, BF_DB_USERNAME and BF_DB_PASSWORD.
BF_DB_DATABASEnamesDatabase(s) to create - separate several with spaces.
BF_DB_USERNAMEstringApplication user, given full access to those databases.
BF_DB_PASSWORDstringApplication user's password (also used by the health check, so keep it set).
BF_DB_SUPER_USER0, 1Give the application user access to all databases and user management - not for production.0

Set BF_DB_APPLICATION, or all three of BF_DB_DATABASE, BF_DB_USERNAME and BF_DB_PASSWORD. Using BF_DB_APPLICATION alone makes the password the same as the user name, so set BF_DB_PASSWORD too.

Backups:

VariableValuesDescriptionDefault
BF_DB_BACKUP_COMPRESS_FILES0, 1Compress backup files with bzip2.0
BF_DB_BACKUP_KEEP_FORNu duration⁠How long to keep backups, e.g. 14day.28day

Server - applied every time the container starts:

VariableValuesDescriptionDefault
BF_DB_CHARACTER_SETstringcharacter_set_server⁠.utf8
BF_DB_COLLATIONstringcollation_server⁠.utf8_general_ci
BF_DB_LOG_WARNINGSintegerlog_warnings⁠.3
BF_DB_QUERY_CACHE_ENABLE0, 1Enable the query cache⁠.0
BF_DB_QUERY_CACHE_SIZE_BYTESintegerTotal query cache size.268435456
BF_DB_QUERY_CACHE_LIMIT_BYTESintegerLargest result cached per query.1048576

SSL - see SSL⁠:

VariableValuesDescriptionDefault
BF_DB_SSL_ENABLE0, 1Enable SSL.0
BF_DB_SSL_EXPIRYNu duration⁠Lifetime of the generated certificates.36500day
BF_DB_SSL_CA_KEY_BITSintegerSize of the CA private key.4096
BF_DB_SSL_SERVER_KEY_BITSintegerSize of the server private key.4096
BF_DB_SSL_CLIENT_KEY_BITSintegerSize of the client private key.4096

See Debian + S6⁠ for BF_DEBUG, BF_TZ and the other base image variables. BF_TZ sets the time backups run.

⁠How It Works

On every start, /etc/my.cnf is generated from the server variables, SSL certificates are generated if needed, and the backup job is added to cron. Then MariaDB starts under S6, its error log is forwarded to docker logs, and the upgrade check runs.

⁠First start

If /data has not been initialised, MariaDB's system tables are installed and an initialisation script runs as the server starts:

  • root is given BF_DB_ROOT_PASSWORD and can only connect from inside the container (localhost)
  • each database in BF_DB_DATABASE is created, and the application user is given full access to it from localhost and any host (%)
  • with BF_DB_SUPER_USER=1, the application user can also access every database and manage users
  • the test database is removed

This only happens once. Changing these variables later does not change passwords, users or databases - see I changed a password but can't log in⁠.

⁠Backups

At a random minute every eight hours (00:xx, 08:xx and 16:xx in BF_TZ), db-backup creates a folder in /backup named by date and time (yyyyMMddHHmm, e.g. 202610171608) containing:

  • dump.sql - every database, used by db-restore
  • <database>.sql - each database on its own

mysql, information_schema, performance_schema, sys and test are not backed up individually. With BF_DB_BACKUP_COMPRESS_FILES=1 the files are compressed with bzip2 (.sql.bz2). Backup folders older than BF_DB_BACKUP_KEEP_FOR are deleted - files in the root of /backup are left alone.

Back up before moving to a newer MariaDB version - run db-backup.

⁠Restore, export and import
  • db-restore <folder> restores every database from a backup folder's dump.sql (or dump.sql.bz2), e.g. db-restore 202610171608. Each database in the dump is dropped and recreated - databases that are not in the dump are left alone.
  • db-export <database> saves /backup/<database>.sql.
  • db-import <database> runs /backup/<database>.sql. Files from db-export and the per-database backup files recreate the database themselves.

To move a database between containers, db-export in one, copy the file to the other's /backup, then db-import.

⁠SSL

With BF_DB_SSL_ENABLE=1, a CA, server and client certificate are generated in /ssl on first start (if /ssl/server-cert.pem doesn't exist) and MariaDB accepts TLS 1.2 and 1.3. Clients need ca-cert.pem, and client-cert.pem / client-key.pem if you use certificate authentication. SSL is offered, not required - to require it, add REQUIRE SSL to the user, or require_secure_transport in your own configuration. Delete the files in /ssl and restart to generate new ones.

⁠Upgrades

After MariaDB starts, the version that created /data is compared with the server's. If they differ, mariadb-upgrade runs once to update the system tables. It also runs every month, as a check. Downgrading is not supported - restore a backup instead.

⁠Custom configuration

/etc/my.cnf includes every file in /etc/my.cnf.d, so mount your own *.cnf files there (e.g. innodb_buffer_pool_size). Don't change datadir, the log file or SSL paths.

⁠Helper commands

Run these with docker exec <container> <command>.

CommandArgumentsDescription
db-rootOpen a MariaDB shell as root (add -it to docker exec).
db-userOpen a MariaDB shell as the application user (add -it).
db-backupBack up now.
db-restorefolderRestore every database from a backup folder.
db-exportdatabaseSave a database to /backup/<database>.sql.
db-importdatabaseRun /backup/<database>.sql.
db-upgradeRun mariadb-upgrade - normally not needed.
db-enable-super-userGive the application user access to all databases and user management.
db-disable-super-userRecreate the application user with access only to BF_DB_DATABASE.
⁠Health check

The health check (inherited from the base image: every 30 seconds) connects as the application user and runs SELECT 1.

⁠Testing

./test.nu              # builds MariaDB 13.0 and runs /test
./test.nu 11.4         # or any version directory
./test.nu --all        # every version, in parallel
./run.sh 11.8          # builds and opens a shell, with /data, /backup and /ssl in this directory
./generate.sh          # regenerates the Dockerfiles from Dockerfile.esh

/test runs this image's tests alongside the base images' tests: the initialisation script, my.cnf, SSL certificate generation, version detection, and backup, restore, export and import (using stub mariadb executables, so no server is needed).

⁠Troubleshooting

⁠The container stops straight after starting

Check docker logs <container>. BF_DB_ROOT_PASSWORD must be set, and either BF_DB_APPLICATION or all of BF_DB_DATABASE, BF_DB_USERNAME and BF_DB_PASSWORD.

⁠I changed a password but can't log in

Passwords are only set on first start⁠. Change them in SQL (docker exec -it <container> db-root, then ALTER USER ... IDENTIFIED BY ...), then update the environment variable to match - backups use BF_DB_ROOT_PASSWORD and the health check uses BF_DB_PASSWORD.

⁠I can't connect as root from outside the container

root can only connect from localhost. Use the application user, or db-root inside the container.

⁠The container is unhealthy

The application user couldn't run SELECT 1. Usually its password no longer matches BF_DB_PASSWORD - see above.

⁠MariaDB won't start after changing the image tag

Moving to an older MariaDB version is not supported. Go back to the previous tag, or restore a backup into an empty /data.

⁠FAQs

⁠I was using an Alpine variant - how do I move?

From 9.0.0 there are no Alpine variants: Alpine's MariaDB version is fixed by the Alpine release, and its packages arrive later on some platforms. The -alpine tags still work but are no longer updated.

Change your tag to the same MariaDB version without -alpine, e.g. mariadb11.8-9.0 - your /data, /backup and /ssl volumes work as they are, because MariaDB runs as dbadm (UID 1000) in both. If you used MariaDB 10.6 (Alpine 3.17), move to 10.11 or newer: the data is upgraded automatically on first start, but take a backup first. There is no linux/arm/v7 image - stay on your current -alpine tag if you need it.

⁠How do I add another database later?

As root (db-root): CREATE DATABASE newdb; then GRANT ALL PRIVILEGES ON newdb.* TO 'myapp'@'%';. Add it to BF_DB_DATABASE too, so db-disable-super-user keeps it.

⁠Can I use the official MariaDB image's variables, such as MARIADB_ROOT_PASSWORD?

No - this image only reads the BF_DB_* variables.

⁠Licence

Copyright (c) 2020-2026 bfren⁠ (unless otherwise stated)

Tag summary

Content type

Image

Digest

sha256:5f4006d7e…

Size

146 MB

Last updated

44 minutes ago

docker pull bfren/mariadb:mariadb11.8.9-9.0.2