Du willst nur eben einen neuen Container starten — Vaultwarden, Immich, irgendwas Schönes fürs Homelab — und Docker grätscht rein: Bind for 0.0.0.0:80 failed: port is already allocated. Oder die Geschwister-Variante address already in use. Willkommen bei einem der meistgegoogelten Probleme überhaupt. Die gute Nachricht: Der Fall ist in ein paar Minuten gelöst, wenn du weißt, welche zwei Befehle du fragen musst. Genau das machen wir jetzt — systematisch, vom Symptom bis zum Fix.

Was du brauchst
- Einen Linux-Rechner oder -Server (Debian, Ubuntu, Raspberry Pi OS — egal)
- sudo-Rechte und ein Terminal
- Docker nur, falls dein Problem aus einem Container kommt — die Diagnose selbst funktioniert auch ohne
Schritt 1: Die Fehlermeldung lesen — sie verrät schon die halbe Lösung
Bevor du wild Container neustartest: Docker sagt dir ziemlich genau, was los ist. Es gibt zwei Varianten dieser Meldung, und sie bedeuten unterschiedliche Dinge.
Variante eins:
Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in useÜbersetzt: Ein Prozess auf dem Host selbst hält den Port fest — ein vorinstallierter Webserver, ein Systemdienst, irgendwas außerhalb von Docker.
Variante zwei:
Bind for 0.0.0.0:80 failed: port is already allocatedÜbersetzt: Ein anderer Docker-Container hat sich den Port schon geschnappt. Oft ein Überbleibsel von einem früheren Experiment, das still im Hintergrund weiterläuft.
Schritt 2: Herausfinden, wer auf dem Port lauscht
Jetzt wird verhört. Das Werkzeug dafür heißt ss und ist auf so gut wie jedem aktuellen Linux vorinstalliert:
sudo ss -tulpn | grep :80Die Buchstabensuppe dahinter ist schnell erklärt: -t zeigt TCP, -u UDP, -l nur lauschende Ports, -p den zugehörigen Prozess und -n Portnummern statt Dienstnamen. Das sudo ist kein Deko-Element: Ohne Root-Rechte bleibt die Prozess-Spalte bei fremden Prozessen einfach leer, und du verhörst eine Wand.
Die Ausgabe sieht dann etwa so aus:
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))Da steht der Name des Schuldigen samt Prozess-ID. Falls du lieber lsof magst, geht auch das:
sudo lsof -i :80Beide Befehle beantworten dieselbe Frage. Such dir einen aus und merk ihn dir — du wirst ihn wieder brauchen.
Schritt 3: Den Schuldigen einordnen
Jetzt kommt es darauf an, was in der Prozess-Spalte steht.
Fall A — ein normaler Dienst wie nginx, apache2 oder smbd: Das ist ein Programm direkt auf dem Host. Mit systemctl status nginx siehst du, ob es als Systemdienst läuft und seit wann.
Fall B — da steht docker-proxy: Dann ist es ein Container. Welcher genau, verrät dir diese Zeile:
docker ps --format '{{.Names}}\t{{.Ports}}'Das listet alle laufenden Container mit ihren Port-Zuordnungen, etwa 0.0.0.0:80->2368/tcp. Der Container, bei dem dein Port vor dem Pfeil steht, ist dein Kandidat.
Schritt 4: Den Port freigeben — drei saubere Wege
Weg 1: Den Alt-Dienst stoppen. Der Klassiker ist ein Apache oder nginx, der bei der Server-Installation mitkam und den nie jemand bestellt hat. Wenn du ihn nicht brauchst:
sudo systemctl stop apache2
sudo systemctl disable apache2stop beendet den Dienst sofort, disable sorgt dafür, dass er nach dem nächsten Neustart nicht wieder aus dem Gebüsch springt. Vorher kurz nachdenken: Läuft da wirklich nichts drüber, was du brauchst?
Weg 2: Deinem neuen Dienst einen anderen Host-Port geben. Wenn der bisherige Bewohner bleiben soll, zieht der Neue einfach in ein anderes Zimmer. In der Compose-Datei:
services:
meindienst:
ports:
- "8081:80"Danach erreichst du den Dienst unter http://server-ip:8081.
Weg 3: Den Zombie-Container abräumen. Wenn ein vergessener Container den Port hält und du ihn nicht mehr brauchst:
docker stop alter-container
docker rm alter-containerDanach startet dein neuer Stack ohne Murren.
Schritt 5: Der Spezialfall Port 53
Ein Kapitel für sich, weil er so viele erwischt: Wer Pi-hole oder AdGuard Home installieren will, scheitert auf Ubuntu und vielen anderen modernen Distributionen zuverlässig an Port 53. Der Übeltäter heißt systemd-resolved — ein Systemdienst, der auf der Adresse 127.0.0.53 einen kleinen DNS-Vermittler betreibt, den sogenannten Stub-Listener. Nützlich für den Alltag, im Weg, sobald du selbst DNS-Server spielen willst.
Der offiziell von Pi-hole dokumentierte Fix in drei Zeilen:
sudo sh -c 'mkdir -p /etc/systemd/resolved.conf.d && printf "[Resolve]\nDNSStubListener=no\n" | tee /etc/systemd/resolved.conf.d/no-stub.conf'
sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
sudo systemctl restart systemd-resolvedZeile eins legt eine Konfigurationsdatei an, die den Stub-Listener abschaltet. Zeile zwei biegt /etc/resolv.conf auf die Datei um, die systemd-resolved automatisch mit den echten DNS-Servern deines Netzwerks pflegt — sonst weiß dein Server danach selbst nicht mehr, wie man Namen auflöst. Zeile drei startet den Dienst neu, damit alles greift. Wichtig: Das machst du nur, wenn du auf dieser Maschine wirklich einen eigenen DNS-Dienst betreiben willst. Für alle anderen Port-Konflikte gilt weiter Schritt 4.
Häufige Stolpersteine
ss ohne sudo ausgeführt: Der Port taucht auf, aber die Prozess-Spalte ist leer — und du rätst ins Blaue. Einfach mit sudo wiederholen.
docker-proxy gekillt: Bitte nicht. Das ist kein eigenständiges Programm, sondern Dockers Weiterleitungshelfer für den Container. Stopp stattdessen den Container, der dahintersteckt (Schritt 3, Fall B).
Die falsche Seite des Mappings geändert: Aus "8081:80" wurde "8080:81", und plötzlich antwortet gar nichts mehr. Merkregel aus der Klartext-Box: links Haustür, rechts Wohnungstür — nur links anfassen.
Dienst mit kill -9 abgeschossen: systemd startet seine Schützlinge brav neu, der Port ist zwei Sekunden später wieder belegt. Systemdienste beendest du mit systemctl stop, sonst spielst du Whack-a-Mole.
Fazit
Ein belegter Port sieht nach Drama aus, ist aber eines der dankbarsten Probleme im Homelab: Die Fehlermeldung sagt dir, in welcher Ecke du suchen musst, und ss -tulpn liefert den Namen frei Haus. Meine Einschätzung: In neun von zehn Fällen ist der Schuldige ein vergessener Container oder ein vorinstallierter Webserver, und der Fix dauert keine fünf Minuten. Den Befehl einmal ins Muskelgedächtnis übernehmen — danach hat diese Fehlermeldung ihren Schrecken dauerhaft verloren.
Welcher Port-Klassiker hat dich schon Nerven gekostet — der ungefragte Apache, ein Zombie-Container oder doch der Endgegner Port 53? Und räumst du alte Container konsequent ab, oder sammelt sich bei dir auch eine kleine Geisterstadt? Schreib's in die Kommentare.
One more thing … wenn dein Stack wieder läuft und du künftig sofort merken willst, sobald ein Dienst schwächelt: In unserer Anleitung Uptime Kuma mit Docker installieren baust du dir in einer Viertelstunde einen Wachdienst, der dich anstupst, bevor es jemand anderes merkt.