Docker · Magento 2 · PHP-FPM · Nginx · Elasticsearch · MariaDB
Docker für Magento
PHP-FPM, Nginx, Node, Elasticsearch und DB

Magento 2 braucht einen präzise abgestimmten Service-Stack. PHP-FPM, Nginx, MariaDB, Redis, Elasticsearch oder OpenSearch und einen Node-Container für Frontend-Builds – jeder dieser Services hat spezifische Konfigurationsanforderungen, die in Docker nicht identisch zur klassischen Server-Installation sind. Wer diese Unterschiede kennt, baut einen stabilen und performanten Magento-Docker-Stack.

16 Min. Lesezeit PHP 8.4-FPM · Nginx · MariaDB 11 · Redis 7 · OpenSearch 2 Magento 2.4.8 · Hyvä Themes

1. Der Magento-Stack: Warum so viele Services

Docker für Magento erfordert mehr Services als eine typische PHP-Anwendung. Magento 2.4 läuft nicht ohne eine Suchmaschine – Elasticsearch oder OpenSearch ist Pflicht für den Catalog Search. Redis ist zwar technisch optional, aber in der Praxis unverzichtbar für Session-Speicher und den Full Page Cache: ohne Redis skaliert Magento auch bei moderatem Traffic nicht. MariaDB oder MySQL ist der primäre Datenspeicher. PHP-FPM verarbeitet Requests hinter Nginx. Und für Hyvä-Themes braucht man einen Node-Container, der Tailwind CSS kompiliert. Der vollständige Stack umfasst damit mindestens sechs Container.

Der wichtigste Grundsatz beim Docker-Magento-Setup: jeder Service ist für genau eine Aufgabe zuständig. PHP-FPM verarbeitet PHP, Nginx liefert statische Dateien direkt aus und proxied PHP-Requests. MariaDB speichert Daten, Redis cached. Diese Trennung ermöglicht es, jeden Service unabhängig zu skalieren und zu konfigurieren. Der häufigste Fehler ist ein kombinierter PHP+Nginx-Container – der verhindert unabhängige Skalierung und macht Health-Checks schwieriger. Mit Docker für Magento lässt sich die Trennung konsequent durchsetzen.

2. PHP-FPM richtig konfigurieren

PHP-FPM im Docker-Magento-Setup benötigt eine spezifische Konfiguration, die sich von der Standard-Debian/Ubuntu-Installation unterscheidet. Der PHP-FPM-Container muss auf Port 9000 oder via Unix-Socket hören – in Docker ist der TCP-Port einfacher, weil Socket-Dateien über gemeinsame Volumes geteilt werden müssen. Die wichtigsten PHP-Einstellungen für Magento sind: memory_limit mindestens 2G für Magento-Operationen wie setup:di:compile, max_execution_time mindestens 1800 für lange CLI-Prozesse und opcache muss aktiviert und für Production korrekt dimensioniert sein.

Für Hyvä-Themes mit Docker für Magento und PHP 8.4 sind zusätzliche Extensions nötig: bcmath, gd, intl, pdo_mysql, soap, xsl und zip. Diese Extensions müssen im Dockerfile des PHP-FPM-Images installiert sein. Der Mark Shust Docker-Magento-Stack nutzt ein vorkonfiguriertes Image, das alle Magento-Extensions enthält – für eigene Images empfiehlt sich dasselbe als Basis. Xdebug gehört nur ins Entwicklungs-Image und sollte per Override aktiv geschaltet werden, nicht in der Basis-Konfiguration.


# Docker Compose service definitions for a complete Magento 2 stack
# Each service has a single responsibility — PHP processes PHP, Nginx serves static files

services:
  phpfpm:
    image: markoshust/magento-php:8.4-fpm-0
    networks: [magento]
    volumes:
      - magento_src:/var/www/html          # shared source volume
      - ./src/app/etc/php.ini.sample:/usr/local/etc/php/conf.d/99-magento.ini:ro
    environment:
      MAGENTO_RUN_MODE: production
      PHP_MEMORY_LIMIT: 2G
      PHP_MAX_EXECUTION_TIME: 1800
      PHP_OPCACHE_ENABLE: 1
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
      opensearch:
        condition: service_healthy
    restart: unless-stopped

  nginx:
    image: markoshust/magento-nginx:1.24-0
    networks: [magento]
    ports:
      - "80:8000"
      - "443:8443"
    volumes:
      - magento_src:/var/www/html:ro       # read-only for static file serving
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - phpfpm
    restart: unless-stopped

  # CLI container for Magento commands — same image as phpfpm, different purpose
  cli:
    image: markoshust/magento-php:8.4-fpm-0
    networks: [magento]
    volumes:
      - magento_src:/var/www/html
    command: ["tail", "-f", "/dev/null"]   # keep container running for exec
    profiles: [cli]                        # only start when explicitly needed

3. Nginx als Magento-Frontend-Proxy

Nginx im Docker-Magento-Setup hat zwei Aufgaben: statische Dateien direkt aus dem Dateisystem ausliefern und PHP-Requests an PHP-FPM weiterleiten. Die Nginx-Konfiguration für Magento ist komplex – Magento liefert eine offizielle nginx.conf.sample, die als Ausgangspunkt dient. Die wichtigsten Anpassungen für Docker für Magento: das fastcgi_pass-Directive muss auf den PHP-FPM-Container-Namen zeigen (phpfpm:9000 statt eines Unix-Sockets), und der root-Pfad muss mit dem Volume-Mount-Pfad übereinstimmen.

Ein häufiger Fehler im Docker-Magento-Nginx-Setup: das statische Content-Verzeichnis /pub/static ist nicht im Nginx-Container vorhanden, weil nur PHP-FPM Zugriff auf das Source-Volume hat. Die Lösung ist, das gemeinsame Volume sowohl in PHP-FPM als auch in Nginx zu mounten – in Nginx read-only, in PHP-FPM read-write. Das erfordert ein benanntes Docker-Volume statt eines Host-Pfad-Mounts, damit beide Container auf denselben Dateistand zugreifen. Gzip-Kompression für JS, CSS und HTML sollte in der Nginx-Konfiguration aktiviert sein – das reduziert die übertragene Datenmenge bei Hyvä-Themes erheblich.

4. MariaDB: Performance und Healthcheck

MariaDB im Docker-Magento-Stack braucht eine spezifische Konfiguration, die über das Standard-Image hinausgeht. Die wichtigsten InnoDB-Parameter für Magento: innodb_buffer_pool_size sollte 70–80% des verfügbaren RAM betragen, innodb_log_file_size mindestens 256M, max_allowed_packet mindestens 64M für große Magento-Importe. Diese Werte als Umgebungsvariablen oder als Custom-Config-Datei via Volume-Mount zu übergeben, ist besser als das Image zu erweitern – so bleiben Updates einfach.

Der Healthcheck für MariaDB in Docker für Magento ist entscheidend, weil PHP-FPM und Nginx erst dann starten sollten, wenn die Datenbank bereit ist. Der offizielle MariaDB-Container enthält ein healthcheck.sh-Script, das genau dafür gedacht ist. Mit depends_on: condition: service_healthy in PHP-FPM und anderen Services, die die Datenbank benötigen, wird sichergestellt, dass der Startup-Reihenfolge korrekt eingehalten wird. Ohne diesen Mechanismus starten Services parallel und schlagen fehl, wenn die Datenbank noch initialisiert wird.


# Database and caching services for Docker Magento
# MariaDB with performance tuning, Redis for two separate roles

  db:
    image: mariadb:11.4
    networks: [magento]
    volumes:
      - db_data:/var/lib/mysql
      - ./mysql/conf.d:/etc/mysql/conf.d:ro   # custom InnoDB config
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: magento
      MYSQL_USER: magento
      MYSQL_PASSWORD: ${DB_PASSWORD}
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    restart: unless-stopped

  # mysql/conf.d/magento.cnf — InnoDB tuning for Magento workloads
  # [mysqld]
  # innodb_buffer_pool_size = 2G
  # innodb_log_file_size = 256M
  # max_allowed_packet = 64M
  # innodb_flush_log_at_trx_commit = 2     # faster, slight durability trade-off

  redis:
    image: redis:7-alpine
    networks: [magento]
    command: ["redis-server", "--maxmemory", "512mb", "--maxmemory-policy", "allkeys-lru"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    restart: unless-stopped

  # Separate Redis instance for session storage (isolated from page cache)
  redis-session:
    image: redis:7-alpine
    networks: [magento]
    command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "noeviction"]
    restart: unless-stopped

5. Redis: Session und Full Page Cache

Redis im Docker-Magento-Setup erfüllt zwei verschiedene Rollen: Full Page Cache und Session-Speicher. Diese beiden Anwendungsfälle haben unterschiedliche Eviction-Policies und sollten idealerweise getrennte Instanzen nutzen. Für den Full Page Cache ist allkeys-lru korrekt – alte Seiten werden verdrängt, wenn der Speicher voll ist. Für Sessions ist noeviction richtig – Sessions dürfen niemals automatisch gelöscht werden, weil das zu unerwarteten Logouts führt. Zwei separate Redis-Container in Docker für Magento sind einfach zu konfigurieren und vermeiden dieses Problem vollständig.

Magento 2.4 nutzt Redis über die env.php-Konfiguration. In einem Docker-Magento-Setup sollten die Redis-Hosts auf die Compose-Service-Namen zeigen: 'host' => 'redis' für den Page-Cache und 'host' => 'redis-session' für Sessions. Wichtig: Redis persistiert Daten standardmäßig nicht. Für Produktionsumgebungen sollte redis.conf mit appendonly yes und einem Volume für das AOF-File konfiguriert werden. In der Entwicklung ist Persistenz optional – ein Redis-Neustart ist schnell, und der Cache wird automatisch neu aufgebaut.

6. Elasticsearch und OpenSearch: Catalog Search

Elasticsearch oder OpenSearch im Docker-Magento-Stack ist der ressourcenhungrigste Service. Elasticsearch benötigt mindestens 1 GB Heap, OpenSearch mindestens 512 MB. Der häufigste Fehler ist die fehlende Einstellung vm.max_map_count auf dem Host: Elasticsearch bricht mit einem OutOfMemoryError ab, wenn dieser Kernel-Parameter nicht auf mindestens 262144 gesetzt ist. In Docker Desktop auf macOS und Windows wird dieser Wert automatisch gesetzt, auf Linux-Hosts muss er manuell gesetzt werden: sysctl -w vm.max_map_count=262144.

Magento 2.4.8 unterstützt OpenSearch 2.x als bevorzugte Alternative zu Elasticsearch 7. Der Docker-Magento-Stack sollte OpenSearch nutzen, da Elasticsearch 7 das EOL-Datum überschritten hat. Die Konfiguration in Magento erfolgt über den Admin unter Stores → Configuration → Catalog Search. Im Docker-Setup ist der Host einfach der Compose-Service-Name (opensearch), der Port 9200. Der Healthcheck für OpenSearch überprüft die Cluster-Health-API – Service-Status green oder yellow ist akzeptabel, red bedeutet, dass Shards fehlen.


# OpenSearch service for Magento 2.4 catalog search
# Elasticsearch has reached EOL — use OpenSearch 2.x instead

  opensearch:
    image: opensearchproject/opensearch:2.13.0
    networks: [magento]
    volumes:
      - opensearch_data:/usr/share/opensearch/data
    environment:
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.type=single-node"
      - "plugins.security.disabled=true"   # disable auth for local dev
      - "DISABLE_PERFORMANCE_ANALYZER_AGENT_CLI=true"
    healthcheck:
      test: ["CMD-SHELL", "curl -s -o /dev/null -w '%{http_code}' http://localhost:9200/_cluster/health | grep -qE '200'"]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 60s
    restart: unless-stopped
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536

  # OpenSearch Dashboards — optional, activate with profile
  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:2.13.0
    networks: [magento]
    ports:
      - "5601:5601"
    environment:
      - "OPENSEARCH_HOSTS=http://opensearch:9200"
      - "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true"
    profiles: [monitoring]

7. Node.js für Hyvä Tailwind Builds

Hyvä-Themes in einem Docker-Magento-Setup benötigen Node.js für den Tailwind CSS Build. Das bedeutet: kein Node auf dem Host-System nötig, aber ein Node-Container oder ein Multi-Stage-Build-Setup. Die einfachste Lösung ist ein dedizierter Node-Service in der docker-compose.override.yml, der das Tailwind-Verzeichnis als Volume mountet und mit einem File-Watcher läuft. Entwickler können dann CSS-Änderungen ohne manuelle Build-Schritte direkt im Browser sehen. Der Service nutzt das offizielle Node-Image in der LTS-Version.

Für Produktions-Deploys im Docker-Magento-Stack gehört der Tailwind-Build in den CI/CD-Prozess: ein Multi-Stage-Dockerfile oder ein separater Build-Container baut den CSS-Output und legt ihn in das finale Image. Das stellt sicher, dass das Produktions-Image immer den aktuellen CSS-Build enthält und kein laufender Node-Prozess im Produktions-Container nötig ist. Der Node-Container im Compose-Stack ist ausschließlich für die lokale Entwicklung gedacht und sollte in CI und Produktion nicht gestartet werden – ein Profile wie dev-tools kapselt ihn sauber.

8. Volume-Strategie für Magento

Die Volume-Strategie ist einer der kritischsten Aspekte beim Docker-Magento-Setup. Magento generiert während des Betriebs erhebliche Mengen an Dateien: kompilierter Code unter var/generation, statische Inhalte unter pub/static, Logs unter var/log und Cache unter var/cache. Diese Verzeichnisse sollten auf benannte Docker-Volumes gemappt werden, nicht auf Host-Pfade – das verbessert die I/O-Performance erheblich, besonders auf macOS mit Docker Desktop, wo Host-Mounts notorisch langsam sind.

Die Source-Code-Dateien selbst werden für lokale Entwicklung als Host-Mount eingebunden, damit Änderungen sofort sichtbar sind. Das Muster für einen Docker-Magento-Stack: das Root-Verzeichnis als Host-Mount, die generierten und Cache-Verzeichnisse als benannte Volumes. Dieser Ansatz kombiniert schnelle Iterationszyklen für den Source-Code mit optimaler I/O-Performance für generierte Dateien. In Produktionsumgebungen gibt es keine Host-Mounts – alle Dateien kommen aus dem Image, und nur persistente Daten wie Uploads, DB-Daten und Log-Dateien liegen in Volumes.

9. Konfigurationsvarianten im Vergleich

Beim Aufbau eines Docker-Magento-Stacks gibt es verschiedene Konfigurationsentscheidungen, die die Performance und Wartbarkeit beeinflussen.

Entscheidung Option A Option B (empfohlen) Begründung
PHP-FPM/Nginx Ein kombinierter Container Separate Container Unabhängige Skalierung, klare Health-Checks
Suchmaschine Elasticsearch 7 (EOL) OpenSearch 2.x Magento 2.4.8 offiziell unterstützt
Redis Eine Instanz für alles Getrennte Instanzen Verschiedene Eviction-Policies nötig
Source-Code-Volumes Nur Host-Mounts Host-Mount + Named Volumes für Cache Performance auf macOS erheblich besser
Node/Tailwind Auf Host installiert Docker-Container mit Profile Keine Host-Abhängigkeiten, reproduzierbar

Die Entscheidung für separate Redis-Instanzen für Session und Cache ist auf den ersten Blick überdimensioniert, zahlt sich aber beim ersten Produktionsproblem aus: eine volle Page-Cache-Instanz verdrängt niemals Sessions, wenn die Instanzen getrennt sind. Das verhindert unerwartete Logouts unter Last – ein Fehler, der in Produktions-Docker-Magento-Stacks regelmäßig auftritt, wenn beide Rollen eine einzige Redis-Instanz teilen.

10. Zusammenfassung

Ein sauberer Docker-Magento-Stack besteht aus mindestens sechs Services mit klarer Aufgabentrennung: PHP-FPM für die Anwendungslogik, Nginx für statische Dateien und Proxy, MariaDB für persistente Daten, zwei Redis-Instanzen für Page-Cache und Session, OpenSearch für die Katalogsuche und optional ein Node-Container für lokale Tailwind-Builds. Jeder Service hat einen Healthcheck, und die Startup-Reihenfolge wird über depends_on mit condition: service_healthy gesteuert.

Die Volume-Strategie ist der häufigste Performance-Engpass in Docker-Magento-Setups: Host-Mounts für Source-Code, benannte Volumes für generierte Dateien und Cache-Verzeichnisse. Auf macOS ist der Unterschied zwischen diesen beiden Ansätzen für Magento-Requests messbar. In Produktionsumgebungen kommen keine Host-Mounts vor – das Image enthält alle Anwendungsdateien, und nur persistente Daten liegen in Volumes. Mit dieser Konfiguration verhält sich der Magento-Stack in jeder Umgebung vorhersehbar.

Mironsoft

Magento 2 Docker-Setup, Hyvä-Entwicklung und Shop-Infrastruktur

Magento-Docker-Stack für euren Shop?

Wir bauen und konfigurieren den vollständigen Docker-Magento-Stack – von PHP-FPM über OpenSearch bis zur Hyvä-Tailwind-Pipeline. Produktion und lokale Entwicklung aus einem Guss.

Stack-Setup

Vollständiger Magento-Docker-Stack mit PHP-FPM, Nginx, MariaDB, Redis und OpenSearch

Performance-Tuning

InnoDB-Konfiguration, Redis-Dimensionierung, OpCache-Einstellungen und Volume-Strategie

Hyvä-Integration

Node-Container für Tailwind-Builds, CI/CD-Pipeline und Multi-Stage-Dockerfiles

Docker für Magento — Das Wichtigste auf einen Blick

Pflicht-Services

PHP-FPM, Nginx, MariaDB, Redis (×2), OpenSearch. Jeder Service mit eigenem Healthcheck und depends_on: condition: service_healthy.

Redis-Strategie

Zwei Instanzen: Page Cache (allkeys-lru) und Session (noeviction). Verhindert unerwartete Logouts unter Last.

Volume-Performance

Source-Code als Host-Mount, generierte Dateien (var/, pub/static) als benannte Volumes. Auf macOS erheblich schneller.

OpenSearch

vm.max_map_count=262144 auf dem Host erforderlich. OpenSearch 2.x statt Elasticsearch 7 (EOL). Einzelner Node für Dev und Staging.

11. FAQ: Docker für Magento

1Warum so viele Services für Magento?
Suchmaschine ist Pflicht. Redis erheblich empfohlen. PHP-FPM und Nginx getrennt für unabhängige Skalierung.
2OpenSearch statt Elasticsearch?
Elasticsearch 7 EOL. Magento 2.4.8 unterstützt OpenSearch 2.x offiziell. Für neue Installationen immer OpenSearch.
3OpenSearch schlägt beim Start fehl?
vm.max_map_count zu niedrig. Auf Linux: sysctl -w vm.max_map_count=262144. Docker Desktop setzt dies automatisch.
4Warum zwei Redis-Instanzen?
Cache braucht allkeys-lru, Sessions brauchen noeviction. Eine Instanz kann Sessions unter Speicherdruck verlieren.
5Volume-Performance auf macOS verbessern?
Generierte Verzeichnisse (var/, pub/static) als benannte Docker-Volumes – deutlich schneller als Host-Mounts über FUSE.
6PHP-FPM memory_limit für Magento?
Mindestens 2G für Web, 4G für CLI-Operationen (setup:di:compile). Als Umgebungsvariable oder Custom php.ini.
7Node für Hyvä Tailwind Builds?
Local Dev: Node-Container mit File-Watcher. Produktion: Multi-Stage-Build im CI. Kein Node im Produktions-Container.
8Startup-Reihenfolge steuern?
depends_on: condition: service_healthy. Erfordert korrekte Healthchecks auf db, redis und opensearch.
9Nginx und PHP-FPM synchronisieren?
Beide mounten dasselbe benannte Volume. Nginx read-only, PHP-FPM read-write. Auf demselben Host sofort konsistent.
10Welche PHP-Extensions braucht Magento?
bcmath, ctype, curl, dom, gd, intl, mbstring, pdo_mysql, soap, xsl, zip. Xdebug nur im Dev-Image.