Aus aktuellem Anlass schreibe ich über eine Feature, mit dem man sich bei der Arbeit mit Zend Framework Projekten wunderbar selbst in den Fuß schießen kann: Den Sektionen in der „application.ini”.
Im Normalfall werden in einem Zend Framework Projekt sämtliche Einstellungen in der Konfigurationsdatei „application.ini” getätigt. Dies beinhaltet damit unter anderem auch wichtige Dinge wie zum Beispiel die Zugangsdaten zur Datenbank und möglicherweise weitere Backendsystemen wie Webservices, FTP-Server, Mailserver, usw.
Durch die Verwendung von Sektionen (Sections), wie in der Dokumentation von Zend vorgeschlagen, kann man sehr einfach unterschiedliche Konfigurationen für verschiedene Systeme eintragen. Das Entwicklungssystem („development”) erbt alle Einstellungen des produktiven Servers („production”) und überschreibt zum Beispiel die Konfiguration der Datenbankparameter. Für weitere Systeme wie QA oder Staging funktioniert das genau so.
Durch entsprechende Einstellungen im Projekt wird die Konfiguration aus der richtigen Sektion der application.ini geladen. Diese Einstellung kann an mehreren Stellen hinterlegt sein. Meist wird sie als Umgebungsvariable im Webserver konfiguriert, also entweder im Virtuellen Host oder der .htaccess-Datei. In der index.php der Anwendung wird der Standardwert dann meistens auf „production” gesetzt. Doch dieses Vorgehen ist gefährlich!
Gefahr droht bei Erreichbarkeit der Backendsysteme
Vergisst man die Umgebungsvariable beim Aufsetzten einer neuen Installation (z.B. in einer Entwicklungs-VM oder einem QA-Server), so steht die Anwendung dort auf Produktionseinstellungen. Sind nun die in der Konfigurationsdatei angegebenen produktiven Backendsysteme von dieser Installation erreichbar, nimmt das Unglück seinen Lauf: Jede Aktion wird ungewollt auf dem produktiven Datenbestand ausgeführt. Der SuperGAU ist eingetreten.
Nur Zugangsdaten des aktuellen Systems
Um einer solchen Situation aus dem Weg zu gehen bietet es sich an eine einfache Regel zu befolgen: Auf jedem System dürfen nur die dort benötigten Zugangsdaten gespeichert sein.
Dies bedeutet, in der application.ini auf Sektionen zu verzichten, es gibt also im einfachsten Fall nur noch eine „production”-Sektion mit allen Daten. Für die unterschiedlichen Einstellungen der einzelnen benötigten Systeme legt man sich am besten eigene Konfigurationsdateien in der Versionsverwaltung (Git, SVN, …) an und übernimmt die frühere Sektion in den Namen (application.ini.qa, application.ini.dev, application.ini.prod, usw).
Beim Deploy der Software muss man nun aktiv die richtige Konfigurationsdatei umbenennen oder kopieren. Wie viele andere Schritte auch, kann man diesen mit einem Build-Tool wie zum Beispiel phing automatisieren.
Weitere Gedanken
Man sollte auch daran denken, die „scharfe” application.ini in der Versionskontrolle zu ignorieren, damit sie nicht von einem Entwickler versehentlich eingecheckt wird. So verhindert man auch, dass man als Entwickler ständig eigene Einstellungen von Kollegen überschrieben bekommt :).
Zusätzlich kann man sich noch überlegen, ob die application.ini des Produktivsystems überhaupt in der Versionsverwaltung eingepflegt sein sollte. Möglicherweise haben dort Leute Zugriff, denen man eigentlich nicht alle Zugangsdaten anvertrauen will.
Als kleiner Blick voraus in die Zukunft: Im gerade entsehenden Zend Framework 2 wird ein ähnlicher Weg eingeschlagen und ebenfalls keine Sektionen mehr verwendet. Auch hier verlässt man sich auf verschiedene einzelne Dateien.
Ich finde die Vererbung der Konfiguration ganz praktisch, habe aber ähnliche Probleme gesehen.
Ich verwende deshalb statt Bezeichnungen wie „prod“ und „dev“ den Hostnamen. Somit gibt es kein vertuen mehr.
Diese „Hostname-Sektionen“ können trotzdem von anderen (intern verwendeten) Sektionen wie „prod“ und „dev“ erben und lassen sich so auch schnell umstellen.
Auf die Vererbung sollte man auch nicht verzichten, finde ich. Schliesslich ist es gerade das, was einem die Konfiguration erleichtert.
Auch stimme ich nicht zu, dass man die application.ini nicht in die Versionskontrolle übernehmen sollte.
Man sollte generell, wenn man ein neues Entwicklersystem aufsetzt auf ein Template setzen und dort bereits die Variable setzen, dass es sich um ein Entwicklungssystem handelt.
Setzt man z. B. Jenkins auf, dann sollte man eh alles checken und sich nicht auf Copy & Paste verlassen.
Interessante Info vor allem bez. ZF2!
Nur die Empfehlung die config des Produktivsystems nicht unter vcs zu stellen, kann ich nicht ganz nachvollziehen. Wenn es um Zugriffsschutz geht, spricht ja nichts dagegen es in einem getrennten repo zu verwalten. Aber unter vc sollte es doch in jedem Fall!?
Als Hintergrundinfo zum Thema configuration globbing im ZF2 noch interessant:
http://framework.zend.com/wiki/display/ZFDEV2/2011-12-07+Meeting+Log
ich finde den Artikel sehr gut geschrieben und danke ganz artig… Grüße aus Freiburg