Docker · Redis · RabbitMQ · OpenSearch · MySQL
Redis, RabbitMQ, OpenSearch und MySQL
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.

14 Min. Lesezeit Redis · RabbitMQ · OpenSearch · MySQL · Health-Checks Magento 2.4 · Docker Compose · Persistente Volumes

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.

11. FAQ: Redis, RabbitMQ, OpenSearch und MySQL in Docker-Stacks

1PHP-FPM verbindet sich nicht mit MySQL beim ersten Start?
MySQL braucht Zeit für Initialisierung. depends_on ohne condition wartet nur auf Container-Start. depends_on: condition: service_healthy + mysqladmin ping Health-Check löst das.
2OpenSearch startet nicht in Docker?
vm.max_map_count zu niedrig – mindestens 262144 nötig. sysctl -w vm.max_map_count=262144 auf Linux. Docker Desktop setzt den Wert automatisch.
3Redis für Cache und Sessions in einer Instanz?
Nicht empfohlen. allkeys-lru evictet Sessions. Zwei getrennte Instanzen: Cache mit lru, Sessions mit noeviction + AOF.
4RabbitMQ braucht persistentes Volume?
Ja, immer. Ohne Volume: verlorene Queue-Nachrichten bei Neustart. /var/lib/rabbitmq muss persistent sein – sonst Bestelldaten-Verlust möglich.
5Service-Namen in Magento env.php?
Compose-Service-Name = Hostname im Netzwerk. mysql → host: mysql, redis → host: redis. Docker DNS löst diese Namen automatisch auf.
6Was ist start_period im Health-Check?
Zusätzliche Zeit beim Start bevor Failures als unhealthy gewertet werden. MySQL 30s, OpenSearch 60s. Verhindert zu frühes unhealthy-Marking.
7OpenSearch-Status überprüfen?
curl http://localhost:9200/_cluster/health. Status green/yellow = ok, red = Problem. Im Container: curl -s http://localhost:9200/_cat/indices für Index-Liste.
8MySQL-Port im Produktions-Stack exponieren?
Nein. Sicherheitsrisiko. MySQL bleibt im internen Netzwerk. SSH-Tunnel für externen Zugriff. Dev-Port nur in compose.dev.yaml.
9MySQL-Daten zwischen Volumes migrieren?
mysqldump im Container für SQL-Dump. alpine-Container mit beiden Volumes für direktes Volume-Kopieren mit cp -av. Dann Volume auf neuen Host transferieren.
10RAM-Bedarf für vollständigen Magento Docker Stack?
Minimal ca. 3 GB: MySQL 512MB, OpenSearch 1GB, Redis 512MB, RabbitMQ 256MB, PHP-FPM 512MB. Empfohlen: 8 GB für komfortables Arbeiten auf macOS.