Docker Compose auf Ubuntu 24.04 einrichten
Installieren Sie Docker Engine und Compose v2 auf Ubuntu 24.04, erstellen Sie einen echten Zwei-Dienste-Stack und umgehen Sie ufw-Fallen beim Port-Publishing.
Was Sie erstellen
Docker Compose bildet die Grundlage für fast alles andere auf dieser Website. Nextcloud, Vaultwarden, n8n, Immich, Rocket.Chat: Jede dieser Anleitungen beginnt mit „Erstellen Sie diese Compose-Datei“. Auf dieser Seite wird erklärt, was diese Datei tatsächlich bewirkt. Sie installieren Docker Engine und das Compose-v2-Plugin aus dem eigenen apt-Repository von Docker auf Ubuntu 24.04. Anschließend richten Sie einen echten Stack mit zwei Diensten ein: Miniflux, einen kleinen RSS-Reader, und PostgreSQL. Dieses Paar deckt alle Muster ab, die auch die größeren Anwendungen verwenden: festgelegte Images, eine Datenbank mit Healthcheck, ein benanntes Volume, Secrets in einer .env-Datei und einen Port, der nur an localhost veröffentlicht wird.
Die Installation dauert fünf Minuten. Im restlichen Teil dieser Anleitung geht es um die Punkte, die später Probleme verursachen: Die Gruppe docker ist nur ein anderer Name für root, veröffentlichte Ports umgehen Ihre ufw-Regeln direkt, und ein bestimmtes Flag bei docker compose down löscht Ihre Datenbank ohne Bestätigungsabfrage.
Voraussetzungen: ein frischer Ubuntu-24.04-KVM-VPS, ein Benutzer mit sudo und mindestens 1 Gigabyte RAM. Eine vorhandene Docker-Installation ist ebenfalls in Ordnung. Im ersten Abschnitt wird erklärt, was Sie entfernen müssen.
Aus dem Docker-Repository installieren, nicht aus dem Ubuntu-Repository
Vor dem ersten Befehl müssen Sie zwei falsche Ansätze ausschließen. Das Ubuntu-eigene docker.io-Paket funktioniert zwar, bleibt aber hinter den Docker-Releases zurück und verwendet nicht das Plugin-Layout, von dem alle anderen Komponenten ausgehen. Die eigenständige docker-compose-Binärdatei mit Bindestrich ist dagegen Compose v1: Python-basiert, seit 2023 nicht mehr unterstützt und der Grund, warum ältere Anleitungen fehlschlagen. Das heutige Compose ist docker compose mit Leerzeichen, ein CLI-Plugin, das aus demselben Repository wie die Engine installiert wird.
Falls bereits eine dieser Komponenten auf dem System vorhanden ist, entfernen Sie sie zuerst. Das gilt auch für docker-compose-v2, die Ubuntu-eigene Paketierung des Plugins. So stammen anschließend alle Komponenten aus einem Repository:
sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runcPackage 'docker.io' is not installed, so not removed ist bei einem frischen VPS die normale Ausgabe. Fügen Sie anschließend das Docker-Repository hinzu und installieren Sie die Pakete:
sudo apt update
sudo apt install -y ca-certificates curl
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.asc
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 update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginÜberprüfen Sie alle drei Ebenen:
docker --version
docker compose version
sudo docker run --rm hello-worldDie ersten beiden Befehle geben Versionszeichenfolgen aus. Docker Compose version v2.x.x bestätigt, dass das Plugin und nicht die veraltete v1-Binärdatei installiert ist. Der Befehl hello-world sollte mit Hello from Docker! enden. Das Paket aktiviert den Dienst beim Systemstart. systemctl is-enabled docker gibt enabled aus.
Die docker-Gruppe bedeutet root-Zugriff – entscheiden Sie bewusst
Derzeit benötigt jeder docker-Befehl sudo, weil der Socket des Daemons unter /var/run/docker.sock root und der Gruppe docker gehört. Ohne Mitgliedschaft erhalten Sie den am häufigsten gesuchten Docker-Fehler:
permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sockDie standardmäßige Lösung:
sudo usermod -aG docker $USERDie Gruppenmitgliedschaft wird beim Anmelden übernommen. Deshalb bleibt der Fehler in Ihrer aktuellen Shell bestehen. Führen Sie für diese Sitzung newgrp docker aus oder melden Sie sich ab und wieder an. Danach sollte id docker in Ihren Gruppen auflisten.
Nun die klare Aussage: Die Mitgliedschaft in der docker-Gruppe gewährt root-Zugriff auf dem Host. Nicht nur eine ähnliche Berechtigung und kein eingeschränkter Zugriff, sondern root. Jedes Mitglied dieser Gruppe kann docker run --rm -it -v /:/host alpine chroot /host ausführen und das gesamte Dateisystem kontrollieren, ohne dass ein Passwort abgefragt wird. Die Gruppe dient der Benutzerfreundlichkeit, nicht der Zugriffseinschränkung.
Der Rootless-Modus von Docker ist die echte Alternative. Dabei läuft der Daemon selbst unter Ihrem nicht privilegierten Benutzer. Das bringt Einschränkungen mit sich: Für Ports unter 1024 ist zusätzliche Konfiguration erforderlich, das Netzwerk läuft über einen Userspace-Shim mit messbarem Overhead, und einige Images verhalten sich ohne echten root-Zugriff fehlerhaft. Auf einem einzelnen VPS mit nur einem Administrator, dessen Login ohnehin sudo-Berechtigungen besitzt, ändert die Gruppe in der Praxis nichts. Genau das setzen alle Anleitungen hier voraus. Geben Sie die Mitgliedschaft trotzdem niemals so aus, als wäre sie weniger weitreichend als sudo.
Aufbau einer Compose-Datei
Geben Sie jedem Stack ein eigenes Verzeichnis. Der Verzeichnisname wird zum Projektnamen und als Präfix für Container, Netzwerke und Volumes verwendet:
sudo mkdir -p /opt/miniflux && sudo chown $USER /opt/miniflux && cd /opt/minifluxErstellen Sie compose.yml (die moderne Bezeichnung; docker-compose.yml funktioniert weiterhin). Lassen Sie den alten Schlüssel version: weg. Er ist veraltet, und Compose gibt eine Warnung aus, wenn er gefunden wird.
services:
miniflux:
image: miniflux/miniflux:2.2.9
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- DATABASE_URL=postgres://miniflux:${POSTGRES_PASSWORD}@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=miniflux
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux", "-d", "miniflux"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:Jede Zeile oben ist eine bewusste Entscheidung. Gehen Sie sie einzeln durch.
Image-Versionen fest pinnen: :latest plus ein Pull ist ein unbeaufsichtigtes Upgrade
postgres:16-alpine, nicht postgres:latest. Ein Tag ist nicht unveränderlich: :latest wird bei jedem Pull erneut aufgelöst und verweist dann auf das, was der Maintainer zuletzt veröffentlicht hat. Kombinieren Sie das mit der regelmäßigen Upgrade-Routine, die Sie gleich kennenlernen, docker compose pull && docker compose up -d, und :latest bedeutet, dass Sprünge auf neue Hauptversionen erfolgen, sobald der Upstream sie veröffentlicht, und nicht erst, wenn Sie sich dafür entscheiden. Bei PostgreSQL ist das keine theoretische Möglichkeit: Ein unerwarteter Sprung von 16 auf 17 lässt den Container in einer Crash-Schleife laufen, weil das Datenverzeichnis inkompatibel ist. Upgrades zwischen PostgreSQL-Hauptversionen erfordern einen Dump und eine Wiederherstellung, keinen Neustart.
Pinnen Sie mindestens die Hauptversion (postgres:16-alpine folgt den Patch-Releases von 16.x). Anwendungen sollten Sie auf ein exaktes Release wie miniflux/miniflux:2.2.9 pinnen. Prüfen Sie die Releases-Seite des Projekts und verwenden Sie beim Erstellen der Datei die aktuell gültige Version. Ein Upgrade besteht dann aus einer einzeiligen Änderung, die Sie bewusst vornehmen und in git diff nachvollziehen können.
Auf 127.0.0.1 veröffentlichen, weil Docker ufw umgeht
"127.0.0.1:8080:8080": Host-Adresse, Host-Port, Container-Port. Die meisten Anleitungen verwenden "8080:8080". Das ist eine Kurzform für 0.0.0.0:8080:8080: Der Dienst lauscht auf jeder Schnittstelle, einschließlich der öffentlichen.
Hier liegt die Falle, die fast jeden mindestens einmal trifft. Docker veröffentlicht einen Port, indem es eine DNAT-Regel schreibt. Diese ändert das Ziel des Pakets vor der Filterung auf die interne IP-Adresse des Containers. Dadurch nimmt das Paket den Pfad FORWARD und erreicht nie INPUT, wo Ihre ufw-Regeln gelten. sudo ufw deny 8080 meldet Erfolg, ufw status zeigt den Port als verweigert an, und der Dienst antwortet trotzdem aus dem gesamten Internet. Ihre Firewall ist nicht defekt. Sie wird konstruktionsbedingt umgangen. Warum Docker ufw umgeht und wie Sie Containerverkehr tatsächlich filtern erklärt den Mechanismus und die DOCKER-USER-Lösung für Ports, die öffentlich erreichbar bleiben müssen.
Die Gewohnheit, die das gesamte Problem beseitigt: Binden Sie veröffentlichte Ports an 127.0.0.1, sofern es keinen konkreten Grund dagegen gibt. Setzen Sie für alles, was aus dem Internet erreichbar sein soll, einen Reverse Proxy davor. Genau das richtet die Anleitung zum Traefik-Reverse-Proxy als nächsten Schritt nach dieser Seite ein: einen Container, der die Ports 80 und 443 übernimmt und alle anderen Dienste anhand des Hostnamens mit TLS weiterleitet. Sie verwenden noch eine ältere Traefik-v2-Konfiguration? Die Migrationsanleitung von Traefik v2 zu v3 beschreibt die Umbenennungen und Änderungen an den Regeln.
Prüfen Sie die Bind-Adresse nach dem Start des Stacks: sudo ss -tlnp | grep 8080 sollte 127.0.0.1:8080 anzeigen, nicht 0.0.0.0:8080 oder *:8080.
Named Volumes und Bind-Mounts
db-data:/var/lib/postgresql/data ist ein Named Volume. Docker erstellt und verwaltet ein Verzeichnis unter /var/lib/docker/volumes/ und mountet es in den Container. Die Alternative ist ein Bind-Mount, ./data:/var/lib/postgresql/data. Dabei wird ein von Ihnen gewählter Pfad auf dem Host eingebunden.
In der Praxis bewährt sich folgende Aufteilung: Named Volumes für Daten, die nur Container verwenden, insbesondere für Datenbanken. Docker initialisiert das Volume mit den vom Image erwarteten Eigentümern, sodass die Dateiberechtigungen direkt passen. Bind-Mounts für Dateien, die Sie vom Host aus bearbeiten, etwa Konfigurationsdateien, die Sie mit einem Texteditor ändern, oder eine Medienbibliothek, in die Sie per rsync Dateien kopieren. Das gilt für alles, dessen Pfad eindeutig erkennbar sein soll. Das typische Problem bei Bind-Mounts sind die Eigentümer: Der Container läuft als UID 999, das Host-Verzeichnis gehört UID 1000, und die Anwendung beendet sich beim Start. In ihren Logs steht dann permission denied. Named Volumes beseitigen diese Fehlerklasse weitgehend. Dafür liegen die Daten an einem von Docker verwalteten Pfad, der weiter unten beschrieben wird.
environment und .env: Secrets nicht in git speichern
${POSTGRES_PASSWORD} wird nicht aus Ihrer Shell gelesen. Compose interpoliert den Wert aus einer Datei mit dem Namen .env, die neben compose.yml liegt. Erstellen Sie sie:
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me-to-something-long
ADMIN_PASSWORD=change-me-too
EOF
chmod 600 .env
echo ".env" >> .gitignoreErzeugen Sie echte Werte mit openssl rand -hex 24. Verwenden Sie absichtlich Hex statt base64: Dieses Passwort wird Bestandteil der DATABASE_URL-Verbindungszeichenfolge. Die von base64 erzeugten Zeichen /, + und = stören die URL-Analyse. Der Fehler äußert sich dann als Authentifizierungsfehler und nicht als Syntaxfehler, was Sie einen Abend kosten kann. Die Zeile .gitignore gehört vor den ersten Commit. Die Compose-Datei können Sie sicher veröffentlichen und versionieren. Die Datei .env dürfen Sie niemals veröffentlichen. Ein Secret, das in der Git-Historie steht, muss als kompromittiert betrachtet und rotiert werden. Wenn Sie den Stack mit einer fehlenden Variable starten, gibt Compose eine deutliche Warnung aus und verwendet anschließend eine leere Zeichenfolge. Bei einem PostgreSQL-Passwort führt das zu einer fehlerhaften Bereitstellung:
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string.docker compose config gibt die vollständig interpolierte Datei aus. Das ist die schnellste Möglichkeit zu prüfen, welche Werte die Container tatsächlich erhalten. Denken Sie daran, dass die Ausgabe Ihre Secrets enthält.
depends_on wartet auf nichts, wenn Sie keinen Healthcheck hinzufügen
Ein einfaches depends_on: [db] steuert nur die Startreihenfolge: Compose startet PostgreSQL zuerst und die Anwendung kurz danach, obwohl PostgreSQL noch einige Sekunden benötigt, bevor es Verbindungen akzeptiert. Die Anwendung verbindet sich mit der Datenbank, schlägt fehl und beendet sich oder versucht die Verbindung erneut. Das hängt davon ab, wie sie implementiert wurde.
Die zuverlässige Variante verwendet die Konfiguration aus der Datei oben: Der Dienst db definiert einen healthcheck. PostgreSQL liefert pg_isready genau für diesen Zweck mit. Die Anwendung deklariert depends_on mit condition: service_healthy. Compose startet die Datenbank, prüft den Zustand alle 10 Sekunden und startet Miniflux erst, wenn der Check erfolgreich ist. Wird die Datenbank nie gesund, etwa wegen eines falschen Passworts oder eines beschädigten Volumes, startet die Anwendung nicht. Compose teilt Ihnen mit, welche Abhängigkeit fehlgeschlagen ist:
dependency failed to start: container miniflux-db-1 is unhealthyDiese Meldung verweist auf docker compose logs db. Dort steht der eigentliche Fehler.
restart: unless-stopped
restart: unless-stopped bei beiden Services sorgt dafür, dass die Container nach einem Absturz und nach einem Neustart des VPS wieder gestartet werden. Sie bleiben jedoch beendet, wenn Sie zuvor absichtlich docker compose stop ausgeführt haben. Die Alternative always startet Container auch nach einem manuellen Stop wieder. Das ist selten beabsichtigt. Ohne eine Restart-Richtlinie kann ein Neustart nach einem Kernel-Update um 4 Uhr morgens Ihre Services unbemerkt außer Betrieb nehmen, bis Sie es bemerken.
Die täglichen Befehle
Für den täglichen Betrieb benötigen Sie fünf Befehle. Führen Sie sie aus dem Projektverzeichnis aus.
docker compose up -d # create and start; idempotent, recreates only what changed
docker compose ps # status, ports, and health of this project's containers
docker compose logs -f miniflux # follow one service's logs; --tail 100 for recent history
docker compose pull && docker compose up -d # upgrade to the pinned tags
docker compose down # stop and remove containers and the networkup -d kann wiederholt und gefahrlos ausgeführt werden. Der Befehl vergleicht die Datei mit dem aktuellen Zustand und startet nur Dienste neu, deren Konfiguration oder Image geändert wurde. Das Upgrade-Paar ruft die Versionen ab, auf die Ihre festgelegten Tags derzeit zeigen: Patch-Releases unter postgres:16-alpine. Bei einer exakt festgelegten Version wird nichts abgerufen, bis Sie diese ändern. Genau das ist beabsichtigt. Nach Upgrades bleiben alte Images auf dem System. Geben Sie mit docker image prune -f Speicherplatz frei.
Nun zum destruktiven Befehl, ausdrücklich: docker compose down kann gefahrlos verwendet werden, wenn Container und Netzwerk verworfen werden dürfen und Ihre Daten im Volume liegen. docker compose down -v löscht auch die benannten Volumes. Ihre Datenbank ist dann sofort und unwiderruflich gelöscht. Es gibt keine Bestätigungsabfrage und keine Möglichkeit zum Rückgängigmachen. Das Flag -v ist zum Entfernen von Testumgebungen vorgesehen. Bei einem Stack mit produktiven Daten müssen Sie es genauso behandeln wie rm -rf. Unter /var/lib/docker/volumes/ gibt es keinen Papierkorb.
Für eine einmalige Shell in einem laufenden Container bringt docker compose exec db psql -U miniflux Sie in die Datenbank. Mit docker compose exec miniflux sh öffnen Sie eine Shell in der Anwendung.
Wo Ihre Daten tatsächlich liegen
Benannte Volumes erhalten das Projektpräfix. Daher wird db-data in einem Verzeichnis namens miniflux zu miniflux_db-data:
docker volume ls
docker volume inspect miniflux_db-dataDie Ausgabe von inspect enthält die relevante Zeile:
"Mountpoint": "/var/lib/docker/volumes/miniflux_db-data/_data"Dieses Verzeichnis enthält die Datenbank. Es gehört auf dem Host-Dateisystem root und bleibt bei down, Upgrades und dem Neuerstellen von Containern erhalten. Genau dieses Verzeichnis müssen Ihre Backups sichern.
Benanntes Volume sichern
Das Standardmuster ist ein kurzlebiger Container, der das Volume schreibgeschützt neben ein Hostverzeichnis einbindet und die Daten mit tar archiviert:
docker run --rm \
-v miniflux_db-data:/data:ro \
-v "$PWD":/backup \
alpine:3.22 tar czf /backup/miniflux-db-$(date +%F).tar.gz -C /data .Es ist keine Installation erforderlich, und es bleibt kein laufender Prozess zurück. Beim Wiederherstellen gehen Sie spiegelbildlich vor: tar xzf in ein neues, leeres Volume, wobei Sie die Mounts umkehren.
Eine Besonderheit gilt für Datenbanken: Wenn Sie das Datenverzeichnis eines laufenden Postgres mit tar archivieren, kann das Archiv einen Zustand mitten in einem Schreibvorgang enthalten. Postgres startet dann möglicherweise nicht ordnungsgemäß. Entweder docker compose stop für die wenigen Sekunden, die tar benötigt, oder Sie erstellen besser einen logischen Dump. Dieser ist konstruktionsbedingt konsistent:
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz-T deaktiviert das Pseudo-Terminal, das Compose standardmäßig zuweist. Wenn die Dump-Ausgabe durch ein TTY geleitet wird, kann sie beschädigt werden. Nehmen Sie einen dieser Befehle in cron auf und kopieren Sie das Ergebnis vom VPS. Ein Backup auf derselben Festplatte wie die geschützten Daten ist nur eine Kopie, kein Backup. Der Nextcloud-Leitfaden baut genau um diese beiden Muster eine vollständige, geplante Routine auf.
Fehlerfälle und die angezeigten Meldungen
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Sie sind noch nicht Mitglied der docker-Gruppe, oder die aktuelle Sitzung wurde vor der Gruppenänderung gestartet. id zeigt die effektiven Gruppen an. newgrp docker übernimmt die Änderung für die aktuelle Shell. Durch Ab- und wieder Anmelden wird die Änderung für alle Sitzungen übernommen.
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?: Das ist ein anderes Problem. Der Daemon selbst ist nicht aktiv. sudo systemctl status docker und sudo journalctl -u docker -n 50 zeigen den Grund. Auf einem VPS ist ein volles Dateisystem die häufigste Ursache. Führen Sie zuerst df -h /var/lib/docker aus.
Bind for 127.0.0.1:8080 failed: port is already allocated: Ein anderer Container hat diesen Host-Port bereits veröffentlicht. docker ps zeigt, welcher Container das ist. Meist ist ein veralteter Container aus einem experimentellen docker run von vor einigen Wochen die Ursache. Wenn docker ps keine Ausgabe liefert, verwendet ein Prozess außerhalb von Docker den Port. sudo ss -tlnp | grep 8080 zeigt, welcher Prozess das ist.
yaml: line 14: did not find expected key: Einrückungsfehler an der genannten Zeile oder unmittelbar darüber. Compose-Dateien sind YAML-Dateien: Verwenden Sie eine Einrückung von zwei Leerzeichen, ausschließlich Leerzeichen, und kein Tabulatorzeichen. Ein Tabulatorzeichen an beliebiger Stelle führt zum Fehler. docker compose config prüft die Datei, ohne etwas zu starten. Führen Sie den Befehl nach jeder Änderung aus.
Die ufw-Überraschung gibt überhaupt keine Fehlermeldung aus. Genau das macht sie gefährlich: Das Deployment funktioniert, ufw status sieht korrekt aus, und ein Portscan von außerhalb findet Ihre Datenbank trotzdem. Lesen Sie den Abschnitt zu den Ports oben erneut. Prüfen Sie jeden ports:-Eintrag auf ein fehlendes Präfix 127.0.0.1:. Bestätigen Sie das Ergebnis von einem anderen Rechner aus mit curl http://your-vps-ip:8080. Die gewünschte Antwort lautet connection refused.
Von hier aus macht der Traefik-Leitfaden aus diesem einzelnen Stack mehrere Anwendungen hinter einem gemeinsamen HTTPS-Einstiegspunkt. Was sich 2026 für Self-Hosting lohnt ist die Liste der Anwendungen, die Sie darüber betreiben können. Sobald mehrere dieser Stacks laufen und jeder sein eigenes Anmeldeformular verwendet, führt ein selbst gehosteter SSO-Server wie Authentik sie hinter demselben Proxy wieder in einem Konto zusammen.
Ein Game-Server wie ein Minecraft-Server auf einem VPS ist ein guter erster Compose-Projekt, an dem Sie üben können. Wenn Sie lieber mit etwas lernen möchten, das Sie täglich öffnen, ist openGym, ein selbst gehosteter Trainings-Tracker ein kleiner Stack, der auf einem Git-Tag statt auf einem Image-Tag festgelegt ist. Davor sollte TLS eingerichtet werden, bevor Sie den ersten Passkey registrieren. Fotos sind normalerweise das Erste, was viele aus der Cloud eines anderen Anbieters zurückholen möchten. Der Vergleich von PhotoPrism und Immich klärt, wie viel RAM mindestens erforderlich ist und welche Backup-Routine Sie einrichten müssen, bevor Sie sich bei einem der beiden für ein Volume entscheiden. Wenn zwei Dienste nicht mehr ausreichen, folgt beim Einrichten von AFFiNE als Notion-ähnlichem Arbeitsbereich denselben Mustern mit vier Containern. Das ist ein guter Test dafür, ob die oben genannten festgelegten Tags, Healthchecks und benannten Volumes bereits zur Gewohnheit geworden sind.
FAQ
Warum erhalte ich „permission denied while trying to connect to the Docker daemon socket“?
Ihr Benutzer ist nicht Mitglied der Gruppe docker oder wurde erst nach Beginn der aktuellen Sitzung hinzugefügt. Die Gruppenmitgliedschaft gilt erst bei der Anmeldung. Führen Sie sudo usermod -aG docker $USER und anschließend newgrp docker aus oder melden Sie sich ab und wieder an. Prüfen Sie die Mitgliedschaft mit id. Die Gruppe gewährt Zugriff auf den Host mit Berechtigungen auf Root-Niveau. Fügen Sie daher nur Benutzer hinzu, denen Sie auch sudo-Zugriff gewähren würden.
Löscht docker compose down meine Daten?
Ein einfaches docker compose down löscht keine Daten. Es entfernt die Container und das Projektnetzwerk. Benannte Volumes bleiben erhalten, und der nächste Aufruf von up -d bindet sie wieder ein. docker compose down -v ist die destruktive Variante. Der Befehl löscht die benannten Volumes, also auch Ihre Datenbank, ohne Rückfrage und ohne Wiederherstellungsmöglichkeit. Führen Sie -v niemals für einen Stack mit echten Daten aus, solange kein verifiziertes Backup vorhanden ist.
Was ist der Unterschied zwischen docker-compose und docker compose?
docker-compose mit Bindestrich ist Compose v1. Dabei handelt es sich um eine eigenständige Python-Binärdatei, deren Lebensdauer 2023 endete und die auf neuen Servern nicht installiert werden sollte. docker compose mit Leerzeichen ist Compose v2. Dabei handelt es sich um ein Go-Plugin für die Docker CLI, das aus dem apt-Repository von Docker als docker-compose-plugin installiert wird. Befehle und YAML sind nahezu vollständig kompatibel. Wenn ein älteres Tutorial docker-compose up angibt, verwenden Sie stattdessen docker compose up.
Warum kann ich meinen Docker-Container aus dem Internet erreichen, obwohl ufw den Port blockiert?
Docker veröffentlicht Ports mit DNAT-Regeln in der PREROUTING-Kette von iptables. Die umgeschriebenen Pakete durchlaufen den FORWARD-Pfad über die eigenen Ketten von Docker und erreichen daher nicht die INPUT-Kette, in der die Regeln von ufw gelten. ufw deny 8080 hat deshalb keine Wirkung auf einen veröffentlichten Container-Port. Beheben Sie das Problem an der Quelle: Veröffentlichen Sie den Port auf 127.0.0.1: und stellen Sie die Dienste stattdessen über einen Reverse Proxy bereit.
Sollte ich ein benanntes Volume oder einen Bind-Mount verwenden?
Verwenden Sie benannte Volumes für Daten, auf die nur der Container zugreift, insbesondere für Datenbanken. Docker setzt dabei den vom Image erwarteten Eigentümer, sodass die Berechtigungen direkt funktionieren. Verwenden Sie Bind-Mounts für Dateien, die Sie auch auf dem Host bearbeiten: Konfigurationsdateien, die Sie ändern, Medien, die Sie hochladen, und alle Dateien, deren Pfad eindeutig erkennbar sein soll. Wenn ein Container beim Start mit permission denied auf einem Bind-Mount fehlschlägt, sollten Sie zuerst eine abweichende UID zwischen Host und Container prüfen.