The Twelve-Factor App

II. Abhängigkeiten

Abhängigkeiten explizit deklarieren und isolieren

Die meisten Programmiersprachen bieten ein System an, um unterstützende Bibliotheken zu verbreiten, wie CPAN für Perl oder Rubygems für Ruby. Aus einem Paketsystem stammende Bibliotheken können systemweit installiert werden (auch “Site Packages” genannt) oder in ein Verzeichnis der App beschränkt werden (genannt “vendoring” oder “bundling” - deutsch auch “mitliefern”).

Eine Zwölf-Faktor-App verlässt sich nie auf die Existenz von systemweiten Paketen. Sie deklariert alle Abhängigkeiten vollständig und korrekt über eine Abhängigkeitsdeklaration. Weiter benutzt sie zur Laufzeit ein Werkzeug zur Isolation von Abhängigkeiten um sicherzustellen, dass keine impliziten Abhängigkeiten aus dem umgebenden System “hereinsickern”. Die vollständige und explizite Spezifikation der Abhängigkeiten wird gleichermaßen in Produktion und Entwicklung angewandt.

So bietet zum Beispiel Bundler für Ruby das Format Gemfile zur Abhängigkeitsdeklaration und bundle exec zur Isolation von Abhängigkeiten. In Python gibt es für diese Schritte zwei unterschiedliche Werkzeuge – Pip für die Deklaration und Virtualenv für die Isolation. Selbst C hat Autoconf zur Deklaration der Abhängigkeiten, und statisches Linken kann für Isolation sorgen. Unabhängig von den Werkzeugen müssen Abhängigkeitsdeklaration und Isolation immer zusammen benutzt werden – eines alleine genügt für die zwölf Faktoren nicht.

Ein Nutzen der expliziten Abhängigkeitsdeklaration ist das einfachere Aufsetzen der App für neue Entwickler. Neue Entwickler können die Codebase der App auf ihre Entwicklungsmaschine auschecken und brauchen dazu nur eine Sprach-Runtime und eine Abhängigkeitsverwaltung. Um die App zum Laufen zu bringen wird lediglich ein deterministisches Build-Kommando benötigt. So ist zum Beispiel das Build-Kommando für Ruby/Bundler bundle install und für Clojure/Leiningen ist es lein deps.

Zwölf-Faktor-Apps verlassen sich auch nicht auf die implizite Existenz irgendwelcher Systemwerkzeuge. Beispiele dafür sind Shell-Aufrufe von ImageMagick oder curl. Auch wenn diese Werkzeuge auf vielen und sogar den meisten Systemen vorhanden sind, gibt es keine Garantie, dass sie auf allen Systemen vorhanden sind, auf denen die App in Zukunft laufen wird, oder dass die Werkzeug-Version die in Zukunft auf einem System vorhanden sein wird, kompatibel ist. Wenn die App per Shell auf ein Systemwerkzeug zugreift, sollte die App das Werkzeug mitliefern.