Running Docker on Debian 13 Properly – 15 Things Administrators Should Know
Docker auf einem Debian-Server zu installieren ist einfach. Docker dauerhaft, sicher und wartbar zu betreiben, ist eine andere Geschichte. Spätestens wenn mehrere Anwendungen wie Reverse Proxies, Datenbanken, Passwortmanager, Monitoring oder eigene Webanwendungen auf einem Host laufen, reichen zufällig zusammenkopierte Compose-Dateien nicht mehr aus.
Dieser Guide zeigt 15 Punkte für den professionelleren Docker-Betrieb auf Debian 13 – inklusive konkreter Shell-Beispiele für Installation, Compose, Rechte, Netzwerke, Firewall, Logging, Updates und Backups.
1. Docker aus einer konsistenten Quelle installieren
Mische nicht unkontrolliert docker.io, docker-ce, manuelle Compose-Binaries und alte Paketreste. Prüfe zunächst den Bestand:
docker --version
docker compose version
docker info
dpkg -l | grep -E 'docker|containerd'
Eine konsistente Installation umfasst typischerweise Docker Engine, CLI, containerd, Buildx und das Compose-Plugin.
2. docker compose statt Legacy-docker-compose
Die moderne Syntax verwendet Compose als Docker-CLI-Plugin:
docker compose up -d
docker compose down
docker compose pull
docker compose logs -f
docker compose ps
Gerade nach Migrationen von älteren Debian-Systemen lohnt sich die Prüfung:
docker compose version
docker-compose --version
3. Saubere Verzeichnisstruktur für Container-Projekte
Verstreue Compose-Dateien nicht beliebig über den Server. Eine nachvollziehbare Struktur könnte so aussehen:
/opt/docker/
├── nginx-proxy-manager/
│ ├── compose.yml
│ └── data/
├── application/
│ ├── compose.yml
│ ├── .env
│ ├── config/
│ └── data/
└── monitoring/
└── compose.yml
Wichtig ist Konsistenz: Ein Projekt sollte Konfiguration, Compose-Datei und zugehörige persistente Daten klar erkennbar zusammenhalten.
4. Wichtige Daten niemals nur im Container speichern
Container sind austauschbar. Persistente Daten gehören in Volumes oder Bind-Mounts.
services:
database:
image: mariadb:11
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Volumes prüfen:
docker volume ls
docker volume inspect db_data
Für Konfigurationsdateien ist ein read-only Bind-Mount häufig sinnvoll:
volumes:
- ./config/app.conf:/etc/app/app.conf:ro
5. Restart-Policies setzen
Ein Server startet neu, Docker wird aktualisiert oder ein Prozess beendet sich unerwartet. Für viele Dienste ist daher sinnvoll:
restart: unless-stopped
Die Einstellung prüfen:
docker inspect CONTAINERNAME \
--format '{{.HostConfig.RestartPolicy.Name}}'
Auch der Docker-Dienst selbst sollte beim Systemstart verfügbar sein:
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
systemctl status docker
6. Die Docker-Gruppe bedeutet weitreichende Rechte
Der bequeme Befehl:
sudo usermod -aG docker $USER
newgrp docker
erspart zwar sudo, ist aber kein harmloser Komfortzugriff. Mitglieder der Docker-Gruppe erhalten weitreichende Möglichkeiten über den Docker-Daemon.
getent group docker
Prüfe daher bewusst, wer Mitglied dieser Gruppe ist.
7. Rootless Docker bewusst bewerten
Docker kann auch im Rootless-Modus betrieben werden. Das kann die Rechte-Trennung verbessern, bringt aber Unterschiede bei Netzwerk, Storage und bestimmten Container-Anforderungen mit sich. Rootless Docker sollte deshalb bewusst in die vorhandene Serverarchitektur passen und nicht automatisch als universelle Lösung betrachtet werden.
8. Das Docker-Socket niemals ungeschützt veröffentlichen
Der lokale Socket befindet sich üblicherweise hier:
ls -l /var/run/docker.sock
Ein ungeschützter TCP-Zugriff auf den Docker-Daemon wäre ein erhebliches Sicherheitsrisiko. Für Remote-Administration sind abgesicherte Verfahren wie SSH sinnvoll.
docker context create \
--docker host=ssh://user@server \
mein-server
docker context use mein-server
9. Docker und Firewall-Regeln verstehen
Bei Docker darf man nicht einfach davon ausgehen, dass eine UFW-Regel automatisch jeden veröffentlichten Container-Port wie erwartet schützt. Prüfe deshalb regelmäßig:
docker ps
Ein Mapping wie:
0.0.0.0:8080->80/tcp
bedeutet, dass der Dienst auf allen Interfaces veröffentlicht wird. Soll ein Dienst nur lokal erreichbar sein:
ports:
- "127.0.0.1:8080:80"
10. Docker-Netzwerke segmentieren
Eine Datenbank muss normalerweise nicht direkt vom Internet erreichbar sein. Trenne Frontend und Backend:
networks:
frontend:
backend:
services:
proxy:
networks:
- frontend
app:
networks:
- frontend
- backend
database:
networks:
- backend
Innerhalb des Compose-Netzwerks kann die Anwendung den Service-Namen direkt verwenden, beispielsweise:
database:3306
11. latest ist keine Update-Strategie
Statt:
image: mariadb:latest
ist eine kontrollierbare Version oft besser:
image: mariadb:11
Updates bewusst durchführen:
docker compose pull
docker compose up -d
docker compose ps
12. Docker-Logs rotieren, bevor die Platte voll ist
Prüfe den Speicherverbrauch:
df -h
docker system df
Eine mögliche Konfiguration in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
Anschließend:
sudo systemctl restart docker
13. daemon.json vor dem Neustart validieren
Eine fehlerhafte Daemon-Konfiguration kann Docker am Start hindern.
sudo dockerd --validate \
--config-file=/etc/docker/daemon.json
Danach:
sudo systemctl restart docker
systemctl status docker
journalctl -u docker -n 100 --no-pager
14. Backups: Compose-Dateien allein reichen nicht
Sichere sowohl Konfigurationen als auch persistente Daten und Datenbanken. Volumes auflisten:
docker volume ls
Beispiel für ein Volume-Backup:
docker run --rm \
-v mein_volume:/source:ro \
-v "$PWD":/backup \
alpine \
tar czf /backup/mein_volume.tar.gz -C /source .
Für MariaDB ist ein konsistenter Dump häufig die bessere Wahl:
docker compose exec -T database \
mysqldump -u root -p MEINE_DATENBANK \
> backup.sql
Passwörter sollten dabei nicht unnötig direkt in der Shell-History landen.
15. Nicht nur Container, sondern den gesamten Server warten
Ein Docker-Host besteht aus mehr als Containern. Regelmäßig prüfen:
sudo apt update
sudo apt upgrade
docker version
docker compose version
uname -a
df -h
free -h
docker system df
docker ps -a
docker images
Ungenutzte Ressourcen können geprüft und bei Bedarf bereinigt werden:
docker system prune
Mit aggressiveren Varianten wie docker system prune -a --volumes sollte man auf produktiven Systemen ausgesprochen vorsichtig sein.
Bonus: Solide Compose-Grundlage
services:
app:
image: example/application:1.2
restart: unless-stopped
environment:
TZ: Europe/Berlin
volumes:
- ./data:/app/data
networks:
- frontend
- backend
database:
image: mariadb:11
restart: unless-stopped
environment:
MARIADB_DATABASE: example
MARIADB_USER: example
MARIADB_PASSWORD: CHANGE_ME
MARIADB_ROOT_PASSWORD: CHANGE_ME_TOO
volumes:
- db_data:/var/lib/mysql
networks:
- backend
volumes:
db_data:
networks:
frontend:
backend:
Mein Docker-Admin-Check für Debian 13
docker version
docker compose version
docker ps -a
docker images
docker network ls
docker volume ls
docker system df
df -h
free -h
systemctl status docker
journalctl -u docker -n 50 --no-pager
docker ps --format "table {{.Names}} {{.Image}} {{.Ports}} {{.Status}}"
Fazit
Docker auf Debian 13 ist hervorragend für den Betrieb mehrerer Anwendungen geeignet – sofern Datenpersistenz, Rechte, Netzwerke, Firewall, Logging, Backups und Updates bewusst geplant werden. Gerade beim Wechsel von Debian 12 auf Debian 13 ist der richtige Zeitpunkt gekommen, alte Compose-Installationen aufzuräumen und aus einem „es läuft irgendwie“-Server eine wartbare Container-Infrastruktur zu machen.