Ubuntu · Debian · VPS

Datenbank

MariaDB + phpMyAdmin

Kompakte Datenbankverwaltung ohne Apache oder Nginx: Caddy übernimmt HTTPS und Auslieferung, PHP-FPM verarbeitet PHP, MariaDB stellt die Datenbank bereit.

ohne Apache ohne Nginx automatisches HTTPS lokaler DB-Port

1. Architektur

flowchart LR
    Browser["Browser"] -->|"HTTPS · 443"| Caddy["Caddy
Reverse Proxy + Auto-TLS"] Caddy -->|"Unix-Socket"| FPM["PHP-FPM"] FPM --> PMA["phpMyAdmin"] PMA -->|"127.0.0.1 : 3306"| DB[("MariaDB")] classDef default fill:#112338,stroke:#45d3ff,stroke-width:1px,color:#dce8f5,rx:8,ry:8 classDef db fill:#0d1b2a,stroke:#7fffd4,stroke-width:1.5px,color:#dce8f5 class DB db linkStyle default stroke:#45d3ff,stroke-width:1.5px,color:#91a7bd
Eigene Subdomain empfohlen Zum Beispiel db.example.de. Der DNS-Eintrag muss auf die öffentliche IP-Adresse des VPS zeigen, bevor Caddy ein TLS-Zertifikat anfordern kann.

2. MySQL oder MariaDB?

MariaDB ist ein 2009 von den ursprünglichen MySQL-Gründern gestarteter Fork von MySQL – als Reaktion auf die Übernahme von MySQL durch Sun und später Oracle. Beide Systeme sprechen bis heute dasselbe Protokoll auf Port 3306 und nutzen dieselben Client-Bibliotheken (z. B. php-mysql), haben sich seit MySQL 5.7/MariaDB 10.2 aber zunehmend auseinanderentwickelt.

KriteriumMySQLMariaDB
Träger / Entwicklung Oracle Corporation MariaDB Foundation / MariaDB plc (community-getragen)
Lizenz GPL (Community-Edition) plus kostenpflichtige, proprietäre Enterprise-Erweiterungen Vollständig quelloffen (GPL), keine proprietäre Variante
Paketname unter Ubuntu/Debian mysql-server mariadb-server – auf Debian seit einigen Jahren die Vorgabe, wenn mysql-server installiert wird
Kompatibilität Referenzimplementierung des MySQL-Protokolls Weitgehend Drop-in-kompatibel (gleicher Port, gleiche Clients), aber kein 100%iger Gleichlauf mehr in neueren Versionen
Storage-Engines InnoDB (Standard), MyISAM InnoDB, zusätzlich eigene Engines wie Aria, ColumnStore, Spider
Clustering InnoDB Cluster / Group Replication Galera Cluster nativ integriert
Feature-Roadmap Eigenständig, z. B. MySQL 8.x/9.x Eigenständig seit ca. Version 10.2/10.3, zunehmend abweichend von MySQL
Warum diese Anleitung MariaDB verwendet MariaDB ist auf Debian-basierten Systemen der Standard in den Distributions-Repos, vollständig quelloffen und ohne Lizenzrisiko durch Oracle. Für die meisten Web-Anwendungen (auch phpMyAdmin) ist der Unterschied im Alltag nicht spürbar.
Migration zwischen beiden Systemen Ein Wechsel ist in der Regel über einen klassischen Dump/Restore möglich (mysqldump bzw. mariadb-dump), da beide dasselbe SQL-Dialekt-Fundament teilen. Bei Nutzung sehr neuer, versionsspezifischer Funktionen (z. B. bestimmte JSON- oder Window-Funktionen) vorher die Kompatibilität prüfen.

3. MariaDB und PHP installieren

Pakete installieren
sudo apt update
Pakete installieren
sudo apt install mariadb-server php-fpm php-mysql php-mbstring php-xml php-curl php-zip php-gd

Dienste aktivieren und direkt starten:

Dienste aktivieren
sudo systemctl enable --now mariadb
Dienste aktivieren
sudo systemctl enable --now php8.5-fpm
PHP-Dienstname prüfen Der genaue Name hängt von der installierten PHP-Version ab und kann abweichen (z. B. php8.3-fpm). Vorab prüfen und danach konsequent in allen folgenden Befehlen verwenden.
Installierten PHP-FPM-Dienst ermitteln
systemctl list-unit-files | grep 'php.*fpm'

4. Editor-Grundlagen: nano und vim

nano zeigt die wichtigsten Tastenkombinationen permanent am unteren Bildschirmrand an und eignet sich für schnelle Änderungen. vim ist auf praktisch jedem Linux-System vorinstalliert und funktioniert auch dann zuverlässig, wenn Copy & Paste in einer Konsole (z. B. VNC oder seriellen Konsole) nicht verfügbar ist.

Anders als nano arbeitet vim modal: Der Normalmodus ist der Startzustand zum Navigieren, mit i/a/o wechselt man in den Einfügemodus, mit : in den Kommandozeilenmodus zum Speichern, Suchen/Ersetzen und Beenden.

Taste / BefehlWirkung
iEinfügen vor der Cursorposition
EscZurück in den Normalmodus (immer zuerst drücken)
:wqSpeichern und beenden
:q!Beenden ohne zu speichern
ddAktuelle Zeile löschen
uRückgängig
/suchbegriffVorwärts suchen, weiter mit n
:%s/alt/neu/gAlle Vorkommen von „alt“ durch „neu“ ersetzen

Beide Editoren sind für alle folgenden Konfigurationsschritte gleichwertig einsetzbar; die Befehle in diesem Dokument zeigen nano, alternativ funktioniert überall vim.

5. MariaDB grundlegend absichern

Absicherungs-Assistent
sudo mariadb-secure-installation

Üblicherweise sind folgende Einstellungen sinnvoll:

  • Anonyme Benutzer entfernen
  • Testdatenbank löschen
  • Remote-Root-Login deaktivieren
  • Berechtigungstabellen neu laden

6. Separaten Datenbankbenutzer anlegen

Öffne zunächst die MariaDB-Konsole:

MariaDB-Konsole öffnen
sudo mariadb

Lege anschließend einen eigenen Administrator für phpMyAdmin an:

SQL: Datenbankbenutzer anlegen
CREATE USER 'dbadmin'@'localhost'
IDENTIFIED BY 'EIN_SEHR_STARKES_PASSWORT';

GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'localhost'
WITH GRANT OPTION;

FLUSH PRIVILEGES;
EXIT;
Vollzugriff bewusst einsetzen Dieser Benutzer besitzt vollständige Administratorrechte. Für einzelne Websites oder Anwendungen sollten später separate Benutzer mit eingeschränkten Rechten verwendet werden.

7. phpMyAdmin installieren

Paket installieren
sudo apt install phpmyadmin

Während der Installation:

  • Keinen Webserver auswählen
  • Mit Tab zu „OK“ wechseln und bestätigen
  • Einrichtung über dbconfig-common bestätigen

phpMyAdmin liegt anschließend in der Regel unter:

Installationspfad
/usr/share/phpmyadmin
Apache kann blockieren Falls Apache versehentlich installiert oder aktiviert wurde, kann er Caddy auf Port 80 oder 443 blockieren.
Apache entfernen
sudo systemctl disable --now apache2
Apache entfernen
sudo apt remove apache2

8. PHP-FPM-Socket prüfen

Socket-Datei suchen
find /run/php -name '*.sock'

Eine typische Ausgabe lautet (Version entsprechend der eigenen Installation):

Beispielpfad
/run/php/php8.5-fpm.sock

Dienststatus kontrollieren:

Status prüfen
sudo systemctl status php8.5-fpm

9. Caddy konfigurieren

Öffne die Caddy-Konfiguration:

Caddyfile bearbeiten
sudo nano /etc/caddy/Caddyfile
Caddyfile bearbeiten
# oder:
sudo vim /etc/caddy/Caddyfile

Minimale Konfiguration für eine eigene Subdomain:

Caddyfile: Minimalkonfiguration
db.example.de {
    root * /usr/share/phpmyadmin
    php_fastcgi unix//run/php/php8.5-fpm.sock
    file_server
}

Konfiguration validieren und neu laden:

Validieren und neu laden
sudo caddy validate --config /etc/caddy/Caddyfile
Validieren und neu laden
sudo systemctl reload caddy
Automatisches HTTPS Sobald die Subdomain korrekt auf den VPS zeigt und die Ports 80 sowie 443 erreichbar sind, fordert Caddy automatisch ein TLS-Zertifikat an.

Wichtige Caddyfile-Direktiven

DirektiveBedeutung
root * <pfad>Basisverzeichnis, aus dem file_server und php_fastcgi Dateien ausliefern.
php_fastcgi <socket|adresse>Leitet .php-Anfragen an PHP-FPM weiter, per Unix-Socket (unix//pfad) oder TCP (127.0.0.1:9000).
file_serverLiefert statische Dateien (CSS, JS, Bilder) direkt aus root aus.
basic_authFragt vor jedem Zugriff Benutzername/Passwort ab, geprüft gegen einen mit caddy hash-password erzeugten Hash.
headerSetzt zusätzliche HTTP-Antwort-Header, z. B. für Sicherheits-Policies.
tls internalErzwingt ein lokal signiertes Zertifikat statt eines öffentlichen Let's-Encrypt-Zertifikats – nützlich für interne/Test-Domains ohne öffentliches DNS.
encode gzipAktiviert Kompression der Antworten, reduziert Ladezeiten.
logSchreibt Zugriffslogs, standardmäßig nach stdout bzw. in den systemd-Journal-Log von Caddy.

Alternative: Apache2 statt Caddy

Nur einen Webserver gleichzeitig betreiben Apache2 und Caddy können nicht beide dieselben Ports 80/443 belegen. Vor der Umstellung Caddy stoppen und deaktivieren: sudo systemctl disable --now caddy.
Apache und PHP-FPM-Anbindung installieren
sudo apt install apache2
Apache und PHP-FPM-Anbindung installieren
sudo a2enmod proxy_fcgi setenvif
Apache und PHP-FPM-Anbindung installieren
sudo a2enconf php8.5-fpm

Das PHP-FPM-Paket legt beim Installieren automatisch die Datei /etc/apache2/conf-available/php8.5-fpm.conf an; a2enconf aktiviert sie und verbindet Apache über proxy_fcgi mit dem PHP-FPM-Socket.

VirtualHost für phpMyAdmin anlegen:

Neue Konfigurationsdatei erstellen
sudo nano /etc/apache2/sites-available/db.example.de.conf
VirtualHost: Minimalkonfiguration
<VirtualHost *:80>
    ServerName db.example.de
    DocumentRoot /usr/share/phpmyadmin

    <Directory /usr/share/phpmyadmin>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/db.example.de-error.log
    CustomLog ${APACHE_LOG_DIR}/db.example.de-access.log combined
</VirtualHost>
Site aktivieren und neu laden
sudo a2ensite db.example.de.conf
Site aktivieren und neu laden
sudo apache2ctl configtest
Site aktivieren und neu laden
sudo systemctl reload apache2

Anders als Caddy stellt Apache kein automatisches HTTPS bereit. Ein Zertifikat lässt sich über Certbot einrichten, das den VirtualHost passend ergänzt:

TLS-Zertifikat mit Certbot
sudo apt install certbot python3-certbot-apache
TLS-Zertifikat mit Certbot
sudo certbot --apache -d db.example.de

Wichtige Apache-Direktiven

DirektiveBedeutung
DocumentRootBasisverzeichnis der ausgelieferten Website, entspricht Caddys root *.
<Directory>Blockweise Rechte- und Optionszuweisung für ein Verzeichnis, z. B. AllowOverride für .htaccess.
Require all grantedErlaubt den Zugriff für alle Clients (Apache-2.4-Syntax, ersetzt das alte Allow from all).
ProxyPassMatch / SetHandler "proxy:unix:..."Alternative Wege, .php-Anfragen an PHP-FPM weiterzuleiten, falls a2enconf php-fpm nicht greift.
AuthType Basic / AuthUserFileAktiviert Basic Auth in Kombination mit einer per htpasswd erzeugten Passwortdatei – das Apache-Äquivalent zu Caddys basic_auth.

Alternative: Nginx statt Caddy

Nur einen Webserver gleichzeitig betreiben Auch Nginx belegt die Ports 80/443. Vor der Umstellung Caddy stoppen und deaktivieren: sudo systemctl disable --now caddy.
Nginx installieren
sudo apt install nginx

Server-Block für phpMyAdmin anlegen:

Neue Konfigurationsdatei erstellen
sudo nano /etc/nginx/sites-available/db.example.de
Server-Block: Minimalkonfiguration
server {
    listen 80;
    server_name db.example.de;
    root /usr/share/phpmyadmin;
    index index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.5-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}
Aktivieren, prüfen und neu laden
sudo ln -s /etc/nginx/sites-available/db.example.de /etc/nginx/sites-enabled/
Aktivieren, prüfen und neu laden
sudo nginx -t
Aktivieren, prüfen und neu laden
sudo systemctl reload nginx

Auch Nginx liefert kein automatisches HTTPS – ein Zertifikat lässt sich ebenfalls über Certbot einrichten:

TLS-Zertifikat mit Certbot
sudo apt install certbot python3-certbot-nginx
TLS-Zertifikat mit Certbot
sudo certbot --nginx -d db.example.de

Wichtige Nginx-Direktiven

DirektiveBedeutung
rootBasisverzeichnis der ausgelieferten Website, entspricht Caddys root *.
indexDatei, die bei Verzeichnisaufrufen ohne Dateiname ausgeliefert wird (hier index.php).
locationRegelblock für passende URL-Pfade oder -Muster, vergleichbar mit Caddys Matcher-Syntax.
fastcgi_passLeitet .php-Anfragen an PHP-FPM weiter, per Unix-Socket oder TCP – Nginx-Pendant zu Caddys php_fastcgi.
fastcgi_param SCRIPT_FILENAMETeilt PHP-FPM den vollständigen Dateipfad des aufzurufenden Skripts mit; ohne diesen Parameter schlägt die Ausführung fehl.
try_filesPrüft nacheinander mehrere Pfade/Dateien und liefert die erste passende aus, sonst 404 – hier das Nginx-Äquivalent zu Caddys file_server.
auth_basic / auth_basic_user_fileAktiviert Basic Auth gegen eine per htpasswd erzeugte Datei – das Nginx-Äquivalent zu Caddys basic_auth.

10. Zugriff zusätzlich schützen

phpMyAdmin sollte nicht ohne zusätzliche Schutzschicht frei im Internet erreichbar sein.

Passwort-Hash erzeugen

Hash erzeugen
caddy hash-password

Caddy mit Basic Auth

Caddyfile: mit Basic Auth und Security-Headern
db.example.de {
    basic_auth {
        USERNAME DEIN_PASSWORT_HASH
    }

    root * /usr/share/phpmyadmin
    php_fastcgi unix//run/php/php8.5-fpm.sock
    file_server

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy same-origin
    }
}
Platzhalter ersetzen USERNAME steht für den gewünschten Basic-Auth-Login (frei wählbar, unabhängig vom Linux- oder Datenbankbenutzer), DEIN_PASSWORT_HASH für die Ausgabe von caddy hash-password. Beide vor dem Einsatz durch echte Werte ersetzen.

Anschließend erneut prüfen und laden:

Validieren und neu laden
sudo caddy validate --config /etc/caddy/Caddyfile
Validieren und neu laden
sudo systemctl reload caddy
Zweistufige Anmeldung Danach erfolgt zuerst die Anmeldung an Caddy und anschließend die Datenbankanmeldung in phpMyAdmin.

11. MariaDB-Konfiguration prüfen und anpassen

Lauschenden Port prüfen
sudo ss -lntp | grep 3306

Optimal ist eine Bindung ausschließlich an die lokale Adresse:

Erwartete Ausgabe
127.0.0.1:3306

Falls MariaDB extern lauscht, prüfe folgende Datei:

Konfiguration bearbeiten
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Konfiguration bearbeiten
# oder:
sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf

Danach MariaDB neu starten:

Dienst neu starten
sudo systemctl restart mariadb

Wichtige Direktiven in 50-server.cnf

DirektiveEmpfehlungBedeutung
bind-address 127.0.0.1 Bindet MariaDB an die lokale Adresse; von außen ist der Port dann nicht erreichbar. Zugriff von entfernten Anwendungen läuft stattdessen über SSH-Tunnel oder ein privates Netzwerk.
port 3306 TCP-Port des Datenbankdiensts. Nur relevant, wenn bind-address nicht auf 127.0.0.1 steht bzw. für lokale TCP-Verbindungen.
socket /run/mysqld/mysqld.sock Pfad zum Unix-Socket für lokale Verbindungen ohne TCP – schneller als 127.0.0.1 und von bind-address unabhängig.
datadir /var/lib/mysql Speicherort aller Datenbankdateien. Bei Änderung müssen Dateirechte und AppArmor/SELinux-Profile angepasst werden.
max_connections 151 (Standard) oder höher Maximale Anzahl gleichzeitiger Client-Verbindungen. Bei vielen parallelen Anwendungen ggf. erhöhen, erhöht aber auch den RAM-Bedarf.
innodb_buffer_pool_size ca. 60–70 % des verfügbaren RAM (dediziert) Cache für InnoDB-Tabellen und -Indizes im Arbeitsspeicher. Wichtigster Wert für die Performance, auf kleinen VPS aber konservativ wählen.
character-set-server / collation-server utf8mb4 / utf8mb4_unicode_ci Standard-Zeichensatz neuer Datenbanken. utf8mb4 unterstützt im Gegensatz zum alten utf8 auch Emojis und den vollen Unicode-Bereich.
skip-networking nicht gesetzt (aus) Würde TCP/IP komplett deaktivieren und nur noch Unix-Socket-Verbindungen erlauben – für einen reinen Localhost-Betrieb eine zusätzliche Alternative zu bind-address.
slow_query_log / long_query_time 1 / 2 (Sekunden) Protokolliert Abfragen, die länger als long_query_time dauern, in slow_query_log_file – hilfreich zur Performance-Analyse.
log_error /var/log/mysql/error.log Pfad der Fehlerprotokolldatei, erste Anlaufstelle bei Startproblemen.
RAM im Blick behalten Änderungen an innodb_buffer_pool_size oder max_connections ohne Rücksicht auf den tatsächlich verfügbaren RAM können auf kleinen VPS-Instanzen zu Out-of-Memory-Abbrüchen führen. Werte schrittweise erhöhen und Speicherauslastung beobachten.

12. Fehlersuche

Caddy-Protokoll

Live-Log
sudo journalctl -u caddy -f

PHP-FPM-Protokoll

Live-Log
sudo journalctl -u php8.5-fpm -f

MariaDB-Protokoll

Live-Log
sudo journalctl -u mariadb -f

Aktive Dienste prüfen

Status aller Dienste
systemctl status caddy mariadb php8.5-fpm

Caddy-Konfiguration formatieren

Formatieren
sudo caddy fmt --overwrite /etc/caddy/Caddyfile

13. Abschlusscheck

  • DNS-Subdomain zeigt auf die öffentliche VPS-IP
  • Caddy läuft und besitzt ein gültiges HTTPS-Zertifikat
  • PHP-FPM-Socket stimmt mit der Caddy-Konfiguration überein
  • phpMyAdmin öffnet sich über die gewünschte Subdomain
  • Basic Auth oder eine IP-Beschränkung ist aktiv
  • MariaDB lauscht nur auf 127.0.0.1:3306
  • Für Anwendungen werden separate DB-Benutzer verwendet
  • Regelmäßige Datenbank-Backups sind eingerichtet
↑ Nach oben