in Docker-Stacks sauber verbinden
Ein Magento-Docker-Stack besteht aus mindestens fünf Services: PHP-FPM, Nginx, MySQL, Redis und OpenSearch. Dazu kommen RabbitMQ für Message Queues und Varnish für Full-Page-Cache. Wie diese Services korrekt vernetzt, persistent gespeichert und in der richtigen Reihenfolge gestartet werden, entscheidet über Stabilität und Wartbarkeit.
Inhaltsverzeichnis
- 1. Die Service-Architektur eines Magento-Docker-Stacks
- 2. MySQL in Docker: Volumes, Init-Scripts und Health-Checks
- 3. Redis in Docker: Cache, Sessions und Persistent Mode
- 4. OpenSearch in Docker: Memory-Limits und Indexierung
- 5. RabbitMQ in Docker: Virtual Hosts und Management-UI
- 6. Startup-Reihenfolge mit Health-Checks steuern
- 7. Netzwerksegmentierung im Multi-Service-Stack
- 8. Connection-Konfiguration in Magento env.php
- 9. Service-Konfigurationen im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Die Service-Architektur eines Magento-Docker-Stacks
Ein vollständiger Magento Docker Stack besteht aus einer Reihe von Services, die zusammenarbeiten müssen, aber unterschiedliche Eigenschaften haben. MySQL ist stateful und braucht persistente Volumes, Warm-up-Zeit beim ersten Start und Health-Checks, bevor andere Services verbinden. Redis ist sowohl Cache als auch Session-Store und kann je nach Konfiguration persistent oder flüchtig betrieben werden. OpenSearch benötigt spezifische Kernel-Parameter (vm.max_map_count) und erheblich mehr RAM als die anderen Services. RabbitMQ verwaltet Message Queues für asynchrone Magento-Operationen wie Inventory-Updates und Newsletter-Versand.
Das zentrale Problem beim Verbinden dieser Services in einem Magento Docker Stack ist die Startup-Reihenfolge. Docker Compose startet alle Services theoretisch parallel. PHP-FPM versucht, sich mit MySQL zu verbinden, bevor MySQL vollständig initialisiert ist – was zu Verbindungsfehlern beim ersten Start führt. Health-Checks in Kombination mit depends_on: condition: service_healthy lösen das Problem: PHP-FPM startet erst, wenn MySQL als gesund gemeldet wird. Diese Startsequenz muss für jeden Service im Stack explizit konfiguriert werden.
2. MySQL in Docker: Volumes, Init-Scripts und Health-Checks
MySQL im Magento Docker Stack braucht zwingend ein persistentes benanntes Volume für die Datenbankdateien. Ohne Volume gehen alle Daten bei jedem docker compose down verloren. Das Volume muss bei der allerersten Initialisierung korrekt belegt werden: MySQL wartet beim Start auf Initialisierung, was mehrere Sekunden dauern kann. Der Health-Check mit mysqladmin ping stellt sicher, dass andere Services erst verbinden, wenn MySQL wirklich bereit ist – nicht nur wenn der Container gestartet ist.
Init-Scripts für MySQL in einem Magento Docker Stack werden im Verzeichnis /docker-entrypoint-initdb.d/ abgelegt. Alle dort platzierten SQL- und Shell-Dateien werden beim allerersten Start ausgeführt – wenn das Daten-Volume noch leer ist. Das ist der richtige Ort für das Erstellen der Magento-Datenbank, das Setzen des Zeichensatzes und das Anlegen von Datenbankbenutzern. Bei einem späteren docker compose down && docker compose up mit bestehendem Volume werden diese Init-Scripts nicht mehr ausgeführt – was korrekt ist.
# compose.yaml — MySQL, Redis, OpenSearch, RabbitMQ for Magento stack
services:
mysql:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
MYSQL_DATABASE: magento
MYSQL_USER: magento
MYSQL_PASSWORD: "${MYSQL_PASSWORD}"
volumes:
- mysql-data:/var/lib/mysql
- ./env/mysql/conf.d:/etc/mysql/conf.d:ro
- ./env/mysql/init:/docker-entrypoint-initdb.d:ro
networks:
- db
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "--password=${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s # Give MySQL time to initialize on first start
restart: unless-stopped
redis:
image: redis:7.4-alpine
command: >
redis-server
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--save 60 1000
--appendonly no
volumes:
- redis-data:/data
networks:
- db
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
restart: unless-stopped
3. Redis in Docker: Cache, Sessions und Persistent Mode
Redis im Magento Docker Stack übernimmt zwei Rollen: Full-Page-Cache-Backend und Session-Speicher. Magento kann Redis für beide Verwendungszwecke konfigurieren, aber die Konfigurationsparameter sollten für beide Rollen unterschiedlich sein. Der Cache-Store kann mit einer aggressiven Eviction-Policy (allkeys-lru) und ohne Persistenz betrieben werden – der Cache kann jederzeit aus dem Backend neu aufgebaut werden. Der Session-Store hingegen braucht Persistenz: Sessions müssen einen Container-Neustart überleben, sonst werden alle eingeloggten Benutzer abgemeldet.
Die sauberste Lösung für den Magento Docker Stack sind zwei Redis-Instanzen: eine für Cache mit --maxmemory-policy allkeys-lru und ohne RDB-Persistenz, eine für Sessions mit --maxmemory-policy noeviction und aktiviertem AOF (Append-Only-File) für Persistenz. Das erhöht die Ressourcenanforderungen leicht, aber eliminiert das Risiko, dass Cache-Eviction eine Session löscht oder Session-Schreibvorgänge die Cache-Performance beeinträchtigen. In der Konfiguration werden dann beide Redis-Instanzen in env.php als separate Backends eingetragen.
4. OpenSearch in Docker: Memory-Limits und Indexierung
OpenSearch im Magento Docker Stack ist der ressourcenintensivste Service. Es braucht mindestens 1 GB Heap-Speicher für eine kleine Magento-Installation, und der Kernel-Parameter vm.max_map_count muss auf mindestens 262144 gesetzt sein. Ohne diesen Parameter startet OpenSearch nicht. Auf Linux-Hosts wird der Parameter mit sysctl -w vm.max_map_count=262144 gesetzt und in /etc/sysctl.conf persistent gemacht. Auf Docker-Desktop-Systemen (macOS, Windows) betreibt die VM diesen Parameter bereits, weshalb OpenSearch dort auch ohne explizite Konfiguration startet.
Im Magento Docker Stack sollte OpenSearch mit expliziten Memory-Limits konfiguriert werden: ES_JAVA_OPTS: "-Xms512m -Xmx512m" für die JVM-Heap-Größe. Diese beiden Werte sollten identisch sein – OpenSearch soll den Heap beim Start vollständig allozieren und nicht dynamisch skalieren. Im Entwicklungsmodus wird OpenSearch als Single-Node-Cluster betrieben (discovery.type: single-node) und die Security-Features können für lokale Entwicklung deaktiviert werden. In der Produktion ist Security obligatorisch.
# OpenSearch and RabbitMQ service definitions for Magento Docker stack
services:
opensearch:
image: opensearchproject/opensearch:2.18
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
# Disable security for local development only
- DISABLE_SECURITY_PLUGIN=true
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data:/usr/share/opensearch/data
networks:
- db
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health | grep -qv '\"status\":\"red\"'"]
interval: 15s
timeout: 10s
retries: 12
start_period: 60s # OpenSearch needs significant startup time
restart: unless-stopped
rabbitmq:
image: rabbitmq:3.13-management-alpine
environment:
RABBITMQ_DEFAULT_USER: "${RABBITMQ_USER:-magento}"
RABBITMQ_DEFAULT_PASS: "${RABBITMQ_PASSWORD}"
RABBITMQ_DEFAULT_VHOST: "magento"
volumes:
- rabbitmq-data:/var/lib/rabbitmq
networks:
- db
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
restart: unless-stopped
# Expose management UI only in development
ports:
- "15672:15672" # Management UI — remove in production
5. RabbitMQ in Docker: Virtual Hosts und Management-UI
RabbitMQ im Magento Docker Stack verwaltet Message Queues für asynchrone Magento-Verarbeitung. Magento nutzt RabbitMQ für Inventory-Reservierungen bei Bestellungen, asynchrone Produktupdates über die Bulk-API und Newsletter-Versand. Ohne RabbitMQ werden diese Operationen synchron verarbeitet, was bei hohem Traffic zu Timeouts führt. RabbitMQ braucht wie MySQL ein persistentes Volume, damit Queue-Nachrichten einen Container-Neustart überleben.
Die RabbitMQ-Konfiguration für den Magento Docker Stack umfasst einen dedizierten Virtual Host für Magento (RABBITMQ_DEFAULT_VHOST=magento), eigene Credentials und ein persistentes Daten-Volume. Das Management-UI auf Port 15672 ist ein nützliches Werkzeug für die Entwicklung, um Queue-Tiefen, unverarbeitete Nachrichten und Consumer-Status zu beobachten. In der Produktion sollte der Management-UI-Port nicht auf den Host exponiert werden oder durch eine zusätzliche Authentifizierungsschicht geschützt sein.
6. Startup-Reihenfolge mit Health-Checks steuern
Die Startup-Reihenfolge im Magento Docker Stack ist eine der häufigsten Fehlerquellen bei neuen Docker-Setups. depends_on: mysql wartet nur, bis der MySQL-Container gestartet ist – nicht bis MySQL bereit für Verbindungen ist. Die korrekte Lösung ist depends_on: condition: service_healthy, das erst weitermacht, wenn der Health-Check des abhängigen Services healthy zurückmeldet. Das setzt voraus, dass jeder Service im Stack einen Health-Check konfiguriert hat.
Im Magento Docker Stack bedeutet die optimale Startup-Reihenfolge: Zuerst MySQL, Redis und OpenSearch starten und auf healthy warten. Dann RabbitMQ starten. Dann PHP-FPM, das von allen Datenbankservices abhängt. Zuletzt Nginx, das von PHP-FPM abhängt. Der start_period im Health-Check gibt Services zusätzliche Zeit beim allerersten Start – OpenSearch braucht deutlich länger als Redis. Diese Konfiguration verhindert Connection-Fehler beim Stack-Start und macht den ersten docker compose up zuverlässig.
# Startup order using health checks — PHP-FPM waits for all backends
services:
phpfpm:
build:
context: .
target: phpfpm
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
opensearch:
condition: service_healthy
rabbitmq:
condition: service_healthy
networks:
- backend
- db
healthcheck:
test: ["CMD-SHELL", "php-fpm-healthcheck || exit 1"]
interval: 10s
timeout: 5s
retries: 5
nginx:
image: nginx:1.27-alpine
depends_on:
phpfpm:
condition: service_healthy
networks:
- frontend
- backend
ports:
- "80:80"
- "443:443"
volumes:
mysql-data:
redis-data:
redis-session-data: # Separate volume for session Redis instance
opensearch-data:
rabbitmq-data:
7. Netzwerksegmentierung im Multi-Service-Stack
Im Magento Docker Stack mit fünf oder mehr Services ist Netzwerksegmentierung nicht optional, sondern notwendige Praxis. MySQL, Redis, OpenSearch und RabbitMQ gehören ins interne Datenbank-Netzwerk mit internal: true. Das verhindert, dass diese Services ausgehende Verbindungen ins Internet aufbauen können, und verhindert den direkten Zugriff vom Host oder Frontend-Netzwerk. PHP-FPM ist im Backend-Netzwerk (erreichbar für Nginx) und im DB-Netzwerk (erreichbar für alle Datenbankservices). Nginx ist im Frontend-Netzwerk mit einem Host-Port und im Backend-Netzwerk für PHP-FPM.
Eine wichtige Ausnahme im Magento Docker Stack: Das RabbitMQ-Management-UI und manchmal MySQL brauchen in der Entwicklung direkte Host-Port-Mappings, damit Entwickler Datenbanktools wie TablePlus oder den RabbitMQ-Browser nutzen können. Diese Ports werden nur in der compose.dev.yaml definiert, nicht in der Produktions-Compose-Datei. Das Pattern: Basisinfrastruktur ohne Host-Ports, Development-Override fügt die benötigten Ports hinzu.
8. Connection-Konfiguration in Magento env.php
Die Verbindungskonfiguration für alle Services im Magento Docker Stack landet in app/etc/env.php. Alle Service-Hostnamen entsprechen den Compose-Service-Namen, weil Docker's eingebetteter DNS diese Namen innerhalb des Netzwerks auflöst. MySQL wird als mysql referenziert, Redis als redis, OpenSearch als opensearch, RabbitMQ als rabbitmq. Keine festen IP-Adressen, keine Port-Weiterleitungen auf den Host – direkte Container-zu-Container-Kommunikation über das interne Netzwerk.
Für den Magento Docker Stack in der Entwicklung ist es sinnvoll, env.php nicht ins Git-Repository zu versionieren, sondern eine env.php.sample mit den Docker-Service-Namen als Vorlage bereitzustellen. Ein Setup-Skript kopiert die Sample-Datei und passt die Credentials aus den Umgebungsvariablen an. Das ermöglicht einfaches Onboarding neuer Entwickler: docker compose up starten, Setup-Skript ausführen, fertig – alle Service-Verbindungen sind automatisch korrekt konfiguriert.
9. Service-Konfigurationen im direkten Vergleich
Die richtige Konfiguration jedes Services im Magento Docker Stack hat direkte Auswirkungen auf Stabilität und Performance. Die Tabelle zeigt die kritischsten Parameter für jeden Service.
| Service | Persistenz | Health-Check | Kritischer Parameter |
|---|---|---|---|
| MySQL 8.4 | Obligatorisch | mysqladmin ping | start_period: 30s |
| Redis (Cache) | Optional | redis-cli ping | allkeys-lru Eviction |
| Redis (Sessions) | Obligatorisch | redis-cli ping | noeviction + AOF |
| OpenSearch 2.x | Empfohlen | cluster/health API | vm.max_map_count, 1GB Heap |
| RabbitMQ 3.13 | Obligatorisch | rabbitmq-diagnostics ping | Virtual Host für Magento |
Alle Services im Magento Docker Stack brauchen persistente Volumes in der Produktion. In der Entwicklung können Redis-Cache-Volumes weggelassen werden, weil der Cache nach einem Neustart schnell wieder aufgebaut wird. MySQL-, RabbitMQ- und Session-Redis-Volumes müssen in jedem Umfeld persistent sein. OpenSearch-Volumes sind empfohlen, weil die Neuindexierung Zeit kostet – besonders bei großen Produktkatalogen.
Mironsoft
Magento-Docker-Stacks, Service-Konfiguration und Production-Ready-Infrastruktur
Magento-Docker-Stack sauber aufbauen?
Wir entwerfen und implementieren euren vollständigen Magento-Docker-Stack mit Redis, RabbitMQ, OpenSearch und MySQL – inklusive Health-Checks, Netzwerksegmentierung und persistenten Volumes.
Stack-Design
Vollständige Compose-Konfiguration mit allen Magento-Services und korrekter Startup-Reihenfolge
Health-Checks
Korrekte Health-Check-Konfiguration für jeden Service mit service_healthy depends_on
Production-Hardening
Netzwerksegmentierung, Secrets-Management und Ressourcenlimits für den Produktionsbetrieb
10. Zusammenfassung
Einen Magento Docker Stack mit Redis, RabbitMQ, OpenSearch und MySQL sauber zu verbinden erfordert drei Dinge: persistente Volumes für alle stateful Services, Health-Checks für jede Datenbank-Service-Instanz und korrekte depends_on: condition: service_healthy-Konfiguration für die Startup-Reihenfolge. Netzwerksegmentierung mit internal: true für das Datenbank-Netzwerk verhindert unnötige Exposition und dokumentiert gleichzeitig die erlaubten Kommunikationspfade.
Redis in zwei Instanzen – eine für Cache, eine für Sessions – verhindert gegenseitige Beeinträchtigung. OpenSearch braucht vm.max_map_count und ausreichend Heap-Speicher. RabbitMQ braucht einen eigenen Virtual Host für Magento. MySQL braucht einen start_period-Puffer im Health-Check für die Initialisierung. Alle Service-Hostnamen in env.php entsprechen den Compose-Service-Namen – Docker's eingebettetes DNS erledigt die Auflösung. Das Ergebnis ist ein Magento Docker Stack, der beim ersten docker compose up zuverlässig startet und im Betrieb stabil bleibt.
Redis, RabbitMQ, OpenSearch, MySQL in Docker — Das Wichtigste auf einen Blick
Startup-Reihenfolge
depends_on: condition: service_healthy statt depends_on ohne Bedingung. Jeder Service braucht einen Health-Check. start_period gibt Zeit für Initialisierung.
Persistente Volumes
MySQL, RabbitMQ und Session-Redis brauchen zwingend persistente Volumes. Cache-Redis optional. OpenSearch-Volume spart Neuindexierungszeit.
Redis-Trennung
Zwei Redis-Instanzen: Cache mit allkeys-lru, Sessions mit noeviction + AOF-Persistenz. Verhindert Eviction von Sessions durch Cache-Druck.
OpenSearch-Anforderungen
vm.max_map_count=262144 auf dem Host. Mindestens 512 MB Heap. discovery.type=single-node für Entwicklung. start_period: 60s im Health-Check.