Skip to content

MariaDB Docker : base de données robuste pour tes services

Brandon
Date de publication:

💡 TL;DR

  • MariaDB est un fork open-source de MySQL, plus rapide et 100% compatible, idéal pour remplacer MySQL dans tes stacks Docker.
  • Une stack Compose minimaliste avec persistance des données, healthcheck et variables d’environnement sécurisées suffit à 90% des cas.
  • Configure des sauvegardes automatiques et des optimisations mémoire pour éviter les surprises en production.

Pourquoi MariaDB plutôt que MySQL ?

MySQL appartient à Oracle. MariaDB, c’est le fork communautaire créé par le fondateur original de MySQL après le rachat. Si tu veux rester dans l’écosystème open-source pur, le choix est vite fait.

Mais au-delà de la philosophie, MariaDB apporte des gains réels :

Dans un environnement Docker, c’est particulièrement pertinent. Tu n’as pas besoin d’installer un client MySQL sur ton hôte, ni de gérer des dépendances système. Une image containerisée propre, un volume pour la persistance, et tu es opérationnel.

Prérequis et architecture minimale

Avant de balancer un docker-compose.yml, vérifie que ton serveur tient la route :

MariaDB, c’est une base de données relationnelle classique. Elle stocke les données dans /var/lib/mysql. Sans volume Docker, un docker compose down efface tout. C’est le premier piège à éviter.

Stack Docker Compose complète

Voici une configuration production-ready, pas un POC bidon. Elle inclut :

Crée un dossier mariadb-stack et ajoute ce docker-compose.yml :

version: "3.9"

services:
  mariadb:
    image: mariadb:11.4
    container_name: mariadb
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - mariadb_data:/var/lib/mysql
      - ./backup:/backup
      - ./conf/custom.cnf:/etc/mysql/conf.d/custom.cnf:ro
    networks:
      - db_network
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 10s
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  mariadb_data:

networks:
  db_network:
    driver: bridge

Et le fichier .env à côté :

MARIADB_ROOT_PASSWORD=ton-mot-de-passe-root-ultra-securise
MARIADB_DATABASE=app_database
MARIADB_USER=app_user
MARIADB_PASSWORD=un-autre-mot-de-passe-fort
TZ=Europe/Paris

Points importants :

Optimisation mémoire et performance

Par défaut, MariaDB Docker tourne avec une config ultra-conservative. Si tu as plus de 2 Go de RAM, tu vas vouloir ajuster quelques paramètres.

Crée le fichier conf/custom.cnf :

[mysqld]
# Mémoire
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
innodb_flush_log_at_trx_commit = 2

# Connexions
max_connections = 100
wait_timeout = 600
interactive_timeout = 600

# Performance
query_cache_type = 1
query_cache_size = 64M
tmp_table_size = 64M
max_heap_table_size = 64M

# Logs
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 2

Explications :

Monte ce fichier en read-only (:ro) dans le conteneur. Si tu vebles la config, tu modifies le fichier, puis docker compose restart mariadb.

Sécuriser l’accès

MariaDB expose le port 3306. Même si tu es derrière un firewall, minimise la surface d’attaque.

Pas de port exposé sur l’hôte

Si tes applications sont aussi en Docker sur le même réseau, ne mappe pas le port 3306 sur l’hôte. Supprime cette ligne du docker-compose.yml :

# PAS ÇA
ports:
  - "3306:3306"

Les autres conteneurs communiquent via le réseau interne db_network. Aucune raison d’exposer MySQL au monde extérieur, même en local.

Si tu dois absolument t’y connecter depuis l’extérieur (ex : DBeaver sur ton poste local), utilise un tunnel SSH via Passkey et SSH plutôt qu’un mapping de port brut. C’est plus sûr et ça évite d’ouvrir un port supplémentaire sur ton firewall.

Utilisateurs dédiés par application

Jamais le root pour les applis. Le docker-compose.yml ci-dessus crée un utilisateur app_user limité à app_database. C’est l’utilisateur que tu passes à Nextcloud, Wallabag, ou tout autre service.

Si tu ajoutes un service supplémentaire plus tard, crée un nouvel utilisateur et une nouvelle base :

docker exec -it mariadb mariadb -u root -p

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'nextcloud'@'%' IDENTIFIED BY 'mot-de-passe-fort';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'%';
FLUSH PRIVILEGES;
EXIT;

Une base = un utilisateur = une surface d’attaque limitée.

Sauvegarde automatisée

La persistance Docker, c’est bien. La sauvegarde externe, c’est mieux. Un volume corrompu, un RAID qui lâche, une fausse manip docker volume rm, bam, c’est fini.

Script de dump quotidien

Crée backup/backup-mariadb.sh :

#!/bin/bash
set -euo pipefail

BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

echo "[$(date)] Démarrage backup MariaDB..."

mysqldump -u root -p"${MARIADB_ROOT_PASSWORD}" --all-databases --single-transaction --routines --events \
  | gzip > "${BACKUP_DIR}/mariadb_backup_${DATE}.sql.gz"

echo "[$(date)] Backup terminé : mariadb_backup_${DATE}.sql.gz"

# Rotation : suppression des backups de plus de 7 jours
find "${BACKUP_DIR}" -name "mariadb_backup_*.sql.gz" -mtime +${RETENTION_DAYS} -delete

echo "[$(date)] Rotation terminée."

Rends-le exécutable :

chmod +x backup/backup-mariadb.sh

Puis exécute-le depuis le conteneur via un cron sur l’hôte :

# Sur l'hôte, édite le crontab de l'utilisateur docker
crontab -e

# Ajoute cette ligne pour un backup tous les jours à 3h du matin
0 3 * * * cd /chemin/vers/mariadb-stack && docker compose exec -T mariadb /backup/backup-mariadb.sh >> /var/log/mariadb-backup.log 2>&1

Le flag -T est important : il désactive le TTY, sinon cron plante. Le fichier de log te permet de surveiller les échecs.

Restauration

Si tu dois restaurer une base spécifique :

# Copie le backup dans le conteneur
docker cp mariadb_backup_20260807_030000.sql.gz mariadb:/tmp/

# Restaure
docker exec -it mariadb bash -c "zcat /tmp/mariadb_backup_20260807_030000.sql.gz | mariadb -u root -p"

Teste ta restauration au moins une fois. Un backup non testé, c’est juste de l’espoir.

Connexion et administration

Depuis un autre conteneur

Un service comme NocoDB ou BookStack se connecte avec ces variables :

environment:
  DB_HOST: mariadb
  DB_PORT: 3306
  DB_NAME: app_database
  DB_USER: app_user
  DB_PASSWORD: ${MARIADB_PASSWORD}

Le nom du service (mariadb) est résolu automatiquement par le DNS interne Docker.

Depuis l’hôte

Si tu as besoin de jeter un œil depuis le terminal de l’hôte :

docker exec -it mariadb mariadb -u root -p

Pas besoin d’installer MySQL Client sur ton hôte. Tout passe par le conteneur.

Interface web (optionnel)

Si tu préfères un GUI, Adminer ou phpMyAdmin en Docker font le job. Pour Adminer, ajoute juste ça à ton docker-compose.yml :

  adminer:
    image: adminer:latest
    container_name: adminer
    restart: unless-stopped
    ports:
      - "8080:8080"
    networks:
      - db_network

Accède via http://IP:8080, serveur = mariadb, et tes identifiants. Si tu utilises Traefik, mets-le derrière un sous-domaine avec HTTPS au lieu d’exposer le port 8080 brut.

Mise à jour de MariaDB

Les mises à jour de base de données, c’est le moment où tu transpires. MariaDB 11.4 vers 11.5 ? Généralement sans souci. Mais d’une majeure à l’autre, la structure interne peut changer.

Procédure sécurisée

  1. Dump complet avant toute chose. Oui, c’est chiant. Oui, ça sauve des vies.
  2. Lis les notes de release de l’image Docker officielle (mariadb sur Docker Hub).
  3. Met à jour le tag dans le docker-compose.yml :
    image: mariadb:11.5
  4. Redéploie :
    docker compose pull
    docker compose up -d
  5. Vérifie les logs :
    docker logs --tail 50 mariadb

Si tu utilises Watchtower, configure une politique de mise à jour conservative. Une base de données qui redémarre toute seule en pleine nuit sans backup préalable, c’est une mauvaise blague.

Monitoring basique

Tu n’as pas besoin de Zabbix pour surveiller une base MariaDB isolée. Quelques commandes simples suffisent.

État du conteneur

docker compose ps
docker stats mariadb --no-stream

Logs en temps réel

docker logs -f --tail 100 mariadb

Métriques SQL rapides

-- Taille des bases
SELECT table_schema AS "Database", 
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)" 
FROM information_schema.tables 
GROUP BY table_schema;

-- Connexions actives
SHOW STATUS LIKE 'Threads_connected';

-- Requêtes lentes
SHOW GLOBAL STATUS LIKE 'Slow_queries';

Healthcheck personnalisé

Si le healthcheck natif ne te suffit pas, tu peux en ajouter un second qui vérifie qu’une base spécifique est accessible :

healthcheck:
  test: ["CMD", "mariadb", "-u", "app_user", "-p${MARIADB_PASSWORD}", "-D", "app_database", "-e", "SELECT 1"]
  interval: 30s
  timeout: 10s
  retries: 3

Cas d’usage concrets dans ton homelab

MariaDB est le ciment de nombreuses applications auto-hébergées. Voici les stacks où je l’utilise régulièrement :

L’avantage d’avoir une instance MariaDB centrale, c’est que tu partages les ressources. Pas besoin de lancer un PostgreSQL pour chaque appli. Un conteneur MariaDB bien tune, et tu branches tout dessus.

Dépannage des erreurs courantes

”Can’t connect to local MySQL server through socket”

Tu essayes de te connecter depuis l’hôte avec mysql sans préciser l’hôte. Depuis l’hôte, utilise toujours docker exec pour entrer dans le conteneur. Ou connecte-toi en TCP si tu as exposé le port.

”Access denied for user”

Vérifie que tu utilises le bon mot de passe et le bon hôte. Dans Docker, les utilisateurs sont souvent créés avec 'user'@'%', ce qui accepte n’importe quel hôte. Mais si tu as créé 'user'@'localhost', ça ne marchera pas depuis un autre conteneur.

Le conteneur redémarre en boucle

docker logs mariadb

Causes fréquentes :

Lenteurs soudaines

Vérifie le slow query log (/var/lib/mysql/slow.log dans le conteneur). Ajoute des index si nécessaire. Si le conteneur manque de RAM, Linux va swapper et tout ralentir. Augmente innodb_buffer_pool_size ou ajoute de la RAM.

Conclusion

MariaDB avec Docker, c’est pas sorcier. Une image stable, un volume persistant, un .env propre, et tu as une base de données relationnelle prête à servir tes applications auto-hébergées. La clé, c’est de ne pas négliger les bases : healthcheck, backup automatisé, et utilisateurs dédiés par service.

Si tu déploies plusieurs applis sur ton serveur, centraliser MariaDB est le choix le plus efficace. Moins de conteneurs, moins de ressources gaspillées, et une maintenance simplifiée. Ce n’est pas le setup le plus hype du monde, mais c’est celui qui fonctionne jour après jour sans te réveiller à 3h du matin.

Next
Amethyst macOS : tiling window manager gratuit pour un workflow au clavier