Ein Basis-Setup für Magento Vagrantboxen

Im ersten Teil der Artikelserie zu Magento mit Vagrant habe ich Vagrant und die automatische Synchronisation mit Rsync vorgestellt. Nun kommen wir zu einem konkreten Setup der Vagrantbox für Magento.

Für das Provisionieren (also automatisches aufsetzen) der Box nutzen wir Shell-Skripte. Für Fortgeschrittene komme ich im letzten Teil der Serie zu einem anspruchsvolleres Setup mit Puppet und werde auch eine einsatzfertige Magento-Box veröffentlichen.

Zum Einstieg in Vagrant empfehle ich allerdings die hier vorgestellte Variante zu übernehmen und ein wenig mit der Konfiguration zu experimentieren. Sie steht vollständig auf Github zur Verfügung. Auch wenn das GUI Tool PuPHPet die Puppet-Konfiguration kinderleicht macht und man die Puppet DSL (Domain specific language) so nicht kennen muss, holt man sich zusätzliche Komplexität ins Haus, was im Fehlerfall einige Stunden und Frustration kosten kann.

Vagrantfile

Das Vagrantfile ist das Herzstück der Vagrantbox, hier werden die Parameter für den Provider (also Virtualbox in unserem Fall) gesetzt, unter anderem zu Netzwerk und Synchronisation.

Was hier im Einzelnen passiert:

  1. Das Basis-Image wird ausgewählt. Wir nutzen eine der Standard-Boxen, Ubuntu 12.04 (Precise Pangolin) 64 Bit. Unter http://vagrantbox.es/ finden sich noch unzählige mehr.
  2. Der Hostname wird gesetzt. Auf Hosts mit Linux oder Apple Bonjour werden Hostnamen mit .local automatisch erkannt. Ansonsten muss er noch in die Datei /etc/hosts bzw. C:\Windows\System32\drivers\etc\hosts eingetragen werden:

  3. Der Netzwerk-Adapter wird konfiguriert. Dies ist ein Host-Only Netzwerk, so dass die Vagrantbox nur mit unserem Rechner und anderen virtuellen Maschinen verbunden ist. Ein zusätzlicher NAT Adapter wird automatisch eingerichtet, so dass die Box Zugriff aufs Internet hat.

  4. Die Hardware der VM wird spezifiziert:

  5. Provisionierungs-Skripte werden definiert. In bin/vagrant-bootstrap.sh wird das System eingerichtet. Das Skript läuft bei jeder Provisionierung, also beim ersten Start und bei explizitem Aufruf von vagrant provision. Zusätzlich sind zwei inline Commands definiert, die bei jedem Start ausgeführt werden: Neustart von Apache sowie von Mailcatcher.

  6. Die mit rsync synchronisierten Verzeichnisse (siehe Teil 1) werden eingerichtet. Beliebige rsync-Parameter können angegeben werden, sowie von der Synchronisation auszunehmende Dateien/Verzeichnisse. Ich synchronisiere /src, /vendor und /.modman. Auf die Verzeichnis-Struktur komme ich unten noch zurück.

bin/vagrant-bootstrap.sh

Wie beschrieben, läuft dieses Skript bei der Provisionierung, das heißt beim ersten Start der Box oder durch expliziten Aufruf von vagrant provision. Hier bringen wir alle Befehle unter, mit denen wir das System auf den gewünschten Stand bringen. Ein Beispiel:

Was hier im Einzelnen passiert:

Installation

Mit apt-get werden nötige Pakete installiert, unter anderem PHP 5.4, MySQL, Apache, Git. Mailcatcher wird als Ruby Gem installiert. Da Vagrant auf Ruby basiert, ist Ruby bereits vorinstalliert, allerdings ohne RVM (Ruby Virtual Machine), dies holen wir nach. Composer, Modman und N98-Magerun werden nach /usr/local/bin heruntergeladen.

Konfiguration

Einige wichtige Konfigurationsdateien habe ich ins Git-Repository nach /conf ausgelagert. Diese werden im Bootstrap-Skript entweder gesymlinkt oder wenn das nicht möglich ist, kopiert:

  • MySQL-Konfiguration: my.cnf
  • Zusätzliche PHP INI Dateien:
    • zend_debugger.ini aktiviert remote debugging
    • mailcatcher.ini setzt den sendmail-Pfad nach catchmail, so dass alle ausgehenden Mails von Mailcatcher gefangen werden
  • Alle Dateien in /.ssh, das kann der eigene SSH-Key und eine known_hosts Datei sein, z.B. für den Zugriff auf interne Repositories.
  • Lokalisierungseinstellungen: locale
  • Apache Virtualhost-Konfiguration: vhost.conf
Magento

Ein zweites Skript vagrant-magento.sh wird als Vagrant-User ausgeführt. Dieses Skript kann von Installation zu Installation unterschiedlich aussehen, je nach Projektstruktur und Installations-Quellen. Wichtig ist, dass hier die Datenbank angelegt und Magento im Verzeichnis www deployed wird.

Sonstiges
  • Die User vagrant und www-data werden gegenseitig ihren jeweiligen Gruppen zugewiesen, so dass bei Dateiberechtigungen von 660 bzw. 770 der User keine Rolle spielt.
  • Einige Git-Konfigurationsparameter werden gesetzt

Mailcatcher

Mailcatcher ist ein Tool, das alle ausgehenden Mails abfängt und in einem Web-Interface bereitstellt. Dieses ist unter magento.local:1080 erreichbar (sofern magento.local der Hostname der Vagrantbox ist).

Zend_Debug Remote Debugging

Eine Anmerkung zum Remote Debugging: Für den Zugriff von Guest auf Host muss bei Windows-Hosts die Windows-Firewall konfiguriert werden. Siehe: http://serverfault.com/a/333584/165983

/bin/vagrant-magento.sh

Hier ein Beispiel für das Magento-Installations-Skript:

Hier führe ich unter anderem ein initales composer install und modman deploy aus, initialisiere EcomDev_PHPUnit und nutze n98-magerun für Magento Download und Installation (Aufsetzen von Datenbank und generierung der local.xml). Code und Kommentare sollten selbsterklärend sein.

composer.json

So kann die initiale Composer-Konfiguration aussehen. Folgendes ist wichtig für unser Setup:

  1. Composer Installer für die Installation von Magento-Extensions via Composer:
  2. Die Konfiguration ebendieses Installers: (Mit dem Typ „Magento-Source“ ist es möglich, den Magento Core ebenfalls über Composer zu installieren. Ich bevorzuge die Installation via n98-magerun, siehe oben)
  3. Composer-Skripte um Magento-Extensions nach Composer-Updates automatisch mit modman zu deployen:

Die übrigen Abhängigkeiten und Konfigurationen sind als Empfehlung zu verstehen, können aber beliebig geändert werden.

Projektstruktur

Die hier vorgestellte Struktur empfehle ich für neu entwickelte Shops. Mögliche Alternativen werden in einem separaten Beitrag erläutert. Der Quellcode verteilt sich auf folgende Verzeichnisse:

Verzeichnis Inhalt
/.modman Magento-Extensions
/src Projektspezifischer Code (inkl. gekaufter Extensions)
/vendor Nicht-Magento-spezifische Bibliotheken
/www Magento-Core

Durch Modman werden auf der Vagrantbox zusätzlich Symlinks in .modman (nach src) und www (nach .modman) erstellt.

In /www/ gibt es also keinerlei custom code, alles kommt mit Composer und Modman entweder aus /vendor bzw. /.modman (für fremden Code und eigene, projektübergreifende Module) oder aus /src (für eigenen, shop-spezifischen Code).

Im Git Repository befindet sich nur der eigene Code sowie Abhängigkeitsdefinitionen und Installations-Anweisungen. Auszug aus der .gitignore:

Diese Verzeichnisse werden mit composer install und modman deploy befüllt. Anmerkung: Es hat auch Vorteile, .modman und vendor mit ins Repository aufzunehmen, damit entfällt das oft langwierige composer install beim Umschalten zwischen Branches und die Verfolgung von Änderungen durch Updates wird einfacher.

Ich benutze https://github.com/AOEpeople/composer-installers als leichtgewichtige Alternative und Drop-in-Replacement zum Magento Composer Installer. Magento Extensions werden damit direkt nach .modman statt vendor heruntergeladen und können von dort ganz normal mit modman deployed werden, frei nach der Unix-Philosophie „one simple tool for each job“. Mehr Infos dazu gibt es in der Präsentation “Wiring Magento Projects“: http://de.slideshare.net/aoepeople/merged-32876900

In /src liegt eine zentrale modman-Datei, die alle eigenen Module mit @import importiert. So muss nur src selbst mit „modman link“ in .modman verlinkt werden. Daher habe ich im oben vorgestellten Vagrantfile bei den Synchronisations-Einstellungen für .modman auch /src exkludiert, dies ist der einzige in .modman angelegte Symlink, alle mit Composer installierten Module sind wie gesagt direkt hier installiert.

Vorteile:

  • Strikte Trennung von Core, 3rd-Party Modulen und Eigenentwicklungen
  • Komplett modular, der Modul-Code ist jeweils an einer Stelle gesammelt

Vollständiges Beispiel auf Github

Das Beispiel-Setup habe ich vollständig einsatzbereit auf Github gestellt. Wenn alle System-Anforderungen aus Teil 1 erfültl sind, kann die Box folgendermaßen installiert und gestartet werden:

Anschließend ist Magento unter magento.local bzw. 192.168.56.101 erreichbar (Eintrag in /etc/hosts nicht vergessen!)

Als Grundlage für kleine bis mittlere Projekte ist dieses Setup schon brauchbar. Im dritten Teil werde ich alternative Projektstrukturen erläutern. Die Fortgeschrittenen-Variante mit Puppet als Provisioner stelle ich im vierten und letzten Teil der Serie vor.

Fabian Schmengler

Author: Fabian Schmengler

Fabian Schmengler ist Diplom-Informatiker und Magento Entwickler bei integer_net. Seine Schwerpunkte sind Backend-Entwicklung, Konzeptionierung und Test-Automatisierung. Seit 2011 ist er Magento Certified Developer, seit 2014 Magento Certified Solution Specialist.