Docker Compose für lokale Stacks
PHP, eine Datenbank und einen Cache lokal gemeinsam ausführen
Docker Compose für lokale Stacks ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
Lokale Stacks mit Compose
Echte PHP-Anwendungen bestehen nie nur aus PHP – sie benötigen eine Datenbank, einen Cache und manchmal eine Warteschlange sowie einen Mail-Catcher. Docker Compose deklariert all diese Komponenten als Services in einer Datei und verbindet sie in einem gemeinsamen Netzwerk, sodass sie sich über ihre Namen erreichen.
In dieser Lektion erstellen Sie einen vollständigen lokalen Stack: PHP-FPM + nginx + MySQL + Redis, mit Volumes, Healthchecks und einer Abhängigkeitsreihenfolge.
Service-Grundgerüst
Eine Compose-Datei listet Services unter services: auf. Jeder Service kann mit build aus einem Dockerfile gebaut oder mit image aus einem Image geladen werden. Compose erstellt ein Standardnetzwerk, in dem jeder Service über seinen Schlüssel erreichbar ist – Ihre PHP-Anwendung verbindet sich mit MySQL unter dem Hostnamen db, nicht unter localhost.
services:
app:
build:
context: .
target: dev # multi-stage dev target
volumes:
- ./:/app # live code mount
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.4
redis:
image: redis:7-alpinenginx vor FPM
FPM spricht FastCGI auf Port 9000, nicht HTTP. nginx übernimmt HTTP und leitet .php-Anfragen an app:9000 weiter. Die nginx-Konfiguration verweist über den Compose-Namen auf den PHP-Service.
# docker/nginx/default.conf
server {
listen 80;
root /app/public;
index index.php;
location / {
try_files $uri /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000; # service name from compose
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}Web-Service anbinden
Der nginx-Service mountet denselben Quellcode, um SCRIPT_FILENAME aufzulösen, sowie die Konfiguration, veröffentlicht Port 80 und hängt vom app-Service ab. Beide verwenden /app, damit die Pfade auf beiden Seiten von FastCGI übereinstimmen.
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
volumes:
- ./:/app:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- appPersistente Volumes
Container-Dateisysteme sind flüchtig. Benannte Volumes bewahren Datenbankdateien über docker compose down hinaus auf. Bind-Mounts (./:/app) synchronisieren den Host-Quellcode während der Entwicklung live. Verwenden Sie benannte Volumes für zustandsbehaftete Daten und Bind-Mounts für den Quellcode.
services:
db:
image: mysql:8.4
environment:
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootsecret
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata: # survives `down`, removed only by `down -v`Healthchecks und depends_on
depends_on wartet allein nur darauf, dass der Container gestartet wurde, nicht darauf, dass MySQL Verbindungen akzeptiert. Fügen Sie einen healthcheck hinzu und verwenden Sie condition: service_healthy, damit Ihre Anwendung wartet, bis die Datenbank tatsächlich bereit ist.
services:
db:
image: mysql:8.4
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-prootsecret"]
interval: 5s
timeout: 3s
retries: 10
app:
build: .
depends_on:
db:
condition: service_healthy # waits for healthcheck passUmgebung & .env
Compose lädt automatisch eine benachbarte .env-Datei zur Variableninterpolation und übergibt die Anwendungskonfiguration über environment oder env_file. Halten Sie Secrets aus der versionierten Compose-Datei heraus und verweisen Sie stattdessen auf Variablen.
services:
app:
build: .
env_file:
- .env
environment:
DATABASE_URL: "mysql://app:secret@db:3306/app"
REDIS_URL: "redis://redis:6379"
# .env (gitignored) provides ${...} substitutions
# MYSQL_PASSWORD=secretAus PHP verbinden
Innerhalb des Netzwerks sind Hostnamen die Namen der Services. Ihr PHP-Code verbindet sich direkt mit db und redis. Dieser Ausschnitt analysiert eine DSN so, wie es eine Konfigurationsschicht tun würde, und zeigt, wie der Compose-Service-Name in Ihre Verbindungszeichenfolge gelangt.
<?php
$dsn = 'mysql://app:secret@db:3306/app';
$p = parse_url($dsn);
printf("driver: %s\n", $p['scheme']);
printf("host: %s\n", $p['host']); // 'db' resolves via compose DNS
printf("port: %d\n", $p['port']);
printf("db: %s\n", ltrim($p['path'], '/'));
$pdoDsn = sprintf('mysql:host=%s;port=%d;dbname=%s', $p['host'], $p['port'], ltrim($p['path'], '/'));
echo $pdoDsn . PHP_EOL;
?>Xdebug für die lokale Entwicklung
Mounten Sie die Xdebug-Konfiguration nur lokal, und zwar über das dev-Build-Ziel. Setzen Sie client_host auf host.docker.internal, damit der Debugger Ihre IDE auf dem Host erreicht. Liefern Sie Xdebug niemals in die Produktion aus – es beeinträchtigt die Performance erheblich.
; docker/php/xdebug.ini (mounted only in dev)
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003Einmalige Befehle ausführen
docker compose run startet einen flüchtigen Container für Migrationen, Tests oder Composer; exec führt einen Befehl innerhalb eines bereits laufenden Services aus. Verwenden Sie run --rm für solche Aufgaben, damit der Wegwerf-Container bereinigt wird.
# Run migrations against the running db
docker compose exec app php bin/console doctrine:migrations:migrate
# One-off: install deps without a long-lived container
docker compose run --rm app composer install
# Tail logs of just the web service
docker compose logs -f webOverride-Dateien
Compose führt docker-compose.yml und docker-compose.override.yml automatisch zusammen. Halten Sie produktionsnahe Standardwerte in der Basisdatei und legen Sie entwicklungsbezogene Volumes, Ports und Xdebug in der Override-Datei ab – so verwendet CI die Basis und Entwickler erhalten die zusätzlichen Funktionen automatisch.
# docker-compose.override.yml (auto-merged, dev only)
services:
app:
volumes:
- ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini:ro
environment:
APP_ENV: dev
# CI runs: docker compose -f docker-compose.yml up (no override)Kurzprüfung
Warum reicht ein einfaches depends_on: [db] vor dem Ausführen von Migrationen nicht aus?
Zusammenfassung
Sie haben mit Compose einen lokalen Stack zusammengestellt: PHP-FPM hinter nginx (FastCGI zu app:9000), MySQL und Redis über den jeweiligen Service-Namen erreichbar, benannte Volumes für die Persistenz, Healthchecks als Voraussetzung für depends_on, umgebungsvariablenbasierte Konfiguration, Xdebug in einem entwicklungsbezogenen Override und einmalige Befehle über run/exec.
Denken Sie daran: Service-Namen sind DNS-Hostnamen, Override-Dateien halten zusätzliche Entwicklungsfunktionen aus CI heraus und Healthchecks sind einer naiven Startreihenfolge überlegen.
Häufig gestellte Fragen
Ist die Lektion „Docker Compose für lokale Stacks“ kostenlos?
Ja — der vollständige Text von „Docker Compose für lokale Stacks“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Docker Compose für lokale Stacks“?
PHP, eine Datenbank und einen Cache lokal gemeinsam ausführen Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um PHP Academy zu starten?
Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Docker Compose für lokale Stacks“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?
Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Eine PHP-Anwendung containerisieren
- Multi-Stage-Builds und Optimierung
- Docker Compose für lokale Stacks
- CI/CD mit GitHub Actions