Docker und Docker Compose
Docker Engine mit Compose-Plugin aus dem offiziellen Repository, ein Compose-Beispiel und warum Docker deine Firewall umgeht.
5 Min. Lesezeit
Auf dieser Seite
Gilt für Debian 12/13, Ubuntu 22.04/24.04, AlmaLinux 9 und Rocky Linux 9. Wir installieren Docker aus dem offiziellen Repository von Docker, nicht das ältere docker.io der Distribution.
Debian
apt remove -y docker.io docker-compose podman-docker containerd runc 2>/dev/null
apt install -y ca-certificates curl
install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
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/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginUbuntu
Wie Debian, nur mit ubuntu in den Adressen:
apt remove -y docker.io docker-compose podman-docker containerd runc 2>/dev/null
apt install -y ca-certificates curl
install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
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 "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" > /etc/apt/sources.list.d/docker.list
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginAlmaLinux und Rocky Linux
dnf remove -y podman buildah runc 2>/dev/null
dnf install -y dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now dockerdnf fragt nach dem GPG-Schlüssel von Docker. Der Fingerabdruck muss 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35 sein.
Auf Debian und Ubuntu startet Docker nach der Installation von selbst.
Prüfen, ob es geklappt hat
docker version
docker compose version
docker run --rm hello-worldhello-world lädt ein winziges Image und gibt Hello from Docker! aus.
Ein Compose-Beispiel
Eine kleine Webanwendung mit Datenbank. Leg einen Ordner an:
mkdir -p /opt/app && cd /opt/app
nano compose.yamlservices:
web:
image: nginx:stable
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- db-data:/var/lib/postgresql/data
secrets:
db_password:
file: ./db_password.txt
volumes:
db-data:mkdir -p html && echo "Hallo" > html/index.html
openssl rand -base64 24 > db_password.txt && chmod 600 db_password.txt
docker compose up -dWichtig sind diese Punkte:
127.0.0.1:8080:80veröffentlicht den Webserver nur auf dem Server selbst. Von außen kommt keiner dran. Ein Reverse-Proxy wie Caddy oder nginx auf dem Host leitet dannhttps://deine-domaindorthin.- Die Datenbank hat gar kein
ports:. Der Webcontainer erreicht sie trotzdem über den Namendb, weil Compose beide in ein gemeinsames Netz steckt. restart: unless-stoppedstartet die Container nach einem Neustart des Servers wieder.
Nützliche Befehle im Ordner:
docker compose ps # was läuft
docker compose logs -f web # Logs live
docker compose pull # neue Images holen
docker compose up -d # mit neuen Images neu starten
docker compose down # stoppen und entfernen (Volumes bleiben)Test auf dem Server:
curl http://127.0.0.1:8080Docker und die Firewall
Docker schreibt eigene Regeln in die Paketfilter des Kernels. Verbindungen zu veröffentlichten Ports laufen an den Regeln von ufw und firewalld vorbei. Ein ufw deny 8080 hilft also nicht, wenn ein Container mit -p 8080:80 läuft.
So bleibst du sicher:
-
Nur auf 127.0.0.1 veröffentlichen, wie im Beispiel oben:
"127.0.0.1:8080:80". Was von außen erreichbar sein soll (meist nur 80 und 443), geht über einen Reverse-Proxy auf dem Host oder einen eigenen Proxy-Container. -
Datenbanken nie veröffentlichen. Container im selben Compose-Netz brauchen kein
ports:. -
Wenn ein Port doch öffentlich sein muss, aber nur für bestimmte Adressen: Regeln in der Kette
DOCKER-USER. Docker wertet sie vor seinen eigenen Regeln aus. Beispiel, Port 5432 nur für198.51.100.7(Schnittstellenname mitip -br linknachsehen):bashiptables -I DOCKER-USER -i eth0 -p tcp --dport 5432 ! -s 198.51.100.7 -j DROPSolche Regeln sind nach einem Neustart weg, wenn du sie nicht dauerhaft speicherst, und gelten nur für IPv4. Darum ist Punkt 1 fast immer der bessere Weg.
Häufige Fehler
| Meldung | Ursache und Lösung |
|---|---|
permission denied while trying to connect to the Docker daemon socket | Ohne root und nicht in der Gruppe docker. sudo docker … oder Gruppe hinzufügen und neu anmelden. |
docker: 'compose' is not a docker command | docker-compose-plugin fehlt. Der alte Befehl docker-compose mit Bindestrich ist veraltet. |
Bind for 0.0.0.0:80 failed: port is already allocated | Den Port nutzt schon etwas anderes. ss -tlnp zeigt was. |
Konflikt mit podman oder runc auf AlmaLinux/Rocky | Vorher dnf remove podman buildah runc, wie oben. |
no space left on device | Alte Images und Build-Reste: docker system df, aufräumen mit docker system prune. |
Wie es weitergeht
- Firewall einrichten für SSH und die Ports deines Reverse-Proxys.
- Swap anlegen, wenn viele Container den RAM füllen.
- Lieber ohne eigenen Server? Webanwendungen aus Git baut und betreibt CitexNode Deploy.
- Hilfe: Ticket.