Docker in Produktion auf einem VPS: Was schiefgeht und wie Sie es beheben

11 Min. Lesezeit·Matthieu·productionsecurityvpsdocker-composedocker|

Docker läuft auf Ihrem Laptop. Auf einem öffentlichen VPS umgeht es Firewalls, füllt Festplatten mit Logs, führt alles als root aus und hat keine Update-Strategie. Hier sind die 8 Probleme, die Sie lösen müssen.

Sie haben Docker auf Ihrem VPS installiert. Sie haben docker compose up ausgeführt. Ihre Anwendung ist online. Fertig, oder?

Nicht ganz. Auf Ihrem Laptop scannt niemand Ihre Ports, Speicherplatz ist reichlich vorhanden, und Sicherheit spielt kaum eine Rolle. Auf einem VPS mit Internetzugang arbeiten die Standardeinstellungen von Docker aktiv gegen Sie.

Diese Seite behandelt die 8 Probleme, auf die Sie stoßen werden, und verlinkt zu einem eigenen Leitfaden für jedes einzelne. Überfliegen Sie sie, finden Sie, was auf Ihren Server zutrifft, folgen Sie dem jeweiligen Leitfaden.

Voraussetzungen

Dieser Leitfaden setzt voraus, dass Sie die Docker-Grundlagen bereits kennen. Falls Sie sich einarbeiten müssen:

  • Docker-Befehle und -Konzepte
  • Multi-Service-Anwendungen mit Compose

Alle Befehle und Ausgaben in diesem Artikel wurden auf Debian 12 und Ubuntu 24.04 mit Docker Engine 29.x und Compose v2 (Version 5.x) getestet.

Was geht kaputt, wenn Sie Docker auf einem öffentlichen VPS betreiben?

Acht Dinge gehen kaputt, wenn Sie Docker von der Entwicklung auf einen öffentlichen VPS verlagern: Ihre Firewall funktioniert nicht mehr, Container laufen als root mit vollem Host-Zugriff, Logs füllen Ihre Festplatte ohne Rotation, Container-Netzwerke kollidieren mit dem Host-Netzwerk, Dienste haben weder Ressourcenlimits noch Health Checks, Volumes haben keine Backup-Strategie, Ports sind ohne TLS exponiert, und Container-Images veralten ohne Update-Plan. Das sind alles Docker-Standardeinstellungen. Jede einzelne wird Ihnen in Produktion Probleme bereiten.

Kurzübersicht vor den detaillierten Leitfäden:

# Problem Diagnosebefehl Risiko
1 Firewall-Umgehung sudo iptables -L DOCKER-USER -n Kritisch
2 Root-Container docker info --format '{{.SecurityOptions}}' Kritisch
3 Festplatte voll durch Logs du -sh /var/lib/docker/containers/*/*-json.log Hoch
4 Netzwerkkonflikte docker network ls Mittel
5 Keine Ressourcenlimits docker stats --no-stream Hoch
6 Keine Volume-Backups docker volume ls Hoch
7 Kein Reverse Proxy / TLS ss -tlnp | grep -E ':80|:443' Kritisch
8 Veraltete Images docker compose images Mittel

Führen Sie diese Befehle jetzt auf Ihrem Server aus. Wenn eine Ausgabe Sie überrascht, lesen Sie den entsprechenden Abschnitt weiter unten.

Umgeht Docker Ihre Firewall?

Ja. Docker manipuliert iptables direkt und fügt Regeln in die Tabellen nat und filter ein, die ausgewertet werden, bevor UFW oder firewalld den Datenverkehr überhaupt sehen. Wenn Sie einen Port mit -p 8080:80 veröffentlichen, ist dieser Port für das gesamte Internet offen, selbst wenn Ihre UFW-Regeln deny incoming sagen.

Prüfen Sie, ob das auf Sie zutrifft:

sudo iptables -L DOCKER-USER -n -v

Wenn die Ausgabe eine leere Chain oder nur eine bedingungslose RETURN-Regel ohne Filterung zeigt, ist jeder veröffentlichte Port weit offen.

Die Ursache: Pakete, die für Docker-Container bestimmt sind, durchlaufen die FORWARD-Chain und die DOCKER-Chain. UFW arbeitet auf der INPUT-Chain. Die beiden treffen sich nie.

Die einfachste sofortige Lösung ist, veröffentlichte Ports nur an 127.0.0.1 zu binden:

ports:
  - "127.0.0.1:8080:80"

Das macht den Port nur vom Host selbst aus erreichbar. Kombinieren Sie es mit einem Reverse Proxy für den externen Datenverkehr.

Für eine vollständige Anleitung zum DOCKER-USER-Chain-Fix, zur UFW-Integration und zur nftables-Konfiguration.

Ist Docker als root auf einem VPS gefährlich?

Standardmäßig läuft der Docker-Daemon als root, und Container laufen als root innerhalb ihrer Namespaces. Wenn ein Angreifer aus einem Container ausbricht, landet er als root auf dem Host. Auf einem öffentlichen VPS ist das ein direkter Weg zur vollständigen Kompromittierung des Servers.

Prüfen Sie Ihre aktuelle Konfiguration:

docker info --format '{{.SecurityOptions}}'

Suchen Sie nach name=rootless in der Ausgabe. Wenn es nicht da ist, läuft Ihr Daemon als root.

Prüfen Sie auch, ob Ihre Container intern als root laufen:

docker ps -q | xargs -I {} docker exec {} id

Wenn Sie bei den meisten Containern uid=0(root) sehen, laufen sie als root innerhalb des Containers. Ein Image, das USER appuser in seinem Dockerfile setzt, zeigt stattdessen eine Nicht-Root-UID an.

Sie haben drei Verteidigungsschichten:

  1. Rootless-Modus führt den gesamten Docker-Daemon unter einem Nicht-Root-Benutzer aus. Selbst ein Container-Ausbruch landet als unprivilegierter Benutzer auf dem Host.
  2. Seccomp-Profile beschränken, welche Syscalls Container verwenden können. Docker liefert ein Standardprofil, das etwa 44 gefährliche Syscalls blockiert, aber Sie können es weiter verschärfen.
  3. AppArmor / SELinux fügt zusätzlich Mandatory Access Control hinzu.

Vollständige Einrichtung für Rootless-Docker, benutzerdefinierte Seccomp-Profile und no-new-privileges.

Warum füllen Docker-Container Ihre Festplatte?

Der Standard-Log-Treiber von Docker ist json-file ohne Größenbeschränkung und ohne Rotation. Jede Zeile, die Ihre Anwendung auf stdout schreibt, wird in /var/lib/docker/containers/<id>/<id>-json.log gespeichert. Eine aktive Webanwendung kann in wenigen Tagen Gigabytes an Logs erzeugen.

Prüfen Sie, wie viel Speicherplatz Logs gerade belegen:

sudo du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -rh | head -5

Auf einem VPS, der seit ein paar Wochen ohne Log-Rotation läuft, könnten Sie eine Ausgabe wie diese sehen:

4.2G    /var/lib/docker/containers/a1b2c3.../a1b2c3...-json.log
1.8G    /var/lib/docker/containers/d4e5f6.../d4e5f6...-json.log
256M    /var/lib/docker/containers/g7h8i9.../g7h8i9...-json.log

Logs sind nicht der einzige Speicherverbraucher. Prüfen Sie die gesamte Docker-Festplattennutzung:

docker system df

Typische Ausgabe auf einem Server mit 5 Diensten:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          12        5         4.2GB     2.8GB (66%)
Containers      8         5         52MB      12MB (23%)
Local Volumes   6         4         1.1GB     245MB (22%)
Build Cache     18        0         890MB     890MB (100%)

Dieser Build-Cache ist zu 100 % rückgewinnbar. Diese 7 ungenutzten Images belegen 2,8 GB. Auf einer 40-GB-VPS-Festplatte summiert sich das schnell.

Die Lösung besteht aus zwei Teilen: Log-Rotation in /etc/docker/daemon.json konfigurieren und regelmäßige Bereinigung ungenutzter Images und des Build-Caches einrichten.

Vollständige Log-Rotation-Konfiguration, Festplattenüberwachung und automatisierte Bereinigung:

Wie funktioniert Docker-Netzwerk auf einem einzelnen VPS?

Docker erstellt sein eigenes Bridge-Netzwerk (172.17.0.0/16 standardmäßig) und verwaltet Container-IPs intern. Auf einem VPS kann das mit Ihrem Host-Netzwerk, Ihren VPN-Subnetzen oder anderen Diensten kollidieren.

Sehen Sie, welche Netzwerke Docker erstellt hat:

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
f6e5d4c3b2a1   host      host      local
9i8h7g6f5e4d   none      null      local

Jedes docker compose up erstellt ein zusätzliches Netzwerk. Nach einigen Projekten haben Sie möglicherweise ein Dutzend Netzwerke mit überlappenden Subnetzen.

Wichtige Entscheidungen für VPS-Netzwerke:

  • Bridge-Modus (Standard): Container erhalten interne IPs, Ports werden über iptables veröffentlicht. Funktioniert für die meisten Setups. Fügt eine NAT-Schicht hinzu.
  • Host-Modus: Container teilen den Netzwerk-Stack des Hosts direkt. Kein NAT-Overhead, aber keine Port-Isolation. Nützlich für performancekritische Dienste.
  • Benutzerdefinierte Bridge-Netzwerke: Container im selben benutzerdefinierten Netzwerk können sich gegenseitig über den Containernamen erreichen. Das erstellt Compose automatisch.

Der wichtige Punkt auf einem VPS: Definieren Sie Ihre Subnetze explizit in docker-compose.yml, anstatt Docker wählen zu lassen. Das vermeidet Konflikte mit den internen Netzwerken Ihres Hosting-Anbieters.

Detaillierter Leitfaden zu Bridge vs. Host, benutzerdefinierten Subnetzen und Inter-Container-DNS:

Was passiert ohne Ressourcenlimits und Health Checks?

Ohne Speicherlimits verbraucht ein einzelner Container mit einem Speicherleck den gesamten verfügbaren RAM, löst den Linux OOM Killer aus und reißt andere Container oder sogar den SSH-Daemon mit. Ohne Health Checks hat Docker keine Möglichkeit zu erkennen, dass ein Container defekt ist. Er bleibt „running", während er Fehler zurückgibt.

Prüfen Sie, ob Ihre Container Limits gesetzt haben:

docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.CPUPerc}}"

Wenn die Spalte MEM % Werte anzeigt, Sie aber nie Limits gesetzt haben, beziehen sich diese Prozentsätze auf den gesamten Host-RAM. Ein Container, der 45 % anzeigt, nutzt 45 % des gesamten VPS-Speichers, und nichts hindert ihn daran, mehr zu nehmen.

Die minimale Produktionskonfiguration in Ihrer docker-compose.yml:

services:
  app:
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    restart: unless-stopped

Die Richtlinie restart: unless-stopped startet abgestürzte Container automatisch neu, respektiert aber manuelle Stopps. Der healthcheck ermöglicht es Docker, fehlerhafte Container zu markieren und sie basierend auf der Wiederholungsanzahl neu zu starten.

Vollständiger Leitfaden zu Compose-Ressourcenlimits, Healthcheck-Patterns und Neustart-Richtlinien:

Wie sichern Sie Docker-Volumes?

Docker-Volumes speichern Daten außerhalb von Containern. Wenn ein Volume gelöscht oder beschädigt wird, sind Ihre Datenbank, hochgeladene Dateien oder Konfiguration weg. Docker hat keinen eingebauten Backup-Mechanismus für Volumes.

Listen Sie Ihre Volumes und deren Größen auf:

docker system df -v | grep -A 100 "Local Volumes space usage"

Oder prüfen Sie einzelne Volume-Mountpoints:

docker volume ls -q | xargs -I {} docker volume inspect {} --format '{{.Name}}: {{.Mountpoint}}'

Die Mountpoints liegen standardmäßig unter /var/lib/docker/volumes/. Sie können sie mit Standard-Linux-Tools sichern, müssen aber den Container zuerst stoppen oder pausieren, um inkonsistente Snapshots zu vermeiden. Bei Datenbanken ist eine Dateisystemkopie einer laufenden Datenbank kein zuverlässiges Backup. Sie brauchen zuerst einen Dump.

Backup-Strategien, Wiederherstellungsverfahren und automatisierte Planung:

Wie exponieren Sie Docker-Dienste mit TLS?

Ports direkt mit -p 443:443 auf jedem Container zu veröffentlichen, skaliert nicht über einen Dienst hinaus. Sie brauchen einen Reverse Proxy, der TLS terminiert, den Datenverkehr zum richtigen Container leitet und die Zertifikatserneuerung übernimmt.

Prüfen Sie, was derzeit auf Ihrem VPS lauscht:

ss -tlnp | grep -E ':80|:443'

Wenn Sie sehen, dass Ihre Anwendungscontainer direkt an Port 80 oder 443 gebunden sind, sind sie ohne Proxy-Schicht exponiert. Das bedeutet, dass jeder Dienst seine eigene Zertifikatsverwaltung braucht, und Sie können nicht mehrere Domains auf einem VPS hosten.

Drei Reverse-Proxy-Optionen dominieren das Docker-Ökosystem:

Proxy Auto-Discovery Automatisches TLS Konfigurationsstil
Traefik Ja (Docker-Labels) Let's Encrypt integriert Labels + YAML
Caddy Über Plugin Standardmäßig automatisch Caddyfile
Nginx Proxy Manager Docker-Socket Let's Encrypt-UI Web-GUI

Traefik ist die häufigste Wahl für Docker-native Setups, weil es Container-Labels liest und Routing-Regeln automatisch generiert. Keine Konfigurationsdateien, die beim Hinzufügen eines Dienstes aktualisiert werden müssen.

Vergleich, Einrichtungsanleitungen und TLS-Konfiguration für jede Option:

Welche Update-Strategie gibt es für Docker-Container auf einem VPS?

Docker-Images aktualisieren sich nicht selbst. Wenn Sie postgres:16 ausführen und ein Sicherheitspatch in postgres:16.4 erscheint, läuft Ihr Container weiter mit dem alten Image, bis Sie es explizit pullen und den Container neu erstellen.

Prüfen Sie, welche Images Ihre Dienste verwenden:

docker compose images

Vergleichen Sie die Image-Digests mit den neuesten verfügbaren Versionen:

docker compose pull --dry-run 2>&1

Wenn ein Image in der Dry-Run-Ausgabe als „pulled" erscheint, ist Ihre laufende Version veraltet.

Die wichtigen Entscheidungen:

  • Image-Tags fixieren: Verwenden Sie nie :latest in Produktion. Nutzen Sie spezifische Versions-Tags wie postgres:16.4 oder sogar SHA-Digests.
  • Geplante Pulls: Führen Sie docker compose pull && docker compose up -d nach Zeitplan aus, testen Sie Updates aber zuerst in einer Staging-Umgebung.
  • Neustarts ohne Ausfallzeit: Verwenden Sie Health Checks und docker compose up -d --no-deps <service>, um einen Dienst nach dem anderen zu aktualisieren.
  • Image-Scanning: Tools wie Trivy scannen Ihre Images vor dem Deployment auf bekannte CVEs.

Update-Strategien, Image-Pinning-Patterns und Deployment ohne Ausfallzeit:

Brauchen Sie Kubernetes, um Docker in Produktion zu betreiben?

Nein. Docker Compose ist ein produktionsreifes Deployment-Tool für Single-Server-Workloads. Kubernetes löst Multi-Node-Orchestrierung, automatische Skalierung und Self-Healing über einen Cluster. Wenn Ihre Anwendung auf einem einzigen VPS läuft, gibt Ihnen Compose alles, was Sie brauchen, ohne den operativen Overhead von Kubernetes.

Wo Compose funktioniert:

  • Ein einzelner VPS mit 3-15 Containern
  • Statische oder vorhersehbare Traffic-Muster
  • Kleines Team ohne dedizierte Plattform-Ingenieure
  • Dienste, die Sekunden Ausfallzeit bei Updates tolerieren

Wo Sie Compose entwachsen:

  • Mehrere Server für Hochverfügbarkeit nötig
  • Auto-Scaling bei Traffic-Spitzen
  • Komplexe Service Meshes mit Hunderten von Microservices
  • Null-Ausfallzeit-Anforderungen mit Blue-Green-Deployments über Nodes hinweg

Der leichtgewichtige Mittelweg ist K3s, ein abgespecktes Kubernetes, das auf einem einzelnen VPS mit etwa 512 MB RAM-Overhead läuft. Aber für die meisten Nebenprojekte, SaaS-MVPs und kleinen Produktionsanwendungen ist Compose das richtige Werkzeug.

Wie viel RAM braucht ein VPS für Docker in Produktion?

Ein VPS, der Docker in Produktion betreibt, benötigt mindestens 4 GB RAM für 3-5 Container. Der Docker-Daemon selbst verbraucht etwa 100-200 MB. Jeder Container fügt seinen eigenen Speicherbedarf hinzu. Ohne gesetzte Speicherlimits kann ein einzelner fehlerhafter Container alles verbrauchen.

VPS-Größe Container Geeignet für
4 GB RAM 3-5 leichtgewichtig Blog, API, Datenbank, Redis
8 GB RAM 5-10 gemischt SaaS-MVP, mehrere Dienste, Monitoring-Stack
16 GB RAM 10-20 Mehrere Projekte, CI-Runner, schwerere Datenbanken
32 GB RAM 20+ KI-Inferenz, große Datenbanken, Build-Server

Speicherplatz ist genauso wichtig wie RAM. Docker-Images, Volumes, Logs und Build-Cache häufen sich an. Planen Sie mindestens 40 GB NVMe-Speicher ein und richten Sie das in beschriebene Monitoring ab dem ersten Tag ein.

CPU ist selten der Engpass für containerisierte Webdienste. 4 vCPUs reichen für die meisten Workloads. Ausnahmen: Videotranskodierung, KI-Inferenz und Build-Server.

Für einen VPS mit NVMe-Speicher, der für Docker-Produktions-Workloads dimensioniert ist, siehe Virtua Cloud VPS-Angebote.

Produktions-Checkliste

Bevor Sie mit Docker auf einem VPS in Produktion gehen, überprüfen Sie jeden Punkt:

  • Firewall-Regeln blockieren alle Docker-veröffentlichten Ports außer über den Reverse Proxy
  • Container laufen wo möglich als Nicht-Root-Benutzer
  • Docker-Daemon läuft im Rootless-Modus oder Container verwenden seccomp + no-new-privileges
  • Log-Rotation ist in /etc/docker/daemon.json konfiguriert
  • docker system prune läuft nach Zeitplan (wöchentlicher Cron)
  • Jeder Dienst hat Speicher- und CPU-Limits in docker-compose.yml
  • Jeder Dienst hat einen Health Check
  • Die Neustart-Richtlinie ist gesetzt (unless-stopped oder on-failure)
  • Volumes mit wichtigen Daten haben automatisierte Backups
  • Ein Reverse Proxy übernimmt TLS-Terminierung und Zertifikatserneuerung
  • Image-Tags sind auf spezifische Versionen fixiert, nicht :latest
  • Sie haben ein getestetes Update-Verfahren zum Pullen neuer Images
  • journalctl -u docker und docker logs <container> funktionieren und Sie wissen, wo Sie nachschauen müssen

Wenn Sie nicht jeden Punkt abhaken können, arbeiten Sie die in den jeweiligen Abschnitten verlinkten Artikel durch.


Copyright 2026 Virtua.Cloud. Alle Rechte vorbehalten. Dieser Inhalt ist ein Originalwerk des Virtua.Cloud-Teams. Vervielfältigung, Wiederveröffentlichung oder Weiterverbreitung ohne schriftliche Genehmigung ist untersagt.

Bereit, es selbst auszuprobieren?

Betreiben Sie Docker produktiv auf einem zuverlässigen VPS.

VPS-Angebote ansehen