Docker und Docker Compose auf Linux installieren (Ubuntu/Debian): die Self-Hosting-Grundlage
Docker und das Compose-Plugin sind die Basis für jedes Self-Hosting-Projekt. Diese Anleitung zeigt die saubere Installation aus dem offiziellen Docker-Repo auf Ubuntu und Debian: GPG-Key, apt-Quelle, docker-ce mit Compose-Plugin, docker-Gruppe und ein erster Compose-Stack als Test.

Wer Dienste wie Nginx Proxy Manager, Vaultwarden, Immich oder Pi-hole selbst hosten will, braucht eine solide Grundlage: Docker. Mit Containern läuft jede Anwendung samt ihrer Abhängigkeiten isoliert, lässt sich in Sekunden starten, aktualisieren oder wieder entfernen, ohne das restliche System zu verschmutzen. Diese Anleitung richtet sich an alle, die einen Linux-Server, eine VM oder einen Homeserver mit Ubuntu oder Debian betreiben und Docker zusammen mit dem Compose-Plugin sauber aus dem offiziellen Docker-Repository installieren wollen. Am Ende läuft ein erster Beispiel-Stack über docker compose und du hast die Basis für jedes weitere Self-Hosting-Projekt.
Was ist Docker und Docker Compose?
Docker (genauer: die Docker Engine) ist eine Container-Laufzeit. Sie packt eine Anwendung mit allen benötigten Bibliotheken in ein portables Image und startet daraus laufende Container. Anders als bei einer vollwertigen virtuellen Maschine teilen sich alle Container den Kernel des Hosts, sind dadurch leichtgewichtig und starten nahezu sofort.
Docker Compose beschreibt einen kompletten Verbund aus mehreren Containern, Netzwerken und Volumes in einer einzigen YAML-Datei. Statt lange docker run-Befehle zu tippen, definierst du den gewünschten Zustand einmal in der compose.yml und steuerst alles mit kurzen Kommandos. Wichtig: Compose v2 ist heute ein Plugin der Docker CLI. Der Befehl lautet deshalb docker compose (mit Leerzeichen) und nicht mehr das alte, separate docker-compose.
Ein zweiter wichtiger Punkt vorab: Wir installieren bewusst nicht das Paket docker.io aus dem Ubuntu-/Debian-Repo. Das ist oft veraltet und bringt das Compose-Plugin nicht in der aktuellen Form mit. Stattdessen nutzen wir das offizielle Repo unter download.docker.com mit den Paketen docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin und docker-compose-plugin.
Voraussetzungen
- Ein Server, eine VM oder ein Homeserver mit Ubuntu LTS (z. B. 22.04 oder 24.04) oder Debian stable (z. B. 12 Bookworm), x86_64 oder ARM64.
- Ein Benutzerkonto mit
sudo-Rechten. - Internetzugang für den Paketdownload.
- Die Pakete
curlundca-certificates(werden im ersten Schritt mit installiert). - Empfehlung: vorher ein vollständiges Systemupdate (
sudo apt update && sudo apt upgrade). - Falls bereits ein altes
docker.iooderdocker-composeinstalliert ist, vorher entfernen, um Konflikte zu vermeiden (siehe Schritt 1).
Schritt 1: Alte Pakete entfernen und System vorbereiten
Damit es keine Kollisionen mit Distributions-Paketen gibt, entfernst du eventuelle Altinstallationen. Der Befehl schadet nicht, wenn nichts davon installiert ist:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove -y $pkg
doneAnschließend bringst du die Paketquellen auf den neuesten Stand und installierst die Helfer für den Schlüssel-Download:
sudo apt-get update
sudo apt-get install -y ca-certificates curlSchritt 2: Offiziellen GPG-Schlüssel von Docker hinterlegen
Der Schlüssel stellt sicher, dass die Pakete tatsächlich von Docker stammen. Lege das Verzeichnis für Schlusselbunde an und lade den Key herunter:
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.ascWichtig für Debian: Ersetze in der URL ubuntu durch debian, also https://download.docker.com/linux/debian/gpg. Der Rest bleibt identisch.
Schritt 3: Docker-Repository als apt-Quelle eintragen
Jetzt fügst du die passende Paketquelle hinzu. Der folgende Befehl liest Architektur und Codename automatisch aus und schreibt die fertige Zeile in die Quelldatei (Variante für Ubuntu):
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get updateFür Debian nutzt du dieselbe Befehlsstruktur, ersetzt aber beide Vorkommen von ubuntu durch debian. Wenn apt-get update ohne Fehler durchläuft, ist das Repo korrekt eingebunden.
Schritt 4: Docker Engine und Compose-Plugin installieren
Nun installierst du die Engine, die CLI, containerd sowie die Plugins für Buildx und Compose in einem Rutsch:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginDer Dienst startet bei der Installation automatisch. Damit Docker auch nach einem Neustart von selbst hochfährt, aktivierst du ihn ausdrücklich:
sudo systemctl enable --now dockerEin erster Funktionstest mit dem offiziellen Testimage:
sudo docker run --rm hello-worldErscheint die Meldung "Hello from Docker!", ziehen Engine und Image-Download sauber. Das Flag --rm räumt den Test-Container danach gleich wieder weg.
Schritt 5: Benutzer in die docker-Gruppe aufnehmen
Bisher musstest du jeden Docker-Befehl mit sudo ausführen. Wenn du deinen Benutzer in die Gruppe docker aufnimmst, geht es ohne. Beachte den Sicherheitsaspekt: Mitglieder der docker-Gruppe haben de facto root-Rechte auf dem Host. Vergib die Mitgliedschaft also nur an vertrauenswürdige Konten.
sudo usermod -aG docker $USERDie Gruppenmitgliedschaft wird erst nach einem neuen Login wirksam. Melde dich also ab und wieder an (bzw. baue die SSH-Sitzung neu auf). Danach prüfst du, ob die Befehle ohne sudo funktionieren:
docker --version
docker compose version
docker run --rm hello-worldBeide Versions-Abfragen müssen eine Ausgabe liefern. Achte darauf, dass docker compose version (mit Leerzeichen) etwas zurückgibt, denn genau diese Schreibweise nutzt du ab jetzt für alle Stacks.
Schritt 6: Erster Stack mit Docker Compose
Zum Abschluss baust du einen kleinen, echten Stack. Als Beispiel dient Uptime Kuma, ein schlankes Self-Hosting-Monitoring mit Weboberfläche. Lege zuerst ein Projektverzeichnis an:
mkdir -p ~/uptime-kuma
cd ~/uptime-kumaErstelle darin die Datei compose.yml mit folgendem Inhalt:
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./data:/app/dataDie wichtigsten Bausteine im Überblick:
- image: Das verwendete Image samt Tag. Der Tag
1bindet die Major-Version 1 und vermeidet ungewollte Sprünge. Für den Produktivbetrieb empfiehlt es sich, auf eine konkrete Version zu pinnen. - restart: unless-stopped: Der Container startet nach einem Reboot automatisch wieder, solange du ihn nicht selbst gestoppt hast.
- ports:
"3001:3001"verbindet Host-Port 3001 mit dem Container-Port 3001 (SchemaHost:Container). - volumes: Der Bind-Mount
./datalegt die Daten im Projektordner ab, sodass sie ein Container-Neubau überlebt.
Jetzt startest du den Stack im Hintergrund:
docker compose up -dSchritt 7: Verifikation im Browser
Prüfe zuerst, ob der Container läuft:
docker compose psIn der Spalte STATUS sollte Up stehen. Öffne anschließend im Browser die Adresse http://SERVER-IP:3001 (auf dem Server selbst http://localhost:3001). Beim ersten Aufruf legst du ein Administrator-Konto an. Klappt das, hast du erfolgreich deinen ersten Compose-Stack ausgerollt. Die Logs lassen sich jederzeit live mitverfolgen:
docker compose logs -fMit Strg + C beendest du die Log-Ansicht, ohne den Container zu stoppen.
Updates und Wartung
Ein Compose-Stack lässt sich in zwei kurzen Befehlen aktualisieren. Du holst die neuen Images und ersetzt die laufenden Container im selben Verzeichnis:
docker compose pull
docker compose up -dCompose erkennt automatisch, welche Container ein neues Image haben, und startet nur diese neu. Nicht mehr benötigte alte Images räumst du gelegentlich auf:
docker image prune -fDen kompletten Stack stoppst und entfernst du mit:
docker compose downWichtig: down entfernt Container und Netzwerke, aber nicht den Bind-Mount-Ordner ./data. Deine Daten bleiben also erhalten. Eine vollautomatische Update-Lösung wie Watchtower (containrrr/watchtower) ist möglich, kann aber durch Breaking Changes Dienste lahmlegen. Für wichtige Stacks ist ein bewusstes, manuelles Update meist die sicherere Wahl.
Backup-Hinweis
Der gesamte Zustand eines Stacks steckt in zwei Dingen: der compose.yml und den Bind-Mount-Ordnern (hier ./data). Sichere konsequent das komplette Projektverzeichnis, zum Beispiel mit einem nächtlichen Tar-Archiv oder einem Backup-Tool wie restic. Lege Stacks am besten einheitlich unter /opt/<app> oder ~/<app> ab, dann hast du einen einzigen, klaren Pfad für dein Backup. Datenbanken (z. B. Postgres in größeren Stacks) solltest du zusätzlich mit einem Dump sichern, da ein reiner Dateikopie-Snapshot bei laufender Datenbank inkonsistent sein kann.
Troubleshooting
- "permission denied" beim docker-Befehl ohne sudo: Du hast dich nach
usermod -aG docker $USERnicht neu eingeloggt. Sitzung beenden und neu anmelden, dann erneut testen. - "docker: command not found": Schritt 4 ist fehlgeschlagen oder das Repo aus Schritt 3 wurde nicht eingebunden. Prüfe die Datei
/etc/apt/sources.list.d/docker.listund wiederholeapt-get update. - "docker-compose: command not found": Das ist erwartet. Nutze die Plugin-Schreibweise
docker composemit Leerzeichen. - Port schon belegt ("address already in use"): Ein anderer Dienst nutzt den Host-Port. Ändere im Stack die linke Zahl der Port-Zuordnung, etwa
"3002:3001". - GPG-Fehler bei apt-get update: Der Schlüssel aus Schritt 2 fehlt oder hat falsche Rechte. Den Download wiederholen und sicherstellen, dass
signed-byauf/etc/apt/keyrings/docker.asczeigt.
Optional: Rootless-Modus
Standardmäßig läuft der Docker-Daemon als root. Wer die Angriffsfläche reduzieren will, kann Docker im Rootless-Modus betreiben, also komplett ohne root-Rechte des Daemons. Das bringt zusätzliche Isolation, hat aber Einschränkungen, etwa bei Ports unter 1024 und beim Netzwerk. Für einen klassischen Homeserver-Einstieg ist die hier gezeigte Standardinstallation völlig ausreichend. Wenn du dich tiefer mit Rootless beschäftigen willst, findest du die Details in der offiziellen Docker-Dokumentation.
Fazit
Mit dem offiziellen Docker-Repo, dem Compose-Plugin und einem Benutzer in der docker-Gruppe steht das Fundament für dein Self-Hosting. Du kennst jetzt den kompletten Lebenszyklus eines Stacks: docker compose up -d zum Starten, logs -f zum Beobachten, pull plus up -d zum Aktualisieren und down zum Abbauen. Auf dieser Basis lassen sich praktisch alle gängigen Self-Hosting-Apps in wenigen Minuten ausrollen, von einem Reverse Proxy über einen Passwortmanager bis zur eigenen Foto-Cloud. Jeder weitere Dienst ist von nun an nur noch eine weitere compose.yml.
Weitere Anleitungen in den Kategorien Synology / NAS und Docker.
Quellen: Docker Docs: Install Docker Engine on Ubuntu, Docker Docs: Install Docker Engine on Debian, Uptime Kuma auf GitHub