🐳MariaDB im Docker-Container

Das offizielle Image mariadb initialisiert beim ersten Start das Datenverzeichnis, legt Benutzer an und spielt Init-Skripte ein. Alles auf dieser Seite sind Beispielwerte.

📝Beispiel: docker-compose.yml

# docker-compose.yml – Beispiel (alle Werte sind Platzhalter)
services:
  db:
    image: mariadb:11.8                 # feste LTS-Linie statt :latest
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db_root
      MARIADB_DATABASE: shop
      MARIADB_USER: app
      MARIADB_PASSWORD: beispiel-passwort
      MARIADB_AUTO_UPGRADE: "1"         # nach Image-Update mariadb-upgrade ausführen
    command: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
    volumes:
      - db-data:/var/lib/mysql                          # Daten (benanntes Volume)
      - ./init:/docker-entrypoint-initdb.d:ro           # nur beim allerersten Start
      - ./conf/60-eigene.cnf:/etc/mysql/conf.d/60-eigene.cnf:ro
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s
    secrets: [db_root]
    # kein "ports:" – nur Container im selben Netz erreichen die DB

  app:
    image: shop-app:1.0
    environment:
      DB_HOST: db
    depends_on:
      db:
        condition: service_healthy      # erst starten, wenn InnoDB bereit ist

volumes:
  db-data:

secrets:
  db_root:
    file: ./secrets/db_root.txt
💡 Image-Tags
Feste Versionen wie mariadb:11.8 (LTS bis 2028) oder mariadb:11.4 (LTS bis 2029) statt latest. Das Tag lts zeigt auf die jeweils neueste LTS-Version (seit der Freigabe im Mai 2026: 12.3).
✅ healthcheck.sh
Liegt im Image. --connect prüft, ob der Server Verbindungen annimmt, --innodb_initialized, ob InnoDB (inkl. Crash-Recovery) fertig ist. Weitere Tests: --innodb_buffer_pool_loaded, --galera_online, --replication.
⚠️ Init-Skripte nur einmal
Dateien in /docker-entrypoint-initdb.d (.sh, .sql, .sql.gz, .sql.xz, .sql.zst) laufen alphabetisch – aber nur bei leerem Datenverzeichnis. Später geänderte Skripte oder Umgebungsvariablen wirken nicht mehr.

🔧Umgebungsvariablen des Images

VariableWirkung
MARIADB_ROOT_PASSWORDPasswort für root. Alternativ MARIADB_ROOT_PASSWORD_HASH, MARIADB_RANDOM_ROOT_PASSWORD oder MARIADB_ALLOW_EMPTY_ROOT_PASSWORD – eine Variante ist Pflicht.
MARIADB_DATABASELegt beim ersten Start eine Datenbank an.
MARIADB_USER / MARIADB_PASSWORDLegt ein Konto an, das alle Rechte auf MARIADB_DATABASE bekommt.
MARIADB_AUTO_UPGRADEFührt nach einem Versionswechsel mariadb-upgrade aus (und legt vorher eine Sicherung der Systemtabellen an). Wirkt auch bei bestehendem Datenverzeichnis.
…_FILEJede Variable gibt es mit Endung _FILE: Der Wert wird aus einer Datei gelesen – ideal für Docker-Secrets.

Bis auf MARIADB_AUTO_UPGRADE haben alle Variablen keine Wirkung, wenn das Datenverzeichnis bereits eine Datenbank enthält.

🗺️Wo liegt was?

Container                                Host
/var/lib/mysql            ──▶ Volume db-data   (Datenverzeichnis!)
/docker-entrypoint-initdb.d ─▶ ./init          (Bind-Mount, :ro)
/etc/mysql/conf.d/*.cnf   ──▶ ./conf           (eigene Konfiguration)
/run/secrets/db_root      ──▶ ./secrets/…      (Docker-Secret)

Ablauf beim ersten Start (leeres Volume):
 1. mariadb-install-db  → Systemtabellen anlegen
 2. temporärer Server nur über Socket
 3. root-Passwort, Datenbank, Benutzer anlegen
 4. Init-Skripte alphabetisch ausführen
 5. temporären Server stoppen, richtigen Server starten
⚠️ Daten gehören in ein Volume
Ohne Volume liegen die Daten in der beschreibbaren Container-Schicht und sind nach docker rm weg. docker compose down -v löscht auch benannte Volumes!
💡 Backup im Container
docker compose exec db sh -c 'mariadb-dump --single-transaction -uroot -p"$(cat /run/secrets/db_root)" shop' > shop.sql
✅ Upgrade
Tag erhöhen (z. B. 11.4 → 11.8), docker compose up -d. Mit MARIADB_AUTO_UPGRADE=1 passt der Entrypoint die Systemtabellen an. Vorher ein Backup ziehen – ein Downgrade des Datenverzeichnisses ist nicht vorgesehen.