Mehrere Domains auf einer Maschine zu betreiben ist normal und sparsam. Ob es sicher ist, entscheidet ihre Trennung: eigene Verzeichnisse, eigene Datenbankbenutzer und idealerweise eigene Systembenutzer.

Der Aufbau

/var/www/
  site-one/    public/  storage/
  site-two/    public/  storage/
  site-three/  public/  storage/

Jedes Document Root zeigt auf sein eigenes öffentliches Verzeichnis. Nichts darüber ist aus dem Web erreichbar, also liegen Konfiguration und Speicher außerhalb dessen, wo eine URL je landen könnte.

Ein Serverblock je Domain

server {
    listen 443 ssl;
    server_name one.example;
    root /var/www/site-one/public;
    include snippets/php.conf;
}

Die Datenbanken auseinanderhalten

CREATE DATABASE site_one CHARACTER SET utf8mb4;
CREATE USER 'site_one'@'localhost' IDENTIFIED BY '...';
GRANT ALL PRIVILEGES ON site_one.* TO 'site_one'@'localhost';
Ein Datenbankbenutzer mit Zugriff auf alle Datenbanken heißt: eine einzige kompromittierte Website liest und schreibt sie alle. Das ist der häufigste Fehler auf einem Mehr-Website-Server, und er macht aus einem Vorfall alle Vorfälle auf einmal.

Getrennte PHP-Pools, wenn möglich

Ein Pool je Website, jeder als eigener Benutzer, heißt: Eine Website kann die Dateien der anderen nicht lesen, obwohl sie sich eine Maschine teilen. Und es verhindert, dass der Verkehr einer Website die Worker aufbraucht, die alle anderen brauchen.

; /etc/php/8.3/fpm/pool.d/site-one.conf
[site-one]
user = site-one
group = site-one
listen = /run/php/site-one.sock
pm = ondemand
pm.max_children = 10

Zertifikate

sudo certbot --nginx -d one.example -d www.one.example
sudo certbot --nginx -d two.example -d www.two.example
Getrennte Zertifikate statt eines für alles. Dann kann die Erneuerung einer Domain die anderen nicht mitreißen, und das Zertifikat veröffentlicht nicht die Liste aller Websites, die Sie betreiben.