mehrere Instanzen lokal testen
Bevor ein Service in Kubernetes oder Docker Swarm mit mehreren Replicas produktiv laeuft, lohnt sich ein lokaler Test mit deploy.replicas in Docker Compose. So lassen sich Port-Konflikte, geteilte Volumes und Lastverteilungsverhalten schon auf dem Entwicklungsrechner aufdecken, statt sie erst nach einem produktiven Rollout zu bemerken.
Inhaltsverzeichnis
- 1. Warum lokale Skalierungstests sinnvoll sind
- 2. deploy.replicas in der compose.yaml definieren
- 3. Die --scale Option fuer spontane Skalierung
- 4. Port-Konflikte bei mehreren Replicas vermeiden
- 5. Lastverteilung mit Nginx als Reverse Proxy
- 6. Geteilte Volumes und Session-Handling bei mehreren Instanzen
- 7. Praxisbeispiel: PHP-FPM Worker horizontal skalieren
- 8. Grenzen von Replicas in Docker Compose gegenueber Swarm und Kubernetes
- 9. Lokale Skalierung im Vergleich zu produktiver Orchestrierung
- 10. Zusammenfassung
- 11. FAQ
1. Warum lokale Skalierungstests sinnvoll sind
Viele Anwendungen werden mit der impliziten Annahme entwickelt, dass immer genau eine Instanz eines Services laeuft. Sobald ein Service in Produktion mit mehreren Replicas hinter einem Load Balancer betrieben wird, zeigen sich Probleme, die im Entwicklungsalltag mit nur einer Instanz nie sichtbar waren: Sessions, die nur im lokalen Speicher eines Containers liegen, Dateien, die auf ein lokales Volume statt auf einen geteilten Storage geschrieben werden, oder Race Conditions bei gleichzeitigem Zugriff auf dieselbe Ressource.
Docker Compose Replicas erlauben es, genau dieses Verhalten schon lokal zu testen, lange bevor ein Service in Kubernetes oder Docker Swarm mit echten Replicas produktiv laeuft. Mit deploy.replicas oder der --scale Option lassen sich mehrere Instanzen desselben Services parallel starten, was Probleme mit zustandsbehafteten Containern, fehlender Lastverteilung oder falsch konfigurierten Shared Resources sichtbar macht, bevor sie in einer produktiven Umgebung zu echten Ausfaellen fuehren.
Der Aufwand fuer diesen Test ist gering im Vergleich zum Nutzen. Ein einzelner Parameter in der compose.yaml oder ein zusaetzliches Flag beim docker compose up Aufruf reicht aus, um dieselbe horizontale Skalierung zu simulieren, die spaeter in Produktion Verwendung findet. Fuer Teams, die ihre Anwendung fuer horizontale Skalierung vorbereiten wollen, ist dieser lokale Test ein guenstiger erster Schritt, bevor teurere Orchestrierungswerkzeuge zum Einsatz kommen.
2. deploy.replicas in der compose.yaml definieren
Der deploy Block in Docker Compose stammt urspruenglich aus dem Docker Swarm Kontext, wird aber auch von der reinen Docker Compose Engine fuer einen Teilbereich seiner Optionen unterstuetzt, darunter replicas. Mit replicas: 3 innerhalb von deploy startet docker compose up drei identische Instanzen desselben Service-Blocks, jede mit eigenem Containernamen, aber identischer Konfiguration bezueglich Image, Umgebungsvariablen und Volumes.
Wichtig zu wissen: Nicht alle deploy Optionen werden von Docker Compose ausserhalb von Swarm unterstuetzt. resources.limits und resources.reservations werden inzwischen respektiert, waehrend andere Swarm-spezifische Optionen wie update_config ignoriert werden. Fuer den reinen Zweck, mehrere Instanzen lokal zu testen, reicht replicas allein vollstaendig aus.
# compose.yaml — running multiple instances of the same service
services:
api:
build: .
deploy:
replicas: 3
environment:
SERVICE_NAME: api
networks:
- backend
networks:
backend:
Ein zentraler Punkt: Ein Service mit replicas darf keine feste host-seitige Portbindung wie "8080:8080" definieren, weil mehrere Container nicht denselben Host-Port gleichzeitig belegen koennen. Docker Compose meldet in diesem Fall einen Fehler beim Start. Fuer skalierte Services muss der Port entweder ganz weggelassen werden, sofern der Zugriff ueber das interne Docker-Netzwerk erfolgt, oder ueber einen Reverse Proxy mit dynamischer Ziel-Erkennung geloest werden.
3. Die --scale Option fuer spontane Skalierung
Neben der statischen Definition in der compose.yaml erlaubt Docker Compose auch eine spontane Skalierung ueber die Kommandozeile mit docker compose up --scale service=anzahl. Dieser Ansatz ist praktisch fuer schnelle Experimente, ohne die compose.yaml selbst aendern zu muessen, und eignet sich besonders fuer temporaere Lasttests, bei denen die Anzahl der Instanzen mehrfach variiert werden soll.
Ein wichtiger Unterschied: Ist in der compose.yaml bereits ein deploy.replicas Wert gesetzt, ueberschreibt die --scale Option diesen Wert fuer den aktuellen Aufruf, ohne die Datei selbst zu veraendern. Das erlaubt es, den Standardwert in der Datei fuer die normale Entwicklung niedrig zu halten, etwa bei 1, und ihn nur bei Bedarf ueber die Kommandozeile fuer einen gezielten Skalierungstest zu erhoehen.
# Scale a service to 5 instances for this run only
docker compose up -d --scale api=5
# Check how many instances are actually running
docker compose ps api
# Scale back down without restarting the whole stack
docker compose up -d --scale api=1
4. Port-Konflikte bei mehreren Replicas vermeiden
Der haeufigste Fehler beim ersten Versuch, einen Service zu skalieren, ist eine feste Portzuordnung wie ports: ["8080:8080"] im betreffenden Service. Sobald replicas groesser als 1 gesetzt wird, versucht Docker Compose, denselben Host-Port fuer mehrere Container zu binden, was unweigerlich fehlschlaegt. Die Loesung besteht darin, entweder komplett auf eine explizite Host-Portbindung zu verzichten und den Service nur ueber das interne Docker-Netzwerk erreichbar zu machen, oder Docker die Portzuordnung dynamisch ueberlassen zu lassen.
Fuer den zweiten Ansatz genuegt es, im ports Eintrag nur den Container-Port ohne festen Host-Port anzugeben, etwa "8080" statt "8080:8080". Docker weist dann fuer jede Replica automatisch einen freien Host-Port zu, der sich per docker compose port oder docker ps ermitteln laesst. Fuer die meisten produktionsnahen Setups ist dieser Ansatz aber weniger relevant, weil der Zugriff ohnehin ueber einen Reverse Proxy erfolgen soll, der die interne Portzuordnung selbst kennt.
# compose.yaml — no fixed host port, safe for multiple replicas
services:
api:
build: .
deploy:
replicas: 3
expose:
- "8080"
networks:
- backend
networks:
backend:
5. Lastverteilung mit Nginx als Reverse Proxy
Damit mehrere Replicas tatsaechlich einen Nutzen bringen, braucht es eine Instanz, die eingehende Anfragen auf die verfuegbaren Container verteilt. In einer lokalen Docker Compose Umgebung uebernimmt diese Rolle typischerweise Nginx als Reverse Proxy, der ueber den internen Docker-DNS-Namen des Service alle laufenden Replicas automatisch erreicht, ohne dass jede einzelne IP-Adresse manuell konfiguriert werden muss.
Docker's eingebauter DNS-Resolver loest den Service-Namen automatisch auf alle laufenden Container-IPs eines skalierten Service auf, was Nginx mit der resolver Direktive und einer Upstream-Definition nutzen kann, um Anfragen im Round-Robin-Verfahren zu verteilen. Dieses Setup simuliert lokal sehr genau, wie ein produktiver Load Balancer vor mehreren Replicas in Kubernetes oder Swarm arbeiten wuerde.
# nginx.conf — load balancing across scaled replicas
upstream api_backend {
# Docker's embedded DNS resolves "api" to all running replica IPs
server api:8080;
}
server {
listen 80;
location / {
proxy_pass http://api_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# compose.yaml — Nginx in front of a scaled API service
services:
api:
build: .
deploy:
replicas: 3
expose:
- "8080"
networks:
- backend
nginx:
image: nginx:1.27-alpine
ports:
- "8000:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- api
networks:
- backend
networks:
backend:
6. Geteilte Volumes und Session-Handling bei mehreren Instanzen
Sobald mehrere Replicas eines Services parallel laufen, wird jede Annahme sichtbar, die implizit von genau einer Instanz ausgegangen ist. Sessions, die im lokalen Dateisystem eines PHP-Containers gespeichert werden, funktionieren nur so lange korrekt, wie derselbe Nutzer wiederholt an dieselbe Instanz weitergeleitet wird. Sobald der Load Balancer eine Anfrage an eine andere Replica weiterleitet, die die Session-Datei nicht kennt, meldet die Anwendung den Nutzer faelschlich als ausgeloggt.
Diese Klasse von Fehlern laesst sich nur durch lokale Skalierungstests zuverlaessig aufdecken, bevor sie in Produktion zu echten Support-Faellen fuehren. Die uebliche Loesung ist, Sessions in einem zentralen Redis-Store statt im lokalen Dateisystem zu speichern, sodass jede Replica auf denselben Session-Zustand zugreifen kann, unabhaengig davon, welche Instanz eine bestimmte Anfrage tatsaechlich verarbeitet. Aehnliches gilt fuer hochgeladene Dateien, die entweder auf einem geteilten Volume oder in einem Objektspeicher liegen muessen, statt lokal in einem einzelnen Container-Dateisystem.
7. Praxisbeispiel: PHP-FPM Worker horizontal skalieren
Fuer PHP-Anwendungen, insbesondere Magento-Shops mit hoher Anfragenlast, ist das Testen mehrerer PHP-FPM Replicas ein direkter Weg, um zu pruefen, ob die Anwendung tatsaechlich zustandslos arbeitet. Ein PHP-FPM Service ohne feste Portbindung, kombiniert mit Redis fuer Sessions und Full-Page-Cache sowie einem geteilten Volume oder Objektspeicher fuer Media-Dateien, laesst sich problemlos mit deploy.replicas: 3 lokal hochskalieren.
Ein solcher Test deckt zuverlaessig auf, ob noch Annahmen im Code existieren, die von genau einer Instanz ausgehen, etwa lokales File-Caching ausserhalb von Redis, In-Memory-Zaehler ohne zentrale Synchronisation, oder Cron-Jobs, die bei mehreren Replicas versehentlich mehrfach parallel laufen und doppelte Verarbeitung ausloesen. Fuer Cron-Jobs empfiehlt sich in einem skalierten Setup ein dedizierter Service mit genau einer Replica, waehrend die Web-Worker selbst frei skalieren koennen.
8. Grenzen von Replicas in Docker Compose gegenueber Swarm und Kubernetes
Docker Compose Replicas eignen sich hervorragend fuer lokale Tests, sind aber kein vollwertiger Ersatz fuer eine produktive Orchestrierungsplattform. Docker Compose bringt keine automatische Healthcheck-basierte Neuverteilung mit, wenn eine Replica ausfaellt, keine automatische horizontale Skalierung basierend auf Last, und keine Verteilung ueber mehrere physische Hosts hinweg. Alle Replicas laufen auf derselben Docker Engine, meistens demselben Entwicklungsrechner oder demselben CI-Runner.
Fuer produktive Umgebungen mit echten Anforderungen an Ausfallsicherheit, automatische Skalierung und Verteilung ueber mehrere Nodes bleiben Kubernetes oder Docker Swarm die passenden Werkzeuge. Docker Compose Replicas sind dafuer gedacht, das grundlegende Skalierungsverhalten einer Anwendung fruehzeitig und guenstig zu testen, nicht dafuer, eine vollstaendige produktive Orchestrierung zu ersetzen.
9. Lokale Skalierung im Vergleich zu produktiver Orchestrierung
Der Vergleich zwischen lokalen Docker Compose Replicas und einer produktiven Orchestrierungsplattform zeigt deutlich, wofuer jeder Ansatz gedacht ist und wo die jeweiligen Grenzen liegen.
| Faehigkeit | Docker Compose Replicas | Docker Swarm | Kubernetes |
|---|---|---|---|
| Mehrere Instanzen starten | Ja, lokal | Ja | Ja |
| Ueber mehrere Hosts verteilen | Nein | Ja | Ja |
| Automatische Neuverteilung bei Ausfall | Nein | Ja | Ja |
| Automatische Skalierung nach Last | Nein | Eingeschraenkt | Ja (HPA) |
| Setup-Aufwand fuer einen Test | Minimal | Mittel | Hoch |
Fuer die reine Frage, ob eine Anwendung ueberhaupt korrekt mit mehreren gleichzeitigen Instanzen umgehen kann, ist der minimale Setup-Aufwand von Docker Compose Replicas ein klarer Vorteil gegenueber Swarm oder Kubernetes. Sobald die Anwendung dieses Verhalten nachweislich beherrscht, ist der Wechsel zu einer echten Orchestrierungsplattform der naechste logische Schritt fuer produktive Ausfallsicherheit und Skalierung ueber mehrere Hosts.
Mironsoft
Docker-Skalierungstests und Magento-Performance
Wisst ihr, ob euer Shop wirklich horizontal skaliert?
Wir testen bestehende Magento- und PHP-Stacks lokal mit mehreren Replicas, decken zustandsbehaftete Annahmen auf und bereiten Anwendungen auf produktive Skalierung vor.
Skalierungstest
deploy.replicas lokal einrichten und Session- sowie Storage-Probleme identifizieren
Lastverteilung
Nginx Reverse Proxy fuer skalierte Services konfigurieren und pruefen
Produktions-Readiness
Redis-Sessions, Objektspeicher und dedizierte Cron-Services einrichten
10. Zusammenfassung
Docker Compose Replicas machen es moeglich, das Skalierungsverhalten einer Anwendung schon lokal zu testen, lange bevor ein Service produktiv in Kubernetes oder Docker Swarm mit mehreren Instanzen laeuft. Mit deploy.replicas in der compose.yaml oder der spontanen --scale Option lassen sich mehrere Container derselben Konfiguration parallel starten, was Probleme mit Sessions, geteilten Volumes und fehlender Lastverteilung fruehzeitig sichtbar macht.
Fuer echte Lastverteilung braucht es zusaetzlich einen Reverse Proxy wie Nginx, der Docker's internen DNS-Resolver nutzt, um Anfragen automatisch auf alle laufenden Replicas zu verteilen. Wichtig bleibt, dass Docker Compose Replicas kein Ersatz fuer eine vollwertige Orchestrierungsplattform sind, weil weder automatische Neuverteilung bei Ausfall noch Verteilung ueber mehrere Hosts unterstuetzt werden. Fuer den fruehen, guenstigen Test des Skalierungsverhaltens einer Anwendung ist der Ansatz aber genau richtig.
Docker Compose Replicas — Das Wichtigste auf einen Blick
deploy.replicas
Statische Definition der Instanzanzahl in der compose.yaml, ideal fuer wiederholbare Tests.
--scale Option
Spontane Skalierung ueber die Kommandozeile, ueberschreibt den Wert aus der Datei fuer den aktuellen Lauf.
Keine feste Portbindung
Skalierte Services duerfen keinen festen Host-Port belegen, expose statt ports verwenden.
Zustandslosigkeit pruefen
Sessions und Uploads muessen zentral in Redis oder Objektspeicher liegen, nicht lokal im Container.