Installation unter Debian
Voraussetzungen schaffen
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release
Keyring zu APT hinzufügen
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Repository einbinden und installieren
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
User zur Docker Gruppe hinzufügen. Damit der Benutzer nicht immer sudo vor den docker Befehl schreiben muss.
sudo usermod -aG docker $USER
Docker Compose.yml
Docker ist installiert. Nun bauen wir die nötigen Container. In diesem Fall als Beispiel 2 Container, einer enthält eine WordPress Instanz, der andere eine Datenbank. Die WordPress Instanz greift über das interne Docker Netzwerk auf den Datenbankcontainer zu. Speziell an dieser Konfiguration ist, dass eine alte PHP-Version genutzt wird und somit eine veraltete WordPress-Instanz im Docker Container isoliert wird.
Wozu braucht man die docker-compose.yml?
Die docker-compose.yml ist eine wichtige Steuerungsdatei und gehört zu dem Projekt. Man kann sie sich als Baukasten für die Dockerumgebung vorstellen. Für Updates und Änderungen wird darauf zugegriffen. Daher legt man normalerweise zu jedem Projekt einen Hauptordner an. In den Ordner kommt die Datei. Docker legt alle weiteren benötigten Dateien auch in diesem Ordner ab. Man kann den Container somit einfach kopieren und in einer neuen Umgebung starten. Unter Debian legt man die Projektordner normalerweise unter /opt oder /srv ab. Ich wähle immer /srv. Generell ist der Ort im Dateisystem jedoch egal.
Die Datei:
services:
wordpress:
image: wordpress:php7.4-apache
container_name: wp_container
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: secret
WORDPRESS_DB_NAME: wpdb
volumes:
- ./wp-data:/var/www/html:cached # WordPress-Dateien persistent auf Host speichern
depends_on:
- db
db:
image: mariadb:10.9
container_name: wp_db
restart: always
environment:
MYSQL_DATABASE: wpdb
MYSQL_USER: wp_user
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootsecret
volumes:
- db_data:/var/lib/mysql # Daten persistent speichern
volumes:
db_data:
Wer sich die Datei aufmerksam ansieht, wird sich fragen, wieso das Volume db_data ganz unten nochmal explizit angegeben wird, das Volume wp-data jedoch nicht. Der Unterschied liegt in sogenannten Named Volumes vs. Bind Mounts. Siehe weiter unten.
Der Switch restart: always bewirkt, dass der container nach einem Neustart des Hosts wieder gestartet wird.
Container initialisieren und starten. Im Stammverzeichnis des Projektordners ausführen.
docker compose up -d
Ausgehenden Traffic per nftables für das Docker Netzwerk erlauben
Folgendes in /etc/nftables.conf hinzufügen:
chain POSTROUTING {
type nat hook postrouting priority 100;
oif "eth0" ip saddr 172.18.0.0/16 masquerade
}
Anschließend nftables neu laden. Es reicht die Regeln einzulesen, ein laufendes nftables bleibt aktiv:
sudo nft -f /etc/nftables.conf
# Falls vorher nich passiert, erlauben und starten
sudo systemctl enable nftables
sudo systemctl start nftables
Befehlsreferenz
Achtung: die Befehle werden immer im Projekt-Stammordner ausgeführt!
docker compose down # Docker container runter fahren, die Container werden dabei gelöscht, die Daten aber nicht
docker compose up -d # Docker hochfahren (berücksichtigt Änderungen an der docker-compose.yml)
docker exec -it wp_container bash # in Container wp_container wechseln
docker exec -it wp_container ps # Man kann so jedes Kommando auf dem Container ausführen
| Befehl | Bedeutung |
docker compose ps | Zeigt den Status aller Container in diesem Projekt an. |
docker compose logs -f | Zeigt die Live-Ausgaben (Logs) der Anwendung an. |
docker compose stop | Hält die Container an, löscht sie aber nicht. |
docker compose down | Stoppt die Container und entfernt sie (Daten in „Volumes“ bleiben erhalten). |
Named Volumes vs. Bind Mounts
db_data – ein Docker Named Volume
volumes:
db_data:
- Das ist ein Docker-namensgebendes Volume, das Docker selbst verwaltet.
- Docker legt den Speicherort automatisch irgendwo in
/var/lib/docker/volumes/...an. - Vorteil:
- Container-Updates oder Neustarts verändern das Volume nicht.
- Ideal für Datenbanken, die persistent bleiben müssen.
- Wir brauchen es hier explizit in
volumes:, damit Docker weiß: „Das ist ein Named Volume, verwalte es!“
./wp-data:/var/www/html – ein Bind Mount
volumes:
- ./wp-data:/var/www/html
- Das ist kein Named Volume, sondern ein Bind Mount:
- Ordner
./wp-dataauf dem Host wird direkt in den Container gemountet. Also beispielsweise /srv/projekt1/wp-data. - Alle Daten in dem Ordner werden gespiegelt. Änderungen im Container und Änderungen aus dem Hostsystem wirken sich daraus aus.
- Docker verwaltet diesen Ordner nicht, es bleibt ein normaler Ordner auf dem Host.
- Ordner
- Vorteil:
- Einfach zu editieren, z. B. Plugins, Themes oder WordPress-Dateien auf dem Host.
- Änderungen auf dem Host erscheinen sofort im Container.
- Man muss diesen Mount nicht explizit unter
volumes:am Ende der Datei deklarieren, weil er direkt im Service definiert ist.