Schon mit dem Update auf Maverick durfte ich meinen gesamten MacPort MAMP-Stack neubauen, mich wieder in die /usr/opt/irgendwas
Ubuntu-fremde Pfadstruktur einarbeiten. Jetzt nach Yosemite war wieder ein Komplettupdate nötig. Da ich zunehmend seltener lokal entwickle, sollte der Stack schon irgendwie bekannten Mustern folgen, also Configs in /etc
, Webkram in /var/www
usw. Lokal läuft ja alles über VHosts, und eine /vhosts
Verzeichnis, das sind recht viele.
Da stolpere ich über die Unterstützung von Vagrant in PHPStorm. Was ist das? Automatisch konfigurierte VirtualBoxen, extern konfigurierbar? Und das noch Quellcode-verwaltbar ohne GUI? Das ist doch bestimmt ganz schön komplex? Ja und nein. Ein Erfahrungsbericht mit Versuch und viel Irrtum.
Es gibt reichlich vorkonfigurierte Boxen bei Github und Vagrant Cloud. Ich hab mit vagrant-php-box und vagrant-percona gestartet bzw. inspirieren lassen.
Als Out-of-the-box-Lösung für PHP-Webdev-Stacks gibts mit PhPHPet eine supergeile GUI die am Ende eine Box-Konfiguration ausspuckt. Aber ich will ja ganz spezielle Boxen selber aufsetzen. (“Framework? Nö, da schreib ich mir lieber ein eigenes, muhaha”). Speziell einen Apache-PHP-Box ohne MySQL und ggf. eine MySQL-Box.
MySQL Datenbank Server
Da ich alle Datenbanken lokal in einen Server bündele, möchte ich das auch weiterhin so handhaben für die Bestandsprojekte.
PHP-Entwicklungsserver (ohne MySQL): Da ja die DB ohnehin in einer eigenen Box stecken, braucht die PHP-Box diesen Server nicht.
Erste Idee: Mysql Server in einer einzelnen Box starten. Blöde Idee, scheitert an Rechten auf die gemountete /var/lib/mysql Datenbank-Ordner. Hat einer auch schon bei StackOverflow gefragt, Tipp war dann Impor/Export-Scripte. Ich habe mich dafür entschieden, dass der Mac die Mysql weiter betreiben darf, aber nicht über Mac Port, sondern als Paket direkt von MySQL.
Anleitungen von MySQL:
Howto install Native Package
Installation Systemsteuerung Panel
Bestehenden MySQL-Dienst stoppen
Nach einem Neustart des Dienstes funktionierte es dann auch ganz ordentlich. Bei Zweifeln ob der MySQL überhaupt läuft, kann man in /usr/local/mysql/bin: sudo -u _mysql ./mysqld
ausführen.
MySQL doch in ein Vagrant umziehen
Jeff auf Stackoverflow hat mit seiner Frage „Pre-existing MySQL data with Vagrant / VirtualBox“ die gleiche Anforderung gehabt, wurde aber dort auf bessere Varianten verwiesen. Ich möchte es trotzdem in einer eigenen Box. Eine Box mit MySQL als einzigen relevanten Dienst ist mit Puppet-Unterstützung recht fix aufgesetzt, das Daten-Verzeichnis noch nach /var/mysql
gemountet und los gehts. Der Start sudo service mysql start
scheitert. Bei Boot-Problemen einfach mal ins upstart-Log schauen: sudo less /var/log/upstart/mysql.log
. Per sudo -u vagrant mysqld
meldet er komische Datei-Zugriffsprobleme. Obwohl die Gruppenschreibrechte auf /var/mysql
korrekt sind und er mit dem Nutzer vagrant
ganz normal alles machen könnte, meldet MySQL es könne keine Testdatei anlegen.
Generell gestaltete sich die Paketinstallation schwierig, die Post-Install-Scripte (apt-get install ...
während der Provisionierung) sind immer wieder ohne erkennbaren Grund abgeschmiert. Eine kurze Recherche ergab, dass es wohl am RAM der Box liegt. Standardmäßig sind 512 MB verordnet, also flux auf 1024 MB angehoben in der Vagrantfile
..
config.vm.provider "virtualbox" do |vm|
vm.memory = 1024
end
Siehe da, funktioniert besser. Die Einstellung bietet sich auch für die späteren Apaches an, da reagieren die zügiger, gerade auch im Debugging. Aber weiter mit MySQL.
Da der Vagrant unter dem eigenen Nutzeraccount läuft, muss zunächst der eigene Nutzer in die Gruppe _mysql
, da das mysql/data
Verzeichnis vom Mac MySQL den Besitzer _mysql:_mysql
hat. Klar, kann man für das folgende umbiegen, muss man aber nicht. Ich nehme meinen Nutzer in die Gruppe _mysql
auf.
sudo dseditgroup -o edit -a ronny -t user _mysql
User mysql
wird Mitglied in Gruppe vagrant
und umgekehrt:
sudo usermod -a -G mysql vagrant
sudo usermod -a -G vagrant mysql
Und vagrant
soll auf /var/log
schreiben können, was der Gruppe syslog
gehört.
sudo usermod -a -G syslog vagrant
sudo usermod -a -G syslog mysql
Funktioniert leider nicht, immer noch Permission Fehler.
Der Tipp dass evtl. /etc/apparmor.d/local/usr.bin.mysqld
fehlen würde, brachte auch nix. Also mal anders probieren. Kann man /var/mysql
nicht als User mysql
mounten? Ja geht mit VirtualBox als Provider:
config.vm.synced_folder "/Volumes/Daten/mysql", "/var/mysql", id: "mysql",
owner: "mysql", group: "mysql",
mount_options: ["dmode=775,fmode=664"]
Blöderweise ermittelt Vagrant beim Boot für Mount die User-ID und Gruppen-ID. Aber die gibts ja vor der Provisionierung nicht. Henne-Ei-Problem – aber in wiederkehrenden Umgebungen ists ja jedes mal gleich, also fixe IDs festgelegt (innerhalb der laufenden Box mit id mysql
ermittelt):
config.vm.synced_folder "/Volumes/Daten/mysql", "/var/mysql", id: "mysql",
owner: 108, group: 113,
mount_options: ["dmode=775,fmode=664"]
Joar, geht auch vor Provisioning!
MySQL startet natürlich immer noch nicht – selber Senf mit Zugriffsrechten
Die Lösung fand ich dann hier – es war doch Apparmor, was verbietet, dass der Nutzer mysql
ausserhalb von /var/lib/mysql
agieren kann. Jetzt startet der MySQL im Vagrant! Meine my.cnf
schaut nun so aus:
[mysqld]
user = mysql
port = 3306
datadir = /var/lib/mysql/vagrant
..
Noch flux den Zugriff von aussen für root eingerichtet:
GRANT ALL ON . to root@'10.0.2.2';
FLUSH PRIVILEGES;
10.0.2.2 ist bekanntlich die Gateway-IP, also die des Hosts (netstat -rn
)
Nice!
SSH muss natürlich auf einen anderen Port nach aussen funken, als bei den PHP-Kisten. Die dürfen auf 2222 mappen, der MySQL aber auf 3322. Im Vagrantfile
so:
config.vm.network :forwarded_port, guest: 22, host: 3322, id: "ssh"
Das id:"ssh"
sorgt dafür, dass er SSH nicht doch per Default wieder auf 2222 mappt.
Die momentane Box-Konfiguration inkl. my.cnf
ist bei Github im Projekt vagrant-mysql-shared-folder verfügbar.
[Update 16.11.2014] MySQL startete beim Boot nicht automatisch, bzw. wurde nach 3x mit „init: mysql respawning too fast, stopped
“ vom Start ausgenommen. Ein dpkg-reconfigure mysql-server-5.5
behob allerdings das Problem.
Apache
Weiter gehts mit Webserver. Auf Basis der Vagrant-Puppets-Configs von jas0nkim’s my-vagrant-puppet-lamp gehts daran, Flechtie und dessen OXID-Onlineshop fitt zu machen. Das Modul mysql
hab ich dabei entfernt (manifests/default.pp + modules/mysql
).
Der MySQL ist vom Guest über dessen Gateway erreichbar (netstat -rn
), bei mir 10.0.2.2. mysql -uroot -h10.0.2.2
zeigt das es funktioniert. Also dies flux in OXIDs-config eingetragen. Der Aufruf von localhost:8080
zeigt dann schonmal ein funktionierenden Shop, inkl. DB-Verbindung zum Host.
Nun muss noch der Aufruf von http://dev.flechtie.de/
direkt in die Vagrant-Box durchschlagen. Problem ist, dass man leider als Nicht-root-Nutzer unter Mac keinen Port >1024 forwarden darf.
Anleitung für Mac bis inkl. Maverick (ipfw)
Anleitung für Mac ab Yosemite (pf)
Bei mir mit Yosemite also so:
Datei /etc/pf.anchors/com.vagrant
rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
<leerzeile>
(Leerzeile am Schluss beachten, <leerzeile> weglassen!)
Datei /etc/pf.conf
:
rdr-anchor "com.apple/*"
rdr-anchor "vagrant"
...
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "vagrant" from "/etc/pf.anchors/com.vagrant"
<leerzeile>
Und aktivieren:
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
Schon zeigt http://dev.flechtie.de/ alles i.O. an.
[Update 19.11.2014] Leider kümmert das Mac beim Boot einen Sch**. Man muss mind. einmal manuell sudo pfctl -e
nochmal ausführen damit es wieder klappt. Über Vagrant Trigger kann man das Port-Forwarding aber in die Vagrantfile
aufnehmen und somit automatisieren – was Salvatore Garbesi in seinen Blogpost „Vagrant Port Forwarding On Mac“ aufgeschrieben hat.
Diese Einträge sorgen dafür:
config.trigger.after [:provision, :up, :reload] do
system('echo "
rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port 80 -> 127.0.0.1 port 8080
rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -f - > /dev/null 2>&1; echo "==> Fowarding Ports: 80 -> 8080, 443 -> 8443"')
end
config.trigger.after [:halt, :destroy] do
system("sudo pfctl -f /etc/pf.conf > /dev/null 2>&1; echo '==> Removing Port Forwarding'")
end
Voraussetzung ist das Modul trigger – installiert mit vagrant plugin install vagrant-triggers
. Dann können die Anpassungen an der pf.conf übrigens entfallen – schaden aber auch nicht.
Mounting als www-data mit Schreibrechten
So recht gefällt mir es nicht, dass das Verz. in der Box komplett vagrant:vagrant
gehört. Besser wäre www-data:www-data
, dann kann der Hack der /etc/apache/envvars
in der vagrant/modules/apache/manifests/init.pp
auch entfallen. Also getan und Box neu provisioniert (ggf. vagrant destroy
& vagrant up
)
Allerdings ist das www-Verzeichnis auf meiner Hostmaschine noch _www:_www
, dem Standard-Apache-Nutzer auf dem Mac. So kann man leider innerhalb der Box dann nicht in die folder_sync-Dateien schreiben. Also flux meinen Nutzer mit in die Gruppe _www
aufgenommen:
sudo dseditgroup -o edit -a ronny -t user _www
Sollten Dateien auf dem Host mit Recht 644 bzw. 755 und _www:_www
vorhanden sein (gern z.B. tmp-Dateien bei OXID), dann chmod -R g+w tmp
Debugging mit xDebug
Damit das Debuggen mit PHPStorm wie vorher klappt war bissl basteln angesagt, und hauptsächlich die Erkenntnis, dass man den Host als Gateway-IP in den remote_host
eintragen muss.
Folgende Zeilen in der php.ini müssen in der Box landen:
[xdebug]
xdebug.remote_enable = 1
xdebug.remote_host = "10.0.2.2"
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 1
xdebug.idekey = "vagrant"
Dann kann man im FF via Plugin easyXdebug das Debugging antriggern und im PHPStorm das Debugging einfach aktiveren (Telefonsymbol auf grün schalten).
Vagrant Manager
[Update 27.11.2014]
Vagrant bringt zwar ein paar Kommandozeilentools, aber so ein hübsches Klicki-Bunti-Tool für die Mac Systemzeile ist doch auch was. So sieht man gleich was es für Vagrant-Boxen gibt, und ob sie laufen, ob sie pausiert worden sind u.ä. … Vagrant Manager ist genau das! Das ganze ist Opensource auf GitHub verfügbar und die Leute da freuen sich über ein mittelkleine Spende.
Fazit
Insgesamt hat mich die Sache bislang einige Abende und einen ganzen Sonntag „gekostet“. Aber die Möglichkeiten der Verzinsung sind enorm! Die lokale Entwicklung nun endlich abgekoppelt vom Host-Betriebssystem ist – Windows statt Mac ist ohne Probleme möglich. Und ohne weiteres können neue Boxen zum Spielen und Lernen aufgesetzt werden. Da sind das fantastische PHP-Framework Laravel mit seiner offiziellen lokalen Entwicklungsumgebung Homestead (Projekt bei Github), oder auch ein Symfony (oder hier), ownCloud, ein NodeJS mit Redis und MongoDB (oder auch hier), oder auch Facebooks HHVM. Leider hab ich für appserver.io noch keine Vagrant Box gefunden, challenge accepted!
Fragen und Anregungen gerne via @rhflow_de oder als Kommentar hier.
Rausschmeißer
Lesespaß gibts noch hier beim PHPmagazin: PHP 5.4 und 5.5 mit Vagrant und Chef virtualisieren.