Magento 2 unter Docker betreiben & Debugging in PhpStorm

Mit Magento 2 habe ich zur Zeit mehrere Probleme – zum einen habe ich bisher immer mit MAMP (4.x) gearbeitet, wodurch zwar alles einigermaßen läuft, aber sicher nicht optimal ist. Für meine Magento 2 Projekte möchte ich lieber

  • mit PHP 7 arbeiten statt mit PHP 5.6 – das könnte man zwar immer in MAMP umstellen, nervt aber ungemein und vergisst man eh ständig
  • mit nginx statt Apache arbeiten – das könnte man auch immer im MAMP umstellen, aber wer macht das schon
  • Debugging sollte weiter wie bisher mit phpStorm funktionieren
  • Es muss schnell für andere Kollegen aufzusetzen sein ohne großen Konfigurationsaufwand

Und genau dafür bin ich jetzt auch auf den Docker-Zug aufgesprungen. Mit Docker bekommt man all diese Probleme gelöst. Und endlich nutzt dann auch jeder im Team die gleichen Versionen von PHP etc.

Ich erhoffe mir, dass das ewige Suchen nach der fehlenden Konfigurationseinstellung einfach entfällt. Dass man Systeme mit einem Fingerschnipp aufsetzen kann, ohne dass man dafür viel Wissen braucht.

Außerdem ist Docker mittlerweile auf einem echt guten Stand auf dem Mac. Die VM muss man nun nicht mehr umständlich über VirtualBox verwalten, sondern läuft einwandfrei im Hintergrund und wird von der Applikation selbst verwaltet. Genau das war mir immer ein Dorn im Auge, da das Datensharing in die Container auch nicht besonders schnell war.

Was muss installiert werden?

  • Docker für macOS (bei mir läuft aktuell 10.12 Sierra) – ich habe Version 1.12.1 (build: 12133)

Gedanken zur Docker-Umgebung

Ich möchte auch nur eine Docker-Umgebung booten, da diese sicherlich für 90% der Magento-Instanzen reichen wird. Natürlich könnte man jetzt auch in jedes Projekt alle Dateien packen, welche für die Docker-Umgebung relevant sind. Das macht aber aus meiner Sicht nur Sinn, wenn sich diese auch unterscheiden. Meistens brauchen wir eh nur php7 und nginx. Sogar ohne mySQL, da dieser Server extern steht und wir uns alle Datenbanken teilen. Ein Problem weniger.

Alle Magento-Shops mit den gleichen Docker-Containern zu betreiben hat zudem den Charme, dass man nicht ständig Container verwalten muss, starten und stoppen usw. Wenn sich mal eine Anforderung an die Container ändert, muss ich nur eine Änderung in einem Repository machen und nicht in jedem Projekt einzeln.

Wird ein Projekt spezieller und benötigt mehr, nehme ich diese Systeme entweder mit in meine Umgebung auf, oder entscheide mich dann doch für eine spezielle Docker-Umgebung nur für das eine Projekt. Weil dann ist doch wieder cool nach einem git clone nur ein docker-compose up aufrufen zu müssen damit alles läuft. Aber das ist Zukunftsmusik und steht bisher nicht auf der Liste, weil noch nicht benötigt. Aber selbst dann ist die folgende Konfiguration ein tolles Template.

Erstmal lebe ich nach dem Motto: Weniger Container gleich weniger Speicherbedarf gleich weniger Verwaltungsaufwand.

Vorbereitungen

Meine Ordnerstruktur ist wie folgt:

  • /Volumes/DEV/magento2 -> In diesem Ordner liegen alle meine Magento2-Instanzen in einzelnen Unterverzeichnissen.
  • Die Domain um alle Shops zu verwalten lautet localhost.magento2
  • Alles ist unter Port 8080 zu erreichen, da Port 80 bereits von MAMP / Apache genutzt wird – für die alten Magento 1 Shops brauche ich diese Sturktur weiterhin (obwohl ich auch das gerne auf Docker umstellen würde)

Daraus folgt, dass wir in die /etc/hosts einmal folgenden Eintrag einfügen müssen:

Außerdem müssen die Base-URLs von Magento jeweils so umgestellt werden, dass diese auch die Unterverzeichnisse enthalten. Also zum Beispiel:

http://localhost.magento2:8080/mkleine-shop/

Das war es auch schon fürs erste. Die folgenden Konfigurationen findest Du auch in meinem GitHub-Projekt.

Die Konfiguration

Starten wir also mit dem Dockerfile für php-fpm:

Eigentlich ziemlich einfach – wir installieren alles, was für einen Betrieb von Magento 2 benötigt wird. Geerbt wird vom Image für php-fpm. Hier ist im Default Version 7 enthalten.

Kommen wir zur docker-compose.yml. In Version 2 braucht man sich nicht einmal mehr um das Linken der Instanzen zu kümmern – alles passiert automatisch und die Systeme erreichen sich gegenseitig anhand der angegebenen Namen.

  • Als Webserver kommt nginx zum Einsatz. Hier wird der lokale Port 8080 auf den Container-Port 80 gemappt.
  • Der Port 443 des Containers ist über 8081 erreichbar – SSL habe ich aber zur Zeit nicht konfiguriert. Folgt aber eventuell später.
  • Dann wird das Verzeichnis eine Ebene höher als /code gemappt. Mein Docker-Repo liegt also in einem Verzeichnis genau neben allen Magento 2 Projekten
  • Der wichtigste Teil ist eigentlich die nginx Config. Hier wird automatisch ermittelt in welchem Unterverzeichnis man sich bewegt und dann entsprechend das MAGE_ROOT gesetzt und an PHP-FPM weitergegeben. Mehr Details gibts in der Datei selbst.
  • PHP gibt den Port 9000 nach außen frei – diesen brauchen wir für xDebug. Stichwort: Remote Debugging
  • Ansonsten folgt noch ein wenig FPM und PHP Konfiguration, welche nach belieben angepasst werden kann

Damit xDebug läuft habe ich mich einem Workaround bedient. Irgendwie ist es im aktuellen Stand von Docker nicht möglich rauszufinden, welche IP der Docker Host hat (was für die xDebug-Konfiguration natürlich wichtig ist). Also habe ich einen alias auf meinem Netzwerkgerät angelegt der wie folgt lautet:

Mit der folgenden xDebug-Konfiguration klappt die Verbindung einwandfrei!

xdebug-konfiguration-docker

Das wars dann eigentlich auch schon – startet man nun Docker, kann man unter localhost.magento2 wunderbar mit Magento2 arbeiten.

Am Ende habe ich mir noch einen Alias in der pash_profile angelegt, welcher automatisch den aktuellen Magento-Pfad ermittelt und dort im Container mit PHP7 alles ausführt.

Das ist sehr praktisch, da ja das komplette Code-Verzeichnis in Docker enthalten ist. Andernfalls müsste man immer umständlich wechseln.

Ich hoffe, dass ich alles ausführlich genug erklärt habe – insgesamt bin ich noch ein blutiger Anfänger in Sachen Docker und stehe noch ganz am Anfang. Eventuell macht es mehr Sinn, die Umgebung in ein eigenes Image zu packen und dann in jeder Magento-Instanz ein eigenes Docker-Compose zu packen. Die Images könnte man ja sogar in einer eigenen Registry verwalten usw.

Schlecht klingt das auf jeden Fall auch nicht und ist sicherlich die Art und Weise wie man seine Umgebung einfacher halten kann. Aber ich bin mit dieser Lösung fürs Erste sehr zufrieden und es geht für mich jetzt schon 100x schneller alles aufzusetzen, als bei jedem Kollegen die MAMP-Umgebung kompliziert aufzubauen.

Falls jemand Tipps und Tricks hat wie ich den Prozess noch verbessern könnte, bin ich natürlich für jede Hilfe und jeden Kommentar dankbar! Gerne auch als Pull-Request im entsprechenden GitHub-Repository.

Über

Jahrgang 87, gelernter Softwareentwickler und fast ein Jahrzehnt Erfahrung im Bereich Web-Entwicklung mit PHP und Web-Design. Diese Eigenschaften machen mich zu einem geeigneten und geschätzten Ansprechpartner für die Umsetzung Ihres Projektes. Weiterhin bin ich seit Ende 2013 Magento Certified Developer.