Zum Inhalt springen

Projekt Phoenyx – Teil 9: Das zentrale Gedächtnis (MariaDB & Tools)

Kategorie: Core-Stack / Datenbank | Lesezeit: ca. 15-20 Minuten

Einführung: Warum eine zentrale Datenbank?

Fast jeder Dienst, den du in Zukunft hosten wirst, braucht ein Gedächtnis. WordPress speichert dort seine Artikel, Nextcloud seine Datei-Indizes und Gitea seinen Code-Verlauf. Dieses Gedächtnis ist meist eine SQL-Datenbank.

Das Problem mit „All-in-One“ Containern

Viele Anfänger nutzen fertige docker-compose.yml Dateien aus dem Internet, die für jeden Dienst eine eigene Datenbank mitbringen. Wenn du 10 Dienste hast, laufen dann 10 Datenbank-Server parallel. Das verschwendet massiv Arbeitsspeicher (RAM) und CPU-Leistung, weil jeder Datenbank-Prozess eigenen Overhead hat.

Unser Ansatz ist effizienter: Wir starten einen zentralen, leistungsstarken Datenbank-Server (MariaDB). Alle unsere Anwendungen (außer Authentik, das Postgres braucht) dürfen diesen Server mitbenutzen. Wir erstellen für jede App einfach eine eigene „Schublade“ (Datenbank) und einen eigenen Schlüssel (Benutzer) auf diesem Server.


Schritt 1: Die MariaDB Konfiguration verstehen

Schauen wir uns die Datei mariadb-docker-compose.yml genau an. Ich erkläre dir jede Zeile, damit du verstehst, was wir da eigentlich tun.

services:
  mariadb-global:
    image: mariadb:11.3 
    container_name: mariadb-global
    restart: always

Wir nutzen MariaDB statt MySQL. MariaDB ist ein Fork von MySQL, der von der Community weiterentwickelt wird, performanter ist und offener lizenziert ist. Version 11.3 ist eine aktuelle, stabile Version. Der Container heißt mariadb-global, damit wir ihn später leicht finden können.

Umgebungsvariablen (Das Root-Passwort)

    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - TZ=Europe/Berlin

Hier definieren wir das Passwort für den „Gott-Modus“ der Datenbank (root). Wichtig: Wir schreiben das Passwort nicht direkt in die Datei! Wir nutzen die Variable ${MYSQL_ROOT_PASSWORD}. Das bedeutet, Docker holt sich das echte Passwort aus deiner .env Datei. Das ist sicherer, falls du deine Compose-Dateien mal versehentlich teilst.

Sicherheit durch Isolation (Das Netzwerk)

    networks:
      - database_internal
    # ports:
    #   - "127.0.0.1:3306:3306"  <-- Auskommentiert!

Das ist der wichtigste Sicherheits-Aspekt. Wir stecken die Datenbank in das Netzwerk database_internal. Da dieses Netzwerk als internal: true definiert ist (siehe Teil 4), ist die Datenbank vom Internet aus unsichtbar.

Mehr noch: Wir haben den Abschnitt ports auskommentiert oder weggelassen. Das bedeutet, man kann nicht einmal vom Host-Server direkt auf Port 3306 zugreifen. Der einzige Weg zur Datenbank führt über das Docker-Netzwerk.

Persistenz (Volumes)

    volumes:
      - mariadb-global-data:/var/lib/mysql
      - /opt/containers/mariadb/config:/etc/mysql/conf.d:ro

Container sind vergesslich. Wenn wir MariaDB neu starten, wären alle Daten weg. Deshalb mounten wir ein Volume. mariadb-global-data ist ein Docker-Volume, in dem die eigentlichen Datenbank-Dateien liegen. Selbst wenn wir den Container löschen, bleiben die Daten in diesem Volume sicher.


Schritt 2: Das Helper-Script (db_create.sh)

Jetzt haben wir einen laufenden Datenbank-Server. Aber wie bekommen wir da Daten rein? Normalerweise müsstest du dich per Konsole in den Container einloggen, den SQL-Client starten und kryptische Befehle wie CREATE USER 'hans'@'%' IDENTIFIED BY 'geheim'; tippen. Tippfehler sind vorprogrammiert.

Deshalb habe ich dir das Skript db_create.sh geschrieben. Es nimmt dir diese Arbeit ab.

Was macht das Skript?

  1. Es fragt dich interaktiv nach den Zugangsdaten (Root-Passwort, neuer DB-Name, neuer User).
  2. Es prüft, ob du alles richtig eingegeben hast (Passwort-Bestätigung).
  3. Es baut im Hintergrund den perfekten SQL-Befehl zusammen.
  4. Es sendet diesen Befehl mittels docker exec direkt in den laufenden Container.

Die Besonderheit: Der "%" Host

Im Skript findest du diese Zeile:

CREATE USER IF NOT EXISTS `${DB_USER}`@'%' ...

Das @'%' ist entscheidend. In SQL kannst du einschränken, von welcher IP ein Benutzer kommen darf. Da in Docker die IPs der Container (z.B. von WordPress) wechseln können, erlaubt % den Zugriff von jeder IP. Da unser Netzwerk database_internal aber hermetisch abgeriegelt ist, ist das sicher: Nur Container in diesem speziellen Netz können überhaupt anklopfen.


Schritt 3: Praxis-Szenario – Wir richten eine App ein

Lass uns das durchspielen. Angenommen, du möchtest nächste Woche WordPress installieren.

1. Skript starten

Du bist auf deinem Server (per SSH) und startest das Skript:

./db_create.sh

2. Daten eingeben

Das Skript fragt dich ab. Du gibst ein:

  • Root-Passwort: (Das aus deiner .env Datei)
  • Neuer DB-Name: wordpress_db
  • Neuer Benutzer: wp_user
  • Neues Passwort: super-sicheres-wp-passwort

3. Ergebnis

Wenn alles klappt, siehst du eine grüne Erfolgsmeldung. Das Skript hat die Datenbank angelegt. Jetzt gehst du in deine wordpress-docker-compose.yml und trägst genau diese Daten ein:

services:
  wordpress:
    image: wordpress:latest
    environment:
      WORDPRESS_DB_HOST: mariadb-global  <-- Der Container-Name!
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: super-sicheres-wp-passwort
      WORDPRESS_DB_NAME: wordpress_db
    networks:
      - traefik_public    (Damit es erreichbar ist)
      - database_internal (Damit es zur DB kommt)

Das ist das Geheimnis: WordPress nutzt den Container-Namen mariadb-global als Hostname. Docker löst das intern in die korrekte IP auf.


Abschluss des Core-Stacks

Herzlichen Glückwunsch! Du hast es geschafft. Wir haben in 9 Teilen eine Infrastruktur aufgebaut, die professionellen Standards entspricht:

  • Wir haben ein sauberes Netzwerk-Konzept.
  • Wir haben Traefik als zentralen, sicheren Eingang.
  • Wir haben Crowdsec als aktiven Schutz.
  • Wir haben Authentik für die Benutzerverwaltung.
  • Wir haben MariaDB für die Daten.

Ab jetzt können wir uns dem spaßigen Teil widmen: Dem Installieren von Anwendungen (Apps). Da das Fundament steht, wird das ein Kinderspiel sein.

Published inHowToNerdStuffTutorial

Sei der Erste der einen Kommentar abgibt

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert