Eigene Projekte einfach umsetzen
Hosten Sie Ihr Projekt einfach selbst auf einem NAS mit passenden Festplatten!
Jetzt mehr erfahren
Anzeige

    VPS Hosting für mehrere Domains: Was Sie wissen müssen

    KI-generiert
    10.09.2026 277 mal gelesen 5 Kommentare
    • Ein VPS bietet dedizierte Ressourcen und volle Administrationsfreiheit, sodass Sie mehrere Domains unabhängig voneinander auf getrennten Websites, Anwendungen oder Hosting-Umgebungen betreiben können.
    • Achten Sie auf ausreichende CPU-, RAM- und Speicherressourcen, skalierbare Bandbreite sowie die Möglichkeit, für jede Domain eigene DNS-Einträge, SSL-Zertifikate, E-Mail-Konten und Datenbanken einzurichten.
    • Sie sind selbst für Updates, Sicherheitsmaßnahmen, Backups, Serverüberwachung und die korrekte Konfiguration von Webserver, Firewall und Benutzerrechten verantwortlich.

    Mehrere Flask-Anwendungen mit einer öffentlichen IP-Adresse betreiben

    Eine einzige öffentliche IP-Adresse reicht aus, um mehrere Flask-Anwendungen parallel bereitzustellen. Entscheidend ist die Kombination aus Domainnamen, Ports und einer vorgeschalteten Routing-Schicht. Der VPS nimmt den Webverkehr auf den Standardports 80 und 443 an und ordnet jede Anfrage anschließend der passenden Anwendung zu.

    Werbung

    Intern erhält jede Anwendung einen eigenen Dienst. So kann etwa app1.example auf 127.0.0.1:5001 und app2.example auf 127.0.0.1:5002 laufen. Von außen bleiben diese Ports unsichtbar. Besucher sehen nur die jeweilige Domain, während einzelne Flask-Prozesse nicht direkt aus dem Internet erreichbar sind.

    Eigene Projekte einfach umsetzen
    Hosten Sie Ihr Projekt einfach selbst auf einem NAS mit passenden Festplatten!
    Jetzt mehr erfahren
    Anzeige

    Die Zuordnung erfolgt über den sogenannten Host-Header der HTTP-Anfrage. Bei HTTPS kommt zusätzlich der angeforderte Domainname aus dem TLS-Aushandlungsprozess hinzu. Der Reverse Proxy kann dadurch unterscheiden, ob jemand shop.example oder blog.example aufruft, obwohl beide Namen auf dieselbe IPv4-Adresse zeigen. Genau dieses Prinzip macht virtuelle Hosts möglich.

    • Domain A: Weiterleitung an den internen Dienst auf Port 5001
    • Domain B: Weiterleitung an den internen Dienst auf Port 5002
    • Domain C: Weiterleitung an einen weiteren Dienst, Container oder eine statische Website

    Für die Flask-Projekte empfiehlt sich eine klare Trennung der Laufzeitumgebungen. Jedes Projekt sollte sein eigenes Verzeichnis, eine eigene virtuelle Python-Umgebung und eigene Konfigurationswerte besitzen. Dadurch führt ein Bibliotheksupdate in einer Anwendung nicht automatisch zu Problemen in den anderen. Gemeinsame Geheimnisse gehören nicht in den Quellcode; pro Dienst sind getrennte Umgebungsvariablen sinnvoll.

    Mehrere Anwendungen können zwar denselben Datenbankserver nutzen, sollten aber getrennte Datenbanken oder mindestens eigene Datenbankbenutzer erhalten. So lassen sich Zugriffsrechte begrenzen. Auch Uploads, Sitzungsdaten und temporäre Dateien sollten je Anwendung getrennt bleiben.

    Die interne Bind-Adresse sollte grundsätzlich auf 127.0.0.1 oder ein geschütztes privates Netzwerk zeigen. Nur der Reverse Proxy muss öffentlich auf den Webports lauschen. Werden interne Ports dagegen auf 0.0.0.0 gebunden, können sie je nach Firewall-Regel direkt erreichbar sein. Das ist meist unnötig und sicherheitlich eine offene Flanke.

    Die gemeinsame IP-Adresse hat Grenzen: Fällt der VPS aus, sind alle Domains gleichzeitig betroffen. Ebenso kann ein sehr speicherhungriger Prozess andere Anwendungen ausbremsen. Für kleine Projekte ist diese Bündelung oft vernünftig. Für voneinander unabhängige Geschäftssysteme kann eine spätere Trennung auf mehrere virtuelle Maschinen oder Server sinnvoller sein.

    Vor dem Umzug sollte jede Anwendung einzeln geprüft werden: Startet sie ohne Entwicklungsserver, funktionieren statische Dateien, sind Datenbankverbindungen korrekt und kennt die App die externe HTTPS-Adresse? Besonders bei Flask sind Proxy-Header wichtig, damit sichere Cookies, Weiterleitungen und erzeugte URLs nicht mit falschem Schema oder Host erscheinen. Erst wenn eine App isoliert sauber läuft, sollte die nächste Domain dazukommen.

    Das Grundmodell lautet damit: eine öffentliche IP, ein zentraler Eingang, mehrere interne Dienste. Die Domains bilden die sichtbare Trennung für Besucher. Eigene Prozesse, Verzeichnisse, Berechtigungen und Datenbanken schaffen die technische Trennung dahinter.

    DNS-Einträge für mehrere Domains und Subdomains richtig setzen

    Für jede Domain oder Subdomain wird im DNS ein eigener Eintrag angelegt. Zeigt er auf die öffentliche IP-Adresse des VPS, kann der Server die Anfrage später anhand des Domainnamens zuordnen. Zusätzliche öffentliche IP-Adressen sind dafür nicht nötig.

    Für eine IPv4-Adresse dient ein A-Record. Beispiel:

    • example1.de → A → 203.0.113.10
    • example2.de → A → 203.0.113.10
    • app.example1.de → A → 203.0.113.10

    Ein Name ohne eigenen A-Record kann auch über einen CNAME auf eine vorhandene Subdomain zeigen:

    • www.example1.de → CNAME → example1.de

    Das ist praktisch für www-Varianten. Ein CNAME darf jedoch nicht einfach zusätzlich am Zonenstamm verwendet werden, weil dort bereits wichtige Einträge wie SOA und NS stehen. Manche DNS-Dienste bieten dafür eigene ALIAS- oder ANAME-Funktionen an.

    IPv6 darf nicht übersehen werden. Existiert ein AAAA-Record, versucht ein Besucher oft zuerst die IPv6-Adresse. Zeigt dieser Eintrag auf einen anderen Server oder ist IPv6 dort nicht korrekt eingerichtet, wirkt die Website je nach Netzwerk unerreichbar. Deshalb gilt: Entweder IPv6 vollständig konfigurieren oder einen veralteten AAAA-Eintrag entfernen.

    Die verwendeten Namen müssen exakt mit den späteren Serverkonfigurationen übereinstimmen. example1.de, www.example1.de und api.example1.de sind drei verschiedene Hostnamen. Wer Besucher von www auf die Hauptdomain umleiten möchte, muss beide Namen technisch berücksichtigen und die Weiterleitung bewusst festlegen.

    Nach einer Änderung ist die Aktualisierung nicht immer sofort überall sichtbar. Maßgeblich ist die TTL, also die Gültigkeitsdauer eines DNS-Eintrags im Cache. Eine TTL von 300 Sekunden ermöglicht bei einem Umzug eine relativ schnelle Anpassung. Bereits zwischengespeicherte Antworten können trotzdem länger erscheinen.

    Vor dem Umzug empfiehlt sich ein kurzer Abgleich:

    • Ist die öffentliche IPv4-Adresse des VPS korrekt?
    • Existieren widersprüchliche A-, AAAA- oder CNAME-Einträge?
    • Zeigen alle gewünschten Namen auf das richtige Ziel?
    • Sind alte Einträge beim bisherigen Hosting entfernt oder bewusst als Übergang belassen?
    • Stimmen die Schreibweise und die verwendeten Subdomains mit der geplanten Serverkonfiguration überein?

    Die Auflösung lässt sich mit Werkzeugen wie dig oder nslookup prüfen. Für eine einzelne Domain liefert etwa dig example1.de A die IPv4-Antwort. Mit dig example1.de AAAA wird sichtbar, ob zusätzlich ein IPv6-Ziel veröffentlicht ist. Öffentliche DNS-Prüfdienste helfen beim Vergleich verschiedener Nameserver, ersetzen aber keine Kontrolle beim eigenen DNS-Anbieter.

    Für Zertifikate sollten alle tatsächlich genutzten Namen schon auf den VPS zeigen, bevor die Ausstellung beginnt. Ein Zertifikat für example1.de deckt nicht automatisch www.example1.de oder api.example1.de ab. Diese Namen müssen ausdrücklich im Zertifikat enthalten sein. Wildcard-Zertifikate wie *.example1.de gelten außerdem nicht für die Hauptdomain selbst und verlangen meist eine DNS-basierte Validierung.

    DNS entscheidet nur, welche IP-Adresse erreicht wird. Es entscheidet nicht über interne Ports und startet keine Flask-Anwendung. Erst die Konfiguration auf dem VPS verarbeitet den Hostnamen und setzt die Anfrage in die passende Anwendung um.

    Reverse Proxy: Domains gezielt an interne Ports weiterleiten

    Der Reverse Proxy ist die zentrale Verkehrsschleuse des VPS. Er nimmt Webanfragen entgegen, prüft den angeforderten Hostnamen und wählt danach den passenden internen Dienst. Für Besucher bleibt diese Weiterleitung unsichtbar; sie rufen weiterhin eine normale Domain auf, nicht einen Port wie :5001.

    In der Praxis erhält jede Anwendung einen eigenen Proxy-Eintrag. Dieser enthält mindestens den Domainnamen, das Ziel innerhalb des Servers und Regeln für die Weitergabe wichtiger Anfrageinformationen. Ein mögliches Schema sieht so aus:

    • portal.example.de → 127.0.0.1:5001
    • kunden.example.de → 127.0.0.1:5002
    • api.example.de → 127.0.0.1:5003

    Der Proxy sollte den ursprünglichen Hostnamen, das verwendete Protokoll und die Client-IP kontrolliert weiterreichen. Flask-Erweiterungen benötigen diese Angaben etwa für absolute URLs, sichere Cookies, Zugriffssperren oder Protokolle. Fehlen sie, entstehen typische Fehler: HTTPS-Links werden als HTTP erzeugt, Weiterleitungen zeigen auf den falschen Namen oder im Log erscheint nur die Adresse des Proxyservers.

    Bei der Client-IP ist Vorsicht angebracht. Ein Backend darf den Header X-Forwarded-For nicht blind als Wahrheit übernehmen. Nur der eigene Proxy darf diesen Wert setzen oder ergänzen. Andernfalls könnte ein Besucher eine fremde IP-Adresse vortäuschen und damit Rate-Limits oder Zugriffsregeln umgehen. Flask sollte daher so konfiguriert sein, dass nur eine bekannte Proxy-Schicht als vertrauenswürdig gilt.

    Ein sauberer Proxy-Eintrag begrenzt außerdem die zulässigen Anfragegrößen und Wartezeiten. Uploads, lange API-Aufrufe und Streaming benötigen andere Werte als eine gewöhnliche HTML-Seite. Zu kleine Limits führen zu scheinbar zufälligen Fehlern wie 413 Request Entity Too Large; zu lange Timeouts halten dagegen Verbindungen und Arbeitsspeicher unnötig fest. Diese Werte sollten pro Anwendung festgelegt werden.

    Statische Dateien können direkt vom Proxy ausgeliefert werden. CSS, JavaScript und Bilder müssen dann nicht durch den Python-Prozess laufen. Das senkt die Last und verbessert meist die Antwortzeit. Dynamische Pfade bleiben beim WSGI-Dienst. Wichtig ist, dass der Pfad zur jeweiligen Dateistruktur eindeutig bleibt; eine versehentliche gemeinsame Ablage kann Dateien zwischen Projekten vermischen.

    Für APIs und WebSocket-Verbindungen gelten zusätzliche Proxy-Regeln. Upgrade-Header müssen korrekt weitergereicht werden, sonst bricht eine dauerhafte Verbindung ab. Bei normalen Flask-Seiten ist das nicht nötig. Prüfe deshalb, welche Kommunikationsform die jeweilige Anwendung tatsächlich verwendet.

    Ein Standard-Serverblock für eine unbekannte Domain sollte keine Anwendung ausliefern. Besser ist eine neutrale Fehlerantwort oder eine gezielte Ablehnung. Ohne diese Regel kann eine falsch geschriebene Domain versehentlich die erste konfigurierte Website anzeigen und bei sensiblen Inhalten Informationen preisgeben.

    Änderungen am Proxy sollten zuerst syntaktisch geprüft und danach kontrolliert neu geladen werden. Ein Reload beendet bestehende Verbindungen normalerweise nicht; ein vollständiger Neustart kann dagegen kurzzeitig alle Domains unterbrechen. Nach jeder Änderung lohnt ein Test mit dem echten Hostnamen und mit verschiedenen Pfaden. Prüfe dabei auch Fehlercodes, Weiterleitungen und die Logdatei der richtigen Anwendung.

    Die Wahl zwischen Nginx, Apache und Caddy hängt weniger von der IP-Adresse ab als von Arbeitsweise und Umgebung. Alle drei können hostbasiertes Routing übernehmen. Entscheidend bleibt eine eindeutige Zuordnung, ein geschützter interner Dienst und eine Konfiguration, die Fehler nicht stillschweigend auf die falsche Website lenkt.

    Flask-Anwendungen mit Gunicorn oder uWSGI dauerhaft ausführen

    Gunicorn oder uWSGI übernimmt zwischen dem Reverse Proxy und der Flask-Anwendung die Rolle des WSGI-Servers. Flask muss dadurch keine Verbindungen selbst verwalten. Stattdessen stellt der WSGI-Server mehrere Worker bereit, verarbeitet Anfragen und beendet sich nicht nach dem ersten Fehler gleich komplett.

    Für kleine Flask-Projekte ist Gunicorn meist der unkompliziertere Einstieg. Es lässt sich direkt aus der virtuellen Python-Umgebung starten und unterstützt mehrere Worker, Threads sowie unterschiedliche Bind-Adressen. uWSGI bietet eine sehr breite Konfiguration, ist dadurch aber anspruchsvoller. Die Wahl sollte zur Anwendung passen, nicht zu einer vermeintlichen Rangliste.

    Ein typischer Startbefehl für eine Anwendung sieht so aus:

    gunicorn --workers 2 --bind 127.0.0.1:5001 wsgi:app

    In diesem Beispiel bezeichnet wsgi:app das Python-Modul wsgi.py und das darin enthaltene Flask-Objekt app. Existiert eine Factory-Funktion, wird stattdessen etwa gunicorn --workers 2 --bind 127.0.0.1:5001 'projekt:create_app()' verwendet. Der genaue Importpfad muss zur Projektstruktur passen.

    Die Worker-Zahl richtet sich nach CPU, Speicher und Verhalten der Anwendung. Zwei Worker sind für ein kleines Projekt oft ein vernünftiger Startwert. Mehr Worker bedeuten nicht automatisch mehr Geschwindigkeit: Jeder Prozess verbraucht Speicher, und bei datenbanklastigen Aufgaben kann ein hoher Wert sogar schaden. Unter Last sollte gemessen werden. Faustformeln sind nur ein grober Kompass.

    Jede Anwendung braucht eine eigene Startdefinition. Darin stehen unter anderem der absolute Projektpfad, die virtuelle Python-Umgebung, der Benutzer, die Umgebungsvariablen und das interne Ziel. So bleibt der Dienst reproduzierbar. Ein Beispiel für eine systemd-Unit:

    [Unit]
    Description=Flask Anwendung 1
    After=network.target

    [Service]
    User=app1
    WorkingDirectory=/srv/app1
    EnvironmentFile=/etc/app1.env
    ExecStart=/srv/app1/.venv/bin/gunicorn --workers 2 --bind 127.0.0.1:5001 wsgi:app
    Restart=on-failure

    [Install]
    WantedBy=multi-user.target

    Die Datei sollte mit den Rechten des Systems geschützt werden, besonders wenn sie Zugangsdaten enthält. Nach einer Änderung wird die Unit neu eingelesen, anschließend startet der Dienst. Prüfe danach den Status und die Journal-Ausgabe. Ein grüner Prozess allein beweist noch nicht, dass die Anwendung auch eine gültige Antwort liefert.

    Für jede Flask-App ist ein eigener Linux-Benutzer sinnvoll. Dieser Benutzer benötigt nur Zugriff auf sein Projekt und die dafür erforderlichen Dateien. Ein kompromittierter Dienst kann dann nicht ohne Weiteres auf Quellcode, Konfiguration oder Uploads anderer Anwendungen zugreifen. Schreibrechte sollten sparsam vergeben werden.

    Produktionsprozesse müssen außerdem mit sauberen Abbruchsignalen umgehen. Bei einem kontrollierten Neustart sollen laufende Anfragen noch beendet werden, während neue Verbindungen bereits an neue Worker gehen. Lange Aufgaben gehören nicht in einen normalen Web-Worker. Für E-Mails, Bildverarbeitung oder umfangreiche Importe ist eine separate Hintergrundverarbeitung geeigneter.

    Gunicorn- und uWSGI-Logs sollten getrennt nach Anwendung erfasst werden. Achte auf Startfehler, wiederholte Worker-Abstürze, Zeitüberschreitungen und ungewöhnlich große Antwortzeiten. Ein passender Health-Endpunkt kann den Dienst prüfen, sollte aber keine teure Datenbankoperation bei jedem Kontrollaufruf ausführen.

    Bevor eine App dauerhaft aktiviert wird, teste vier Fälle: normaler Seitenaufruf, absichtlich ausgelöster Fehler, Neustart des Dienstes und parallele Anfragen. Erst dann zeigt sich, ob Importpfade, Berechtigungen und Worker-Einstellungen wirklich zusammenpassen. Der Entwicklungsserver bleibt dabei außen vor; er ist für lokale Tests gedacht, nicht als Produktionsschicht.

    Nginx, Apache oder Caddy als zentrale Zugangsschicht auswählen

    Die Zugangsschicht sollte den gesamten öffentlichen Webverkehr bündeln und nur die Dienste anbieten, die wirklich benötigt werden. Für mehrere Flask-Anwendungen sind Nginx, Apache und Caddy grundsätzlich geeignet. Die Unterschiede liegen vor allem bei Konfiguration, Automatisierung, Modulen und dem Aufwand im laufenden Betrieb.

    Nginx passt gut zu einem schlanken VPS. Die Konfiguration ist übersichtlich, der Speicherbedarf meist niedrig und statische Inhalte lassen sich effizient ausliefern. Mit seinen Server-Blöcken können viele Domains getrennt verwaltet werden.

    Apache bietet eine große Modulauswahl und flexible Verzeichnisregeln. Das ist hilfreich, wenn bestehende Anwendungen, komplexe Zugriffsregeln oder spezielle Erweiterungen übernommen werden müssen. Für einen neuen, reinen Flask-Server wirkt Apache allerdings oft umfangreicher als nötig.

    Caddy richtet sich an Betreiber, die möglichst wenig Handarbeit bei der Bereitstellung wünschen. Eine kurze Konfiguration kann mehrere Hostnamen bedienen. Zertifikate und Weiterleitungen werden weitgehend automatisch verwaltet. Das spart Zeit, verlangt aber Vertrauen in die Automatisierung und eine saubere Kontrolle der erzeugten Einstellungen.

    • Nginx: schlank, schnell und gut für präzise Einzelkonfigurationen
    • Apache: vielseitig, modular und stark bei bestehenden Serverstrukturen
    • Caddy: einfacher Einstieg mit viel Automatisierung

    Für die Auswahl zählt das Betriebsmodell. Werden häufig neue Domains hinzugefügt, kann eine leicht automatisierbare Konfiguration den Ausschlag geben. Gibt es viele Sonderregeln oder ältere Webprojekte, ist die breite Modulwelt von Apache nützlich. Bei wenigen Flask-Apps und einem klaren, manuellen Setup reicht meist eine schlanke Lösung.

    Unabhängig vom Produkt sollte nur eine Zugangsschicht gleichzeitig die öffentlichen Webports belegen. Ein häufiger Fehler ist, mehrere Webserver parallel zu installieren, obwohl sie beide auf Port 80 oder 443 lauschen wollen. Zusätzliche Instanzen können intern arbeiten, müssen dann aber andere Ports oder Unix-Sockets verwenden.

    Unix-Sockets sind für lokale Verbindungen oft eine gute Alternative zu TCP-Ports. Sie vermeiden eine Netzwerköffnung und können über Dateirechte geschützt werden. Ein Socket pro Anwendung erleichtert außerdem die Zuordnung. TCP bleibt sinnvoll, wenn Dienste in getrennten Containern oder auf unterschiedlichen Rechnern laufen.

    Auch die Konfigurationsstruktur verdient Aufmerksamkeit. Lege pro Domain eine eigene Datei oder einen klar abgegrenzten Abschnitt an. Gemeinsame Regeln, etwa für Sicherheits-Header oder Komprimierung, sollten zentral gepflegt werden. Individuelle Besonderheiten gehören dagegen zur jeweiligen Website. So bleibt eine Änderung an kunden.example.de von blog.example.de getrennt.

    Vor der Aktivierung sollte der Webserver seine Konfiguration prüfen können. Danach testest du jede Domain einzeln, einschließlich einer nicht vorgesehenen Domain. Kontrolliere Statuscodes, Weiterleitungen, große Antworten und Fehlermeldungen. Ein automatischer Konfigurationscheck im Deployment verhindert, dass ein kleiner Tippfehler alle Websites vom Netz nimmt.

    Für einen neuen VPS mit mehreren kleinen Flask-Projekten ist Nginx oder Caddy meist der pragmatische Start. Apache bleibt eine gute Wahl, wenn konkrete Module oder vorhandene Regeln benötigt werden. Entscheidend sind Wartbarkeit, Fehlersuche und die Frage, wie oft sich die Umgebung künftig verändert.

    HTTPS für mehrere Domains mit Let’s Encrypt einrichten

    Für mehrere Domains genügt meist ein Zertifikat pro Domain oder ein gemeinsames Zertifikat mit mehreren Namen. Der Reverse Proxy wählt anhand des TLS-Namens das passende Zertifikat aus. Diese Funktion heißt SNI und ermöglicht viele HTTPS-Websites auf derselben IP-Adresse.

    Vor der Ausstellung müssen die gewünschten Hostnamen öffentlich auf den VPS zeigen. Der häufigste Weg ist die HTTP-01-Prüfung. Dabei ruft die Zertifizierungsstelle eine spezielle Datei über Port 80 ab. Dieser Port muss erreichbar bleiben, auch wenn Besucher später automatisch auf HTTPS umgeleitet werden.

    Alternativ eignet sich die DNS-01-Prüfung. Sie bestätigt die Domain über einen speziellen TXT-Eintrag. Das ist besonders hilfreich für Wildcard-Zertifikate wie *.example.de oder wenn Port 80 nicht öffentlich zugänglich sein soll. Der DNS-Zugang sollte dabei stark eingeschränkt werden. Ein vollständiger API-Schlüssel für die ganze DNS-Zone ist unnötig riskant.

    Ein typischer Ablauf sieht so aus:

    • Alle benötigten Namen und Zertifikatsvarianten festlegen.
    • Erreichbarkeit der Validierungswege prüfen.
    • Zertifikat über einen ACME-Client anfordern.
    • Das Zertifikat dem passenden HTTPS-Eintrag zuweisen.
    • Die automatische Verlängerung testen.

    Die Zertifikate von Let’s Encrypt sind 90 Tage gültig. Das ist kein Problem, solange die Erneuerung automatisiert läuft. Ein täglicher Prüfauftrag kann rechtzeitig verlängern; bei Erfolg wird die Zugangsschicht anschließend neu geladen. Entscheidend ist ein echter Probelauf der Verlängerung.

    Die privaten Schlüssel müssen besonders geschützt werden. Sie gehören nicht in öffentliche Projektverzeichnisse, Git-Repositories oder frei lesbare Backup-Ordner. Geeignete Dateirechte und ein begrenzter Zugriff des Webservers verhindern, dass ein Fehler in einer Anwendung gleich den Schlüsselbestand aller Domains offenlegt.

    Für jede Domain sollten mindestens diese HTTPS-Eigenschaften geprüft werden:

    • Gültiges Zertifikat mit passendem Namen
    • Keine abgelaufene oder falsche Zertifikatskette
    • Weiterleitung von HTTP auf HTTPS
    • Gültige Zertifikate auch für www-Varianten, sofern genutzt
    • Keine gemischten Inhalte durch alte HTTP-URLs
    • Funktionierende Erneuerung nach Änderungen am Proxy

    HSTS kann später den Schutz verstärken, weil Browser künftig nur noch HTTPS verwenden. Setze den Header aber erst, wenn alle relevanten Domains, Subdomains und Weiterleitungen zuverlässig funktionieren. Die Option includeSubDomains kann auch bislang unvorbereitete Subdomains erfassen.

    Bei einer Zertifikatsstörung sollte nicht unbemerkt ein falsches Zertifikat für eine andere Website ausgeliefert werden. Prüfe deshalb jede Domain separat, sowohl im Browser als auch mit einem TLS-Testwerkzeug. Besonders wichtig sind Zertifikatsname, Ablaufdatum, Kette und das Verhalten bei einer unbekannten Subdomain.

    ACME-Clients können Zertifikate für viele Domains bündeln. Ein gemeinsames Zertifikat vereinfacht die Verwaltung, verbindet die Namen aber stärker miteinander: Wird es gesperrt oder die Erneuerung blockiert, betrifft das mehrere Websites. Getrennte Zertifikate begrenzen diesen Einfluss. Für unabhängige Projekte ist diese Trennung oft die robustere Variante.

    Aktuelle Hinweise zu ACME-Validierungen und Zertifikatsrichtlinien veröffentlicht die offizielle Dokumentation von Let’s Encrypt. Sie sollte vor Änderungen an Challenge-Verfahren oder Automatisierung geprüft werden.

    Anwendungen mit systemd oder Supervisor überwachen und neu starten

    systemd ist auf den meisten Linux-VPS bereits vorhanden und eignet sich als zentrale Prozessverwaltung. Für jede Flask-Anwendung wird eine eigene Unit angelegt. Sie kann den Prozess beim Systemstart starten, nach einem Absturz erneut ausführen und den Dienststatus sichtbar machen.

    Wichtig ist die Wahl der Neustartregel. Restart=on-failure reagiert auf unerwartete Abbrüche, lässt einen absichtlichen Stopp aber bestehen. Bei wiederholten Abstürzen sollte eine Verzögerung hinzukommen. Sonst entsteht eine enge Neustartschleife, die CPU verbraucht und die Ursache im Log verschleiert.

    Ein eigener Dienstbenutzer begrenzt die Folgen eines Fehlers. Der Prozess erhält nur die Rechte, die er für sein Projekt braucht. Nutzt eine Anwendung Uploads oder erzeugt temporäre Dateien, sollten diese Pfade ausdrücklich freigegeben sein. Der Quellcode selbst muss nicht allgemein beschreibbar sein.

    Supervisor ist eine Alternative, wenn bereits mehrere Anwendungen damit verwaltet werden oder eine einfache, projektnahe Oberfläche gewünscht ist. Es überwacht Prozesse, führt sie als festgelegter Benutzer aus und kann bei einem Abbruch neu starten. systemd ist jedoch enger in das Betriebssystem eingebunden und benötigt auf modernen Distributionen meist keine zusätzliche Software.

    Die Überwachung sollte nicht beim Prozessstatus enden. Ein laufender Worker kann zwar aktiv sein, aber wegen einer fehlerhaften Datenbankverbindung keine brauchbare Antwort liefern. Ergänze deshalb eine leichte Funktionsprüfung, die einen repräsentativen Endpunkt abfragt und einen klaren Fehlerstatus meldet.

    • Prozess läuft und bleibt nach einem Absturz aktiv
    • Gesundheitsprüfung liefert den erwarteten HTTP-Status
    • Speicherverbrauch bleibt unter dem festgelegten Grenzwert
    • Fehlerhäufigkeit und Antwortzeit werden beobachtet
    • Protokolle werden begrenzt, rotiert und nicht endlos gespeichert

    Logrotation ist bei mehreren Anwendungen besonders wichtig. Ein einzelnes Debug-Log kann sonst den Speicher des VPS füllen und dadurch andere Dienste beeinträchtigen. Bewahre nur so viele Dateien und Tage auf, wie für Fehlersuche und betriebliche Anforderungen nötig sind. Zugangsdaten, Sitzungstokens und personenbezogene Inhalte gehören nicht ungeschützt in Logzeilen.

    Nach einem Neustart des Servers müssen alle benötigten Dienste in der richtigen Reihenfolge verfügbar werden. Anwendungen, die eine Datenbank, einen Cache oder einen lokalen Dateidienst benötigen, sollten diese Abhängigkeiten ausdrücklich angeben. Ein bloßes Starten beim Bootvorgang ist keine verlässliche Reihenfolge.

    Teste das Verhalten absichtlich: Beende einen Worker kontrolliert, simuliere einen fehlerhaften Start und starte den VPS neu. Prüfe danach jede Anwendung einzeln. Ein Überwachungssystem, das nur grüne Symbole zeigt, aber keine Benachrichtigung bei Ausfällen sendet, ist letztlich ein hübsches Armaturenbrett ohne Warnleuchte.

    Für systemd bietet die offizielle Dokumentation zu systemd.service die verbindlichen Details zu Start-, Abhängigkeit- und Neustartregeln. Die Supervisor-Dokumentation beschreibt die entsprechenden Prozessoptionen für diese Alternative.

    VPS-Ressourcen für mehrere Flask-Anwendungen planen

    Bei mehreren Flask-Anwendungen zählt nicht nur die Zahl der vCPUs. Entscheidend ist, wie viel Arbeit gleichzeitig anfällt, wie speicherhungrig die Prozesse sind und ob Anfragen lange offen bleiben. Eine kleine Website mit wenigen Besuchern braucht deutlich weniger Reserven als mehrere APIs mit Dateiimporten, Bildverarbeitung oder regelmäßigen Hintergrundaufgaben.

    Plane zuerst den Grundbedarf des Systems. Betriebssystem, Zugangsschicht, Protokollierung, Sicherheitswerkzeuge und Datenbank benötigen bereits einen festen Anteil. Danach kommen pro Anwendung die Laufzeit, ihre Worker, Bibliotheken und der Cache hinzu. Eine Python-Anwendung kann im Leerlauf wenig CPU verbrauchen, belegt aber je nach Abhängigkeiten und Workerzahl mehrere hundert Megabyte Arbeitsspeicher.

    Als grobe Startgröße sind für zwei kleine Flask-Projekte oft 2 vCPUs und 2 bis 4 GB RAM brauchbar. Bei datenbankintensiven Anwendungen, mehreren Worker-Prozessen oder wachsendem Besucheraufkommen sind 4 vCPUs und 8 GB RAM deutlich entspannter. Diese Werte sind keine Garantie, sondern ein Startpunkt; reale Messwerte schlagen jede Faustformel.

    Der wichtigste Engpass ist häufig der Arbeitsspeicher. Jeder zusätzliche Worker lädt Teile des Python-Projekts und seiner Bibliotheken erneut. Bei zu wenig RAM beginnt das System zu swappen. Webseiten werden dann oft sprunghaft träge. Reserviere daher mindestens 20 bis 30 Prozent Speicher für Spitzenlast und Systemaufgaben.

    Ein Swap-Bereich kann kurze Speicherpeaks abfedern, ersetzt aber keinen passenden RAM. Auf einem kleinen VPS sind etwa 1 bis 2 GB Swap als Notpuffer sinnvoll. Dauerhafte Auslagerung belastet die virtuelle Festplatte stark. Beobachte deshalb, ob Swap nur gelegentlich genutzt wird oder bereits zum Normalbetrieb gehört.

    Auch die CPU-Auslegung braucht einen Blick auf das Anfrageprofil:

    • Viele kurze Anfragen: mehrere Worker können den Durchsatz erhöhen.
    • Lange Datenbankabfragen: die Datenbank und ihre Verbindungen werden zum Engpass.
    • Bild- oder PDF-Verarbeitung: CPU-Last und Speicherbedarf steigen deutlich.
    • Streaming oder lange Verbindungen: Worker bleiben länger gebunden.
    • Regelmäßige Jobs: zusätzliche Last entsteht auch außerhalb der Besucherzeiten.

    Speicherplatz sollte nicht nur für Quellcode kalkuliert werden. Datenbanken, Uploads, Backups, temporäre Dateien und Systemprotokolle wachsen weiter. Eine 40-GB-Festplatte kann für kleine Websites genügen, wird aber bei vielen Medien schnell knapp. Plane einen freien Puffer von mindestens 20 Prozent ein und überwache die Belegung.

    Die Datenbank verdient eine eigene Ressourcenrechnung. Viele kleine Anwendungen profitieren von getrennten Datenbankkonten, aber jede Verbindung verbraucht Ressourcen. Begrenze den Verbindungspool pro Projekt und addiere die Höchstwerte aller Anwendungen. Sonst erreicht der Datenbankserver sein Limit, obwohl CPU und RAM noch Luft haben.

    Miss die Last unter realistischen Bedingungen. Ein kurzer Belastungstest sollte typische Seiten, API-Endpunkte, Datenbankzugriffe und Uploads abbilden. Beobachte dabei Antwortzeit, CPU-Auslastung, RAM, Swap, I/O-Wartezeit und Fehlerraten. Ein VPS, der im Leerlauf glänzt, kann unter zehn parallelen Importen plötzlich ins Schwitzen kommen.

    Plane Wachstum in Stufen. Beginne mit einer kleinen Reserve, definiere aber klare Auslöser für ein Upgrade: anhaltend über 70 bis 80 Prozent RAM-Nutzung, steigende I/O-Wartezeit, häufige Timeouts oder dauerhaft hohe CPU-Last. Vertikales Skalieren ist zunächst meist einfacher als eine Aufteilung auf mehrere Server. Bei kritischen Anwendungen sollte der gemeinsame Ressourcenpool jedoch nicht zum gemeinsamen Risiko werden.

    Firewall, SSH-Zugang und Sicherheitsupdates absichern

    Ein VPS mit mehreren Webanwendungen braucht eine bewusst kleine Angriffsfläche. Öffentliche Dienste sollten auf das Nötigste beschränkt bleiben. In der Regel gehören nur die Webports 80 und 443 sowie ein abgesicherter SSH-Zugang dazu. Interne Anwendungsports und Datenbankdienste bleiben für das Internet gesperrt.

    Richte die Firewall nach dem Prinzip der kleinsten Freigabe ein: Erlaube nur bekannte Ports, blockiere den übrigen eingehenden Verkehr und lasse notwendige ausgehende Verbindungen zu. Eine zusätzliche Begrenzung nach Quell-IP ist für SSH sinnvoll, sofern du über eine feste Büro- oder VPN-Adresse verfügst. Prüfe die Regeln immer in einer zweiten Sitzung, damit du dich nicht selbst aussperrst.

    Der SSH-Dienst sollte nicht mit dem direkten Administratorkonto und möglichst nicht mit einem Passwort erreichbar sein. Nutze einen persönlichen Benutzer mit SSH-Schlüssel, aktiviere den privilegierten Zugriff nur über sudo und deaktiviere die Anmeldung per Passwort erst, nachdem der Schlüsselzugang nachweislich funktioniert. Ein anderer SSH-Port kann automatisierte Scans reduzieren, ersetzt aber keine echte Zugriffskontrolle.

    Für mehrere Betreiber sind individuelle Schlüssel besser als ein gemeinsam verwendeter Zugang. Wird eine Person entfernt, kann ihr Schlüssel gezielt aus der Kontokonfiguration gelöscht werden. Private Schlüssel gehören nur auf vertrauenswürdige Geräte und sollten zusätzlich mit einer Passphrase geschützt sein. Ein zentraler Notfallzugang des VPS-Anbieters muss trotzdem geprüft werden, bevor du dich auf die Absicherung verlässt.

    Installiere Sicherheitsaktualisierungen regelmäßig und trenne dabei Betriebssystem, Python-Abhängigkeiten und Webserver. Automatische Aktualisierungen können kritische Korrekturen schnell einspielen, sollten aber durch einen kontrollierten Neustart und eine Funktionsprüfung ergänzt werden. Bei Python-Projekten müssen lockere Versionsvorgaben vermieden werden; verwende reproduzierbare Abhängigkeiten und aktualisiere sie in einer Testumgebung.

    • Veraltete Systempakete regelmäßig ermitteln
    • Sicherheitsupdates zeitnah einspielen
    • Python-Abhängigkeiten gezielt prüfen und aktualisieren
    • Nach Änderungen Anmeldung, Webzugriff und Datenbankverbindungen testen
    • Für kritische Pakete einen Rückweg bei Problemen vorbereiten

    Beschränke Dateirechte konsequent. Quellcode, Konfigurationsdateien und geheime Schlüssel dürfen nicht für alle lokalen Benutzer lesbar sein. Besonders gefährlich sind versehentlich veröffentlichte Dateien wie .env, Sicherungskopien oder Versionskontrollverzeichnisse. Der Webserver sollte niemals aus einem Projektverzeichnis beliebige Dateien anbieten können.

    Ein Intrusion-Prevention-Dienst wie Fail2ban kann wiederholte fehlgeschlagene SSH-Anmeldungen zeitweise sperren. Er ist eine Ergänzung, kein Ersatz für Schlüssel, Firewall und Updates. Prüfe außerdem Serverzeitzone und Uhrsynchronisierung. Falsche Zeitstempel erschweren die Auswertung von Sicherheitsereignissen erheblich.

    Kontrolliere die Absicherung von außen. Ein Portscan sollte nur die vorgesehenen Dienste zeigen. Teste danach bewusst, ob interne Ports, Datenbanken, Verwaltungsoberflächen und Debug-Endpunkte nicht erreichbar sind. Bei Flask darf der Debug-Modus auf einem öffentlichen System niemals aktiviert sein.

    Dokumentiere Änderungen an Firewall, SSH und Paketquellen. Bei einem Notfall zählt jede Minute. Sicherheitsupdates schützen nicht nur einzelne Anwendungen: Auf einem gemeinsamen VPS reduzieren sie das Risiko, dass ein kompromittierter Dienst als Sprungbrett zu den übrigen Projekten dient.

    Backups, Protokolle und Ausfälle zuverlässig verwalten

    Ein VPS bündelt mehrere Anwendungen an einem gemeinsamen Ausfallpunkt. Ein defektes Laufwerk, ein fehlerhaftes Update oder ein versehentlich gelöschtes Verzeichnis kann daher alle Domains betreffen. Backups müssen nicht nur vorhanden sein, sondern eine vollständige Wiederherstellung jeder einzelnen Anwendung ermöglichen.

    Lege fest, welche Daten gesichert werden: Quellcode, Abhängigkeiten, Konfigurationsdateien, Datenbanken, Uploads, Zertifikatsschlüssel und relevante Systemdefinitionen. Geheimnisse sollten verschlüsselt abgelegt werden. Eine Kopie des Quellcodes allein reicht nicht, wenn die eigentlichen Kundendaten in einer Datenbank oder in Upload-Verzeichnissen liegen.

    Nutze mindestens drei Sicherungsebenen:

    • Lokale Sicherung: schnelle Wiederherstellung einzelner Dateien
    • Externe Sicherung: Schutz bei Defekt oder Verlust des VPS
    • Versionierte Sicherung: Rückkehr zu einem früheren, noch fehlerfreien Stand

    Ein tägliches Backup kann für viele kleine Projekte genügen. Datenbanken mit häufigen Änderungen benötigen eventuell kürzere Intervalle oder Transaktionsprotokolle. Bewahre mehrere Generationen auf, statt jede ältere Sicherung sofort zu überschreiben. Sonst wird ein Fehler, der erst nach Tagen auffällt, dauerhaft mitgesichert.

    Teste die Rücksicherung regelmäßig auf einer getrennten Umgebung. Prüfe dabei nicht nur, ob eine Datei kopiert wurde. Eine brauchbare Übung startet die Anwendung, stellt die Datenbank wieder her, bindet Uploads ein und ruft jede Domain auf. Messe außerdem die Wiederherstellungszeit. Im Ernstfall zählt: Wie viele Stunden Ausfall sind akzeptabel und wie viele Daten dürfen maximal fehlen?

    Protokolle helfen, Fehler zeitlich einzugrenzen. Trenne Zugriffs-, Anwendungs- und Systemmeldungen. Jede Flask-Anwendung sollte einen eindeutigen Namen im Log tragen. So lässt sich erkennen, ob ein Problem aus dem Code, der Datenbank, dem Betriebssystem oder der Zugangsschicht stammt. Datenschutzrechtlich sensible Inhalte und vollständige Zugangstokens gehören nicht in die Protokolle.

    Definiere eine Aufbewahrung, die zur Nutzung passt. Kurze Rotationszyklen verhindern volle Datenträger, während komprimierte Archive eine spätere Analyse ermöglichen. Überwache freien Speicher und Backup-Erfolg getrennt. Ein Auftrag, der ohne Fehlermeldung endet, garantiert nicht, dass das Ziel erreichbar war oder die Datei vollständig geschrieben wurde.

    Für einen Ausfall sollte eine knappe Notfallanleitung bereitliegen:

    • Betroffene Domain und Zeitpunkt feststellen
    • Erreichbarkeit des VPS und der einzelnen Dienste prüfen
    • Letzte erfolgreiche Sicherung identifizieren
    • Entscheiden: Reparatur, Rollback oder vollständige Wiederherstellung
    • DNS, Zertifikate, Datenbank und Uploads gemeinsam kontrollieren
    • Ursache und Maßnahme nach dem Vorfall dokumentieren

    Ein Rollback muss gezielt erfolgen. Wird nur der Quellcode zurückgesetzt, können Datenbankschema und Anwendungsversion auseinanderlaufen. Erstelle deshalb vor größeren Releases ein konsistentes Paket aus Code, Migrationen und Daten. Bei mehreren unabhängigen Projekten darf die Wiederherstellung einer App nicht versehentlich Dateien oder Daten einer anderen überschreiben.

    Überlege auch, wie du eine einzelne Domain vorübergehend aus dem Verkehr ziehst. Eine Wartungsseite oder gezielte Deaktivierung kann den übrigen Anwendungen ihren Betrieb lassen. Bei einem vollständigen VPS-Ausfall hilft sie allerdings nicht. Dann brauchst du entweder einen vorbereiteten Ersatzserver oder eine externe Notfallseite, die nicht vom betroffenen System abhängt.

    Eine belastbare Strategie verbindet Datensicherung, prüfbare Protokolle und einen geübten Wiederanlauf. Erst dieser Dreiklang macht das Bündeln mehrerer Flask-Anwendungen auf einem VPS betriebssicher.

    PythonAnywhere mit einem VPS vergleichen

    PythonAnywhere und ein VPS lösen dasselbe Grundproblem auf unterschiedliche Weise. Bei PythonAnywhere wird ein großer Teil der Betriebsarbeit abgenommen. Ein VPS gibt dir dagegen die volle Kontrolle über Server, Laufzeiten und die Zahl der Flask-Anwendungen. Für mehrere Domains ist deshalb weniger die IP-Adresse entscheidend als der gewünschte Grad an Eigenverwaltung.

    PythonAnywhere eignet sich besonders, wenn eine oder wenige Python-Anwendungen schnell online sein sollen. Deployment, Python-Umgebung und Teile der Webserver-Konfiguration sind stark vereinfacht. Das senkt die Einstiegshürde. Gleichzeitig hängen Funktionen wie zusätzliche Webanwendungen, Ressourcen und Betriebsoptionen vom gewählten Tarif ab. Vor einem Wechsel solltest du die aktuellen Grenzen und Preise direkt beim Anbieter prüfen.

    Ein VPS stellt dir dagegen eine eigene virtuelle Maschine bereit. Du kannst Projekte voneinander trennen, eigene Pakete installieren und zusätzliche Dienste wie Datenbanken, Caches oder Aufgabenplaner betreiben. Auch ungewöhnliche Anforderungen sind möglich. Der Preis dafür ist Verantwortung: Du bist für Betriebssystem, Konfiguration, Sicherheitsprozesse, Fehleranalyse und Kapazitätsplanung zuständig.

    • PythonAnywhere: weniger Administration, schneller Start, stärker an Plattformregeln gebunden
    • VPS: mehr Kontrolle, flexible Erweiterung, eigener Aufwand für den gesamten Betrieb

    Vergleiche nicht nur den monatlichen Grundpreis. Bei einem VPS können zusätzliche Kosten für verwaltete Backups, externe Überwachung, Speicher, Traffic oder eine Datenbank entstehen. Bei PythonAnywhere kann ein höherer Tarif günstiger sein als mehrere Stunden monatlicher Wartung. Rechne daher auch deine Arbeitszeit ein. Ein VPS ist nur dann „billiger“, wenn die gewonnene Freiheit den Verwaltungsaufwand rechtfertigt.

    Für den Umzug einer bestehenden Anwendung sind außerdem Plattformunterschiede relevant. Prüfe Python-Version, unterstützte Systembibliotheken, Dateipfade, Umgebungsvariablen, Datenbankzugriff und Aufgaben, die bisher über die Plattform liefen. Eine Anwendung kann technisch starten und trotzdem an fehlenden Cronjobs, Schreibrechten oder abweichenden Netzwerkregeln scheitern.

    Ein stufenweiser Wechsel senkt das Risiko. Lasse die bisherige Website zunächst unverändert online, richte die neue Umgebung parallel ein und teste eine zusätzliche Subdomain. Erst wenn Datenübernahme, Formulare, Hintergrundaufgaben und Fehlerseiten funktionieren, wird die Hauptdomain umgestellt. Plane eine kurze Rückkehrmöglichkeit ein, falls beim DNS-Wechsel oder bei der Datenmigration etwas klemmt.

    Die Wahl lässt sich grob so treffen:

    • Wähle PythonAnywhere, wenn einfache Bereitstellung und geringe Betriebsarbeit Vorrang haben.
    • Wähle einen VPS, wenn mehrere Projekte, eigene Systemdienste oder besondere Softwareversionen benötigt werden.
    • Bleibe zunächst bei der Plattform, wenn kein belastbarer Plan für Updates, Wiederherstellung und Überwachung vorhanden ist.
    • Prüfe ein Managed-VPS-Angebot, wenn du mehr Freiheit möchtest, aber nicht jede Systemaufgabe selbst übernehmen willst.

    Für das beschriebene Szenario ist ein VPS besonders interessant, sobald mehrere Flask-Anwendungen unabhängig voneinander wachsen oder zusätzliche Dienste benötigen. PythonAnywhere bleibt attraktiv, wenn Bequemlichkeit und ein klar begrenzter Plattformumfang wichtiger sind. Die richtige Entscheidung entsteht aus einer Vollkostenrechnung, einer realistischen Zeitplanung und einem getesteten Migrationsplan, nicht aus dem Vergleich einzelner Tarifzahlen.

    Für verbindliche Angaben zu Limits, Preisen und unterstützten Funktionen solltest du die aktuellen Dokumentationen von PythonAnywhere und des jeweiligen VPS-Anbieters heranziehen. Diese Bedingungen können sich ändern und sind im August 2026 nicht pauschal für alle Tarife gleich.

    Fazit: Domains bündeln, Anwendungen trennen und den VPS sicher betreiben

    Ein VPS ist für mehrere Flask-Anwendungen mit eigenen Domains eine tragfähige Lösung, solange die gemeinsame technische Basis bewusst geplant wird. Die eine öffentliche IP-Adresse reicht aus. Sichtbare Domains trennen die Angebote nach außen, während getrennte Projekte, Konten und Dienste die interne Ordnung sichern.

    Der wichtigste praktische Schritt ist eine feste Betriebsroutine. Neue Anwendungen sollten immer nach demselben Muster hinzukommen: eigenes Projektverzeichnis, eigene Konfiguration, eigener Dienst, eigene Domainregeln und ein dokumentierter Test. Das macht spätere Erweiterungen berechenbar und verhindert, dass eine spontane Änderung an einer Website den gesamten Server ins Wanken bringt.

    Behandle den VPS als gemeinsame Plattform mit klaren Grenzen. Anwendungen mit sehr unterschiedlichem Risiko oder stark schwankender Last gehören nicht automatisch auf denselben Rechner. Eine Trennung auf mehrere virtuelle Maschinen kann sinnvoll werden, wenn Datenschutz, Verfügbarkeit oder unabhängige Wartungsfenster wichtiger sind als die zentrale Verwaltung.

    Für die laufende Qualitätssicherung helfen messbare Ziele: maximale Antwortzeit, zulässige Ausfallzeit, verfügbare Speichermenge und Zeit bis zur Wiederherstellung. Ohne solche Werte bleibt „stabil“ eine Bauchentscheidung. Kleine regelmäßige Prüfungen sind wirkungsvoller als eine aufwendige Kontrolle, die niemand dauerhaft pflegt.

    • Jede Domain und jedes Projekt eindeutig dokumentieren
    • Änderungen zunächst isoliert prüfen
    • Abhängigkeiten zwischen Anwendungen sichtbar machen
    • Auslastungs- und Verfügbarkeitsziele schriftlich festlegen
    • Bei wachsendem Risiko die gemeinsame Plattform aufteilen

    Wer den Server selbst betreibt, sollte Zuständigkeiten und Notfallkontakte festhalten. Dazu gehören Zugangsdatenverwaltung, Wartungsfenster, Wiederanlaufreihenfolge und eine Entscheidung, wer bei einem Ausfall handeln darf. Diese organisatorische Seite wirkt unspektakulär, entscheidet aber oft darüber, ob ein Problem in Minuten oder erst am nächsten Morgen gelöst wird.

    Die Architektur passt besonders zu kleinen bis mittleren Projekten, Entwicklungsportalen und mehreren unabhängigen Webauftritten. Sie ist kein Freibrief für unbegrenztes Wachstum. Steigen Anforderungen an Verfügbarkeit, Isolation oder Compliance, sollte die Struktur mitwachsen, etwa durch getrennte Datenbanken, Container oder vollständig separierte Systeme.

    Unterm Strich ist das Modell klar: Eine IP-Adresse bündelt den Zugang, die Domain bestimmt das Ziel und die interne Organisation hält die Anwendungen auseinander. Wer diese Ebenen sauber dokumentiert und regelmäßig prüft, erhält eine flexible Plattform statt eines schwer durchschaubaren Serverknäuels.


    FAQ zum Hosting mehrerer Domains auf einem VPS

    Kann ich mehrere Domains mit nur einer öffentlichen IP-Adresse auf einem VPS betreiben?

    Ja. Alle Domains können per DNS auf dieselbe öffentliche IP-Adresse zeigen. Ein Reverse Proxy wie Nginx, Apache oder Caddy erkennt den angeforderten Domainnamen und leitet die Anfrage an die jeweils passende Anwendung oder Website weiter.

    Wie werden mehrere Flask-Anwendungen auf einem VPS voneinander getrennt?

    Jede Flask-Anwendung sollte einen eigenen Dienst, ein eigenes Projektverzeichnis, eine eigene virtuelle Python-Umgebung und möglichst einen eigenen Linux-Benutzer erhalten. Intern kann jede Anwendung auf einem separaten Port oder Unix-Socket laufen, während der Reverse Proxy die Domains gezielt zuordnet.

    Warum sollte Flask nicht direkt mit dem Entwicklungsserver betrieben werden?

    Der Flask-Entwicklungsserver ist nicht für den produktiven Betrieb ausgelegt. Stattdessen sollte die Anwendung über einen WSGI-Server wie Gunicorn oder uWSGI ausgeführt werden. Ein Reverse Proxy übernimmt zusätzlich TLS, öffentliche Webports, Weiterleitungen und die Verteilung der Anfragen.

    Wie richte ich HTTPS für mehrere Domains auf demselben VPS ein?

    Für jede Domain müssen die DNS-Einträge auf den VPS zeigen. Anschließend können mit Let’s Encrypt und einem ACME-Client Zertifikate ausgestellt werden. Der Reverse Proxy ordnet anhand des Domainnamens das passende Zertifikat zu und leitet HTTP-Anfragen üblicherweise auf HTTPS um.

    Welche Sicherheits- und Wartungsaufgaben fallen beim VPS-Betrieb an?

    Der Betreiber ist selbst für Sicherheitsupdates, Firewall-Regeln, abgesicherten SSH-Zugang, Backups, Logrotation und die Überwachung der Dienste verantwortlich. Mit systemd oder Supervisor können Anwendungen automatisch gestartet und nach Abstürzen neu gestartet werden. Regelmäßige Wiederherstellungstests stellen sicher, dass Backups im Notfall tatsächlich funktionieren.

    Hinweis zum Einsatz von Künstlicher Intelligenz auf dieser Webseite

    Ihre Meinung zu diesem Artikel

    Bitte geben Sie eine gültige E-Mail-Adresse ein.
    Bitte geben Sie einen Kommentar ein.
    Ich finde den Artikel insgesamt sehr praxisnah, gerade weil nicht bei der üblichen Aussage „ein VPS und mehrere Domains geht problemlos“ aufgehört wird. Die Trennung zwischen DNS, Reverse Proxy und den internen Flask-Diensten wird verständlich erklärt. Viele machen am Anfang den Fehler, die Apps einfach auf 0.0.0.0 laufen zu lassen und dann zu hoffen, dass die Firewall schon alles richtet. Dass hier ausdrücklich 127.0.0.1 beziehungsweise private Netzwerke empfohlen werden, ist deshalb ein wichtiger Punkt.

    Was mir besonders gefällt, ist der Hinweis auf die gemeinsamen Risiken. Mehrere kleine Projekte auf einem VPS zu bündeln ist natürlich bequem und meistens auch günstiger, aber der Ausfallpunkt bleibt eben gemeinsam. Ich habe selbst schon erlebt, dass ein einziger Prozess mit einem Speicherleck irgendwann den ganzen Server ausgebremst hat. Nach außen sah es erst so aus, als wären plötzlich mehrere Websites gleichzeitig kaputt, obwohl nur eine Anwendung die Ursache war. Ressourcenlimits und getrennte Benutzer sind daher nicht bloß „nice to have“.

    Beim Thema Datenbanken hätte ich mir eventuell noch einen etwas deutlicheren Hinweis auf Migrationen gewünscht. Getrennte Datenbankbenutzer sind wichtig, aber wenn mehrere Anwendungen denselben PostgreSQL- oder MySQL-Dienst nutzen, kann ein fehlerhaftes Update trotzdem die gemeinsame Datenbankinstanz belasten. Auch Connection-Pools werden gerne vergessen. Jede App funktioniert einzeln, und sobald sie gleichzeitig gestartet werden, ist plötzlich das Verbindungslimit erreicht.

    Sehr richtig finde ich auch die Warnung vor dem Entwicklungsserver. Gerade bei Flask gibt es erstaunlich viele Anleitungen, die für den ersten Test gedacht sind, später aber unverändert in Produktion landen. Gunicorn oder uWSGI zusammen mit systemd ist zwar etwas mehr Arbeit, dafür weiß man dann wenigstens, wie der Dienst startet und was nach einem Absturz passiert. Bei den Worker-Zahlen sollte man wirklich nicht blind irgendeine Formel übernehmen. Zwei Worker können völlig reichen, bei einer CPU-intensiven App sind sie aber auch schnell zu wenig.

    Der Abschnitt zu DNS und IPv6 ist ebenfalls wertvoll. Ein alter AAAA-Eintrag wird meiner Erfahrung nach sehr oft übersehen. Dann funktioniert die Domain bei manchen Leuten und bei anderen überhaupt nicht, was die Fehlersuche unnötig schwierig macht. Auch die Unterscheidung zwischen Hauptdomain und www-Subdomain sollte man nicht unterschätzen. Zertifikate, Weiterleitungen und Proxy-Konfiguration müssen schlussendlich alle denselben Namensbestand abbilden.

    Bei Let’s Encrypt würde ich jedem raten, die automatische Verlängerung nicht nur einzurichten, sondern einmal bewusst zu testen. Ein Cronjob, der irgendwann mal angelegt wurde, ist noch kein funktionierendes Backup und auch keine funktionierende Zertifikatsverlängerung. Gerade nach Änderungen an Nginx oder Caddy merkt man sonst erst beim Ablauf, dass der ACME-Client keinen Zugriff mehr auf den Validierungsweg hat. HSTS würde ich ebenfalls erst aktivieren, wenn man wirklich alle Subdomains im Blick hat. Das kann sonst schnell zur selbstgebauten Falle werden.

    Der Vergleich mit PythonAnywhere ist angenehm ausgewogen. Oft werden Plattformen entweder als völlig ungeeignet oder als die einzig vernünftige Lösung dargestellt. In Wirklichkeit hängt es doch davon ab, ob man Serverbetrieb lernen und dauerhaft machen möchte. Ein VPS ist nicht automatisch günstiger, wenn man jeden Sonntag mehrere Stunden mit Updates, Logs und Backups verbringt. Für private Projekte kann das Spaß machen, für ein kleines Unternehmen vielleicht eher nicht.

    Was mir im Fazit noch etwas fehlt, ist der Gedanke an Container. Docker ist sicher auch kein magischer Sicherheitsmantel, aber für mehrere Flask-Projekte kann es helfen, Abhängigkeiten und Deployments sauberer zu trennen. Gleichzeitig bringt es wieder eigene Komplexität mit, weshalb die beschriebene Lösung mit systemd für viele kleine Anwendungen wahrscheinlich sogar übersichtlicher bleibt. Nicht alles muss sofort Kubernetes werden, nur weil mehr als eine Domain auf dem Server liegt.

    Unterm Strich ist das eine gute Anleitung für Leute, die mehrere Flask-Anwendungen auf einem überschaubaren VPS betreiben möchten. Besonders wichtig ist, dass der Artikel nicht nur die Einrichtung beschreibt, sondern auch Wartung, Backups, Überwachung und den möglichen späteren Umzug auf getrennte Systeme anspricht. Genau an diesen Themen scheitern Setups meistens nicht am ersten Tag, sondern nach ein paar Monaten wenn niemand mehr weiß, warum welcher Dienst auf welchem Port läuft.
    Ein Punkt der noch fehlt ist die DNS Propagation beim umzug, manchmal denkt man der Server is kaputt dabei hängt blos noch der alte Eintrag irgentwo im cache fest
    Der Container Gedanke is echt interesant, wobei Docker auch schnell mehr Baustellen macht als es löst. Für kleine Flask Apps sind getrennte User und systemd warscheinlich erstmal übersichtlicher, bevor man sich noch in 20 neue Konfigs verrennt.
    Der artikel ist wirklich voll mit details, aber ein punkt wird meiner meinung nach noch zu wenig beachtet: was passiert eigentlich wenn der DNS anbieter oder der VPS anbieter selber probleme hat. Dann hilft die ganze saubere trennung von nginx und Flask auch nur begrenzt. Besonders wenn man DNSSEC, Nameserver wechsel oder solche sachen macht kann man sich glaub ich sehr schnell selber aussperren, hab ich zumindest schon erlebt bei einer domain die plötzlich garnicht mehr auflösbar war obwohl am server alles lief

    Auch die Sache mit den falschen Domains im Proxy find ich wichtig. Viele testen warscheinlich immer nur die hauptdomain und merken garnicht das eine falsch geschriebene subdomain dann irgendeine andere seite ausliefert. Das ist bei privaten blogs vielleicht nur peinlich, bei kundenprojekten aber schon ziemlich schlecht. Ein neutraler default server klingt unspektakulär, sollte aber echt standard sein.

    Was bei den ganzen Tipps etwas untergeht ist das deployen. Wenn man mehrere apps hat, muss man ja auch irgendwie wissen welche Version gerade läuft. Einfach dateien überschreiben und service neustarten geht am anfang, später wirds schnell unübersichtlich. Da wären releases mit symlink oder wenigstens git tags hilfreich, damit man im notfall auf den alten stand zurück kann. Sonst macht man ein update, alles geht kaputt und keiner weiß mehr welche Datei eigentlich geändert wurde.

    Bei Python ist auch die Versionsfrage so eine sache. Eigene virtuelle umgebungen sind gut, aber wenn das system irgendwann Python 3.xx nicht mehr unterstützt oder ein paket nur noch mit einer anderen Version läuft, steht man wieder da. Das merkt man oft erst beim neu aufsetzen, weil die alte Umgebung zwar noch läuft aber nicht reproduzierbar gesichert wurde. Anforderungen einfrieren alleine reicht glaube ich nicht immer, manche Pakete brauchen ja auch systembibliotheken und compiler zeug.

    Und bei Uploads würde ich noch mehr vorsicht walten lassen. Eine Flask app sollte hochgeladene Dateien nicht einfach unter dem webroot speichern, sonst können html oder script dateien eventuell direkt ausgeliefert werden. Selbst wenn Python nichts ausführt, kann man sich mit falschen Content Types und solchen sachen schon ärger einhandeln. Dateinamen sollte man auch nie direkt übernehmen, da gibts bestimmt tausend komische sonderzeichen und pfad tricks.

    Was ich ausserdem vermisse ist ein Hinweis auf externe Abhängigkeiten. Wenn die Anwendung einen Zahlungsanbieter, Maildienst oder eine externe API nutzt, kann die eigene Seite gesund aussehen und trotzdem wichtige funktionen nicht machen. Ein Healthcheck der nur /health aufruft findet das dann nicht. Man sollte vielleicht getrennte checks haben, aber auch nicht bei jedem check gleich eine echte bestellung auslösen sonst wirds teuer und peinlich.

    Und beim Thema Monitoring ist „Benachrichtigung“ eigentlich der entscheidene punkt. Logs anschauen wenn schon jemand merkt das die seite kaputt ist, ist keine überwachung. Für kleine Projekte reicht vielleicht ein externer HTTP check und eine Meldung per Mail, aber die Meldung darf nicht über denselben VPS laufen. Sonst bekommt man vom Ausfall natürlich nix mit. Klingt banal, wird aber bestimmt oft so gemacht.

    Die vielen Domains auf einer IP haben auch noch das problem mit Rate limits und Reputation. Wenn eine Anwendung Spam verschickt oder kompromitiert wurde kann eventuell die IP oder der Mailserver auf einer blacklist landen und dann leiden die anderen projekte mit. Deshalb würde ich Mailversand nicht unbedingt direkt vom VPS machen, sondern über einen extra Anbieter. Das steht nicht direkt im Artikel, gehört aber irgendwie zur gemeinsamen Plattform dazu.

    Insgesamt finde ich die Anleitung trotzdem gut, vorallem weil sie nicht so tut als wäre ein VPS einfach nur ein billiger Knopf für mehr leistung. Der eigentliche aufwand kommt ja erst nach dem einrichten, bei updates, testen und wenn irgendwas nachts ausfällt. Und man sollte sich wirklich aufschreiben was man gemacht hat, auch wenn man denkt man merkt sich das. Nach ein paar monaten ist der Port 5002 dann plötzlich ein mysterium und niemand weiß mehr welche app dahinter steckt.
    Der organisatorische Hinweis zu Zuständigkeiten und Notfallkontakten ist vielleicht unspektakulär, aber genau sowas fehlt im Alltag oft und entscheidet dann, ob ein Ausfall schnell gelöst wird.

    Zusammenfassung des Artikels

    Mehrere Flask-Anwendungen lassen sich über eine gemeinsame öffentliche IP betreiben, indem DNS und Reverse Proxy Domains sicher auf getrennte interne Dienste weiterleiten. Eigenständige Umgebungen, Datenbanken und korrekte Proxy- sowie DNS-Konfigurationen verbessern Sicherheit und Zuverlässigkeit.

    Eigene Projekte einfach umsetzen
    Hosten Sie Ihr Projekt einfach selbst auf einem NAS mit passenden Festplatten!
    Jetzt mehr erfahren
    Anzeige

    Nützliche Tipps zum Thema:

    1. Weisen Sie jeder Domain oder Subdomain einen eigenen DNS-Eintrag zur öffentlichen IP-Adresse des VPS zu und prüfen Sie insbesondere widersprüchliche A- und AAAA-Records.
    2. Betreiben Sie jede Flask-Anwendung als separaten Dienst mit eigener virtueller Python-Umgebung, eigenem Benutzer und eigenem internen Port oder Unix-Socket.
    3. Setzen Sie einen Reverse Proxy wie Nginx, Apache oder Caddy ein, der anhand des Hostnamens auf die passende Anwendung weiterleitet. Öffnen Sie die internen Ports nicht öffentlich.
    4. Richten Sie HTTPS für alle tatsächlich verwendeten Namen ein und testen Sie die automatische Let’s-Encrypt-Erneuerung, bevor Sie die Domains produktiv schalten.
    5. Planen Sie den VPS als gemeinsamen Ausfallpunkt: Überwachen Sie Ressourcen und Dienste, sichern Sie Datenbanken sowie Uploads extern und testen Sie die Wiederherstellung regelmäßig.

    Anbieter im Vergleich (Vergleichstabelle)

    Verschiedene Pakete
    Günstigstes Monatspaket 5,99 €
    Serverstandort Deutschland
    Sicherheitsfeatures
    Guter Support
    Verschiedene Pakete
    Günstigstes Monatspaket 1,90 €
    Serverstandort Deutschland
    Sicherheitsfeatures
    Guter Support
    Verschiedene Pakete
    Günstigstes Monatspaket 6,95€
    Serverstandort Deutschland
    Sicherheitsfeatures
    Guter Support
    Verschiedene Pakete
    Günstigstes Monatspaket 4,40 €
    Serverstandort Deutschland Unter Anderem
    Sicherheitsfeatures
    Guter Support
    Verschiedene Pakete
    Günstigstes Monatspaket 4,90 €
    Serverstandort Deutschland Unter Anderem
    Sicherheitsfeatures
    Guter Support
      dogadoKI-generiert ZAP-HostingKI-generiert webgoKI-generiert easynameKI-generiert checkdomainKI-generiert
      dogado ZAP-Hosting webgo easyname checkdomain
    Verschiedene Pakete
    Günstigstes Monatspaket 5,99 € 1,90 € 6,95€ 4,40 € 4,90 €
    Serverstandort Deutschland Unter Anderem Unter Anderem
    Sicherheitsfeatures
    Guter Support
      » ZUR WEBSEITE » ZUR WEBSEITE » ZUR WEBSEITE » ZUR WEBSEITE » ZUR WEBSEITE
    Tabelle horizontal scrollen für mehr Anbieter
    Counter