Privatkunde Geschäftskunde

Docker auf dem vServer installierenDocker Engine und Compose auf einem LXC-Container

Docker läuft auf unseren vServern - auf unseren LXC-Containern ist Nesting aktiviert. Diese Anleitung zeigt die Installation von Docker Engine und Docker Compose, einen ersten Stack aus Reverse Proxy und Anwendung und die Besonderheiten, die du auf einem Container-vServer kennen solltest.

Docker EngineDocker ComposeLXC mit Nesting20 Minuten

Docker auf einem LXC-vServer: was geht und was nicht

Unsere vServer nutzen LXC-Containervirtualisierung. Anders als bei einer vollwertigen KVM-Maschine teilen sich alle Container den Kernel des Host-Systems. Für Docker ist das grundsätzlich kein Hindernis, denn Docker-Container sind selbst nur Prozesse mit abgeschottetem Namensraum - keine echten virtuellen Maschinen.

Damit Docker innerhalb eines LXC-Containers laufen kann, muss allerdings Nesting aktiviert sein. Das ist bei unseren vServern der Fall, du musst dafür nichts beantragen oder umstellen.

Funktioniert

  • Docker Engine und Docker Compose
  • Images aus Docker Hub und eigenen Registries
  • Eigene Images bauen per Dockerfile
  • Volumes, Netzwerke, Port-Mapping
  • Automatischer Neustart per restart-Policy

Funktioniert nicht

  • Verschachtelte Virtualisierung, also eigene VMs per KVM innerhalb des Containers
  • Container, die eigene Kernel-Module nachladen wollen
  • Images, die zwingend einen Windows-Kernel brauchen

Für die allermeisten Anwendungsfälle - Webanwendungen, Datenbanken, Reverse Proxies, Bots, Automatisierung - ist das völlig ausreichend. Mehr zum Unterschied findest du im Ratgeber LXC oder KVM.

Voraussetzungen

Bevor du loslegst, sollte der vServer aktuell und grundlegend abgesichert sein. Falls noch nicht geschehen, arbeite zuerst die ersten Schritte und die SSH-Absicherung ab.

Zur Tarifwahl: Docker selbst verbraucht kaum Ressourcen, die Container darin sehr wohl. Als Anhaltspunkt:

  • Tarif S: ein bis zwei kleine Container, etwa ein Bot oder ein statischer Webserver.
  • Tarif M: ein typischer Stack aus Reverse Proxy, Anwendung und Datenbank.
  • Tarif L oder XL: mehrere Stacks parallel, Entwicklungsumgebungen oder speicherhungrige Anwendungen wie Nextcloud mit Volltextsuche.

Nicht unterschätzen solltest du den Speicherplatz: Docker-Images belegen schnell mehrere Gigabyte, alte Layer bleiben ohne Aufräumen liegen.

Docker Engine installieren

Die Version aus den Standard-Paketquellen von Debian und Ubuntu ist meist veraltet. Nimm deshalb die offiziellen Docker-Paketquellen. Zuerst die Vorbereitung:

sudo apt update
sudo apt install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings

Dann den Signaturschlüssel holen. Für Debian:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Für Ubuntu ersetzt du in beiden Zeilen debian durch ubuntu. Anschließend installierst du:

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Der Test:

sudo docker run --rm hello-world

Erscheint die Begrüßungsmeldung, läuft Docker. Der Parameter --rm räumt den Testcontainer gleich wieder ab.

Docker ohne sudo benutzen

Damit du nicht bei jedem Befehl sudo voranstellen musst, nimmst du deinen Benutzer in die Gruppe docker auf:

sudo usermod -aG docker $USER

Die Änderung greift erst nach einer neuen Anmeldung - melde dich also ab und wieder an. Danach funktioniert docker ps ohne sudo.

Sei dir dabei bewusst: Mitglieder der Gruppe docker können über Container faktisch Root-Rechte auf dem gesamten System erlangen. Nimm nur Benutzer auf, denen du diese Rechte ohnehin geben würdest.

Erster Compose-Stack

Einzelne docker run-Befehle sind für Tests praktisch, im Dauerbetrieb aber unhandlich. Docker Compose beschreibt stattdessen den gesamten Stack in einer Datei, die du versionieren und wiederverwenden kannst.

Lege ein Verzeichnis an und darin eine compose.yaml:

mkdir -p ~/stacks/demo && cd ~/stacks/demo
nano compose.yaml

Ein minimales Beispiel mit Webserver und Datenbank:

services:
  web:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro

  db:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: bitte-hier-ein-langes-zufallspasswort
      MARIADB_DATABASE: demo
    volumes:
      - dbdata:/var/lib/mysql

volumes:
  dbdata:

Starten, Status prüfen, Logs ansehen:

docker compose up -d
docker compose ps
docker compose logs -f web

Zwei Details in dieser Datei sind wichtiger, als sie aussehen. restart: unless-stopped sorgt dafür, dass die Container nach einem Neustart des Servers von allein wieder hochkommen. Und die Portangabe 127.0.0.1:8080:80 bindet den Dienst bewusst nur an localhost - dazu gleich mehr.

Ports, Firewall und ein bekannter Fallstrick

Hier stolpern viele: Docker umgeht deine ufw-Regeln. Schreibst du in der Compose-Datei ports: - "8080:80", trägt Docker eigene iptables-Regeln ein, die vor denen von ufw greifen. Der Dienst ist dann aus dem Internet erreichbar, obwohl ufw status den Port gar nicht listet. Das ist kein Fehler, sondern eine bewusste Design-Entscheidung von Docker - sie überrascht nur regelmäßig.

Der saubere Umgang damit sieht so aus:

  • Nur an localhost binden: Schreibe "127.0.0.1:8080:80" statt "8080:80". Der Container ist dann nur vom Server selbst aus erreichbar.
  • Einen Reverse Proxy davorsetzen: nginx oder Caddy lauschen auf 80 und 443, terminieren TLS und reichen intern an die Container weiter. Nur diese beiden Ports gibst du in der Firewall frei.
  • Interne Kommunikation über das Compose-Netzwerk: Container im selben Stack erreichen sich über ihren Servicenamen, im Beispiel oben also per db als Hostname. Dafür brauchst du überhaupt kein Port-Mapping.

Wie du den Reverse Proxy samt kostenlosem SSL-Zertifikat aufsetzt, steht im Ratgeber Webserver einrichten.

Speicherplatz im Griff behalten

Docker sammelt: alte Images, verwaiste Volumes, Build-Caches. Auf einem vServer mit begrenztem NVMe-Speicher merkst du das schneller als auf einer großen Maschine. Verschaffe dir regelmäßig einen Überblick:

docker system df

Aufräumen lässt sich in zwei Stufen. Die harmlose Variante entfernt gestoppte Container, ungenutzte Netzwerke und verwaiste Images:

docker system prune

Die gründliche Variante nimmt zusätzlich ungenutzte Volumes mit - und damit potenziell Datenbankinhalte:

docker system prune -a --volumes

Den zweiten Befehl nur ausführen, wenn du sicher weißt, welche Volumes gerade nicht in Benutzung sind. Ein Backup vorher schadet nie.

Updates und Betrieb

Container aktualisierst du, indem du das Image neu ziehst und den Stack neu startest:

cd ~/stacks/demo
docker compose pull
docker compose up -d

Compose ersetzt dabei nur die Container, deren Image sich tatsächlich geändert hat. Daten in benannten Volumes bleiben erhalten.

Zwei Gewohnheiten, die sich im Dauerbetrieb auszahlen: Verwende feste Versions-Tags statt latest, damit ein pull nicht ungewollt einen Major-Sprung mitbringt. Und sichere deine Compose-Dateien zusammen mit den Volume-Inhalten - eine compose.yaml allein bringt dir bei einem Datenverlust wenig.

Häufige Fragen

Ja. Auf unseren vServern ist Nesting aktiviert, dadurch laufen Docker Engine und Docker Compose im Container. Du kannst Images ziehen, eigene Images bauen und mehrere Dienste über eine Compose-Datei parallel betreiben. Was nicht funktioniert, ist verschachtelte Virtualisierung, also das Starten eigener virtueller Maschinen per KVM innerhalb des Containers.

Ein einzelner kleiner Container - etwa ein Discord-Bot oder ein statischer Webserver - läuft bereits auf dem Tarif S. Für einen typischen Stack aus Reverse Proxy, Anwendung und Datenbank ist M die sinnvolle Einstiegsgröße. Wer mehrere Stacks parallel betreibt oder speicherhungrige Anwendungen wie Nextcloud mit Volltextsuche einsetzt, sollte L oder XL wählen. Ein Upgrade ist jederzeit ohne Datenverlust möglich.

Weil Docker eigene iptables-Regeln schreibt, die vor den ufw-Regeln greifen. Das ist bekanntes Docker-Verhalten und kein Fehler in deiner Konfiguration. Die einfachste Lösung: Binde Ports in der Compose-Datei explizit an localhost, also "127.0.0.1:8080:80" statt "8080:80", und stelle einen Reverse Proxy davor, der als einziger Dienst nach außen erreichbar ist.

Docker selbst nur wenige hundert Megabyte, die Images dagegen deutlich mehr. Ein schlankes Alpine-Image liegt bei rund 10 MB, ein vollständiges Anwendungs-Image kann mehrere Gigabyte groß sein. Dazu kommen Build-Caches und verwaiste Layer. Prüfe den Verbrauch regelmäßig mit "docker system df" und räume mit "docker system prune" auf.

Nur, wenn du es festlegst. Setze in der Compose-Datei je Service "restart: unless-stopped" - dann startet Docker die Container nach einem Neustart des vServers automatisch wieder. Ohne diese Angabe bleiben sie gestoppt. Prüfe zusätzlich mit "systemctl is-enabled docker", dass der Docker-Dienst selbst beim Systemstart hochfährt.

Ja, Portainer läuft als normaler Container und funktioniert auf dem vServer. Binde die Weboberfläche aber nicht ungeschützt an eine öffentliche Adresse. Empfehlenswert ist, sie nur an localhost zu binden und über einen SSH-Tunnel oder einen abgesicherten Reverse Proxy zu erreichen.

vServer für deinen Docker-Stack

Ein einzelner kleiner Container läuft bereits auf dem Tarif S. Für einen typischen Stack aus Reverse Proxy, Anwendung und Datenbank ist M die sinnvolle Einstiegsgröße. Alle Tarife mit NVMe-SSD, unlimitiertem Traffic und vollem Root-Zugriff.

vServer-Tarife & Preise ansehen