diff --git a/content/de/admin-processes.md b/content/de/admin-processes.md index 709adf1a2..7cfcc074c 100644 --- a/content/de/admin-processes.md +++ b/content/de/admin-processes.md @@ -1,14 +1,14 @@ ## XII. Admin-Prozesse ### Admin/Management-Aufgaben als einmalige Vorgänge behandeln -Die [Prozess-Formation](./concurrency) ist das Bündel von Prozessen zur Erledigung der üblichen Aufgaben einer App (wie die Abarbeitung von Web Requests) während sie läuft. Daneben möchten Entwickler oft einmalige Administrativ- oder Wartungsaufgaben an der App erledigen, wie zum Beispiel: +Die [Prozess-Formation](./concurrency) ist das Bündel von Prozessen zur Erledigung der üblichen Aufgaben einer App (wie die Abarbeitung von Web-Requests) während sie läuft. Daneben möchten Entwickler oft einmalige Administrativ- oder Wartungsaufgaben an der App erledigen, wie zum Beispiel: -* Datenbank-Migrationen starten(z.B. `manage.py migrate` in Django, `rake db:migrate` in Rails). +* Datenbank-Migrationen starten (z.B. `manage.py migrate` in Django, `rake db:migrate` in Rails) * Eine Konsole starten (auch bekannt als [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) Shell) um beliebigen Code zu starten oder die Modelle der App gegen die Live-Datenbank zu prüfen. Die meisten Sprachen stellen eine REPL zur Verfügung, wenn man den Interpreter ohne Argumente startet (z.B. `python` oder `perl`) oder in manchen Fällen mit einem anderen Kommando (z.B. `irb` für Ruby, `rails console` für Rails). -* Einmalig auszuführende Skripts aus dem Repo der App starten (z.B. `php scripts/fix_bad_records.php`). +* Einmalig auszuführende Skripte aus dem Repo der App starten (z.B. `php scripts/fix_bad_records.php`). -Einmalige Administrations-Prozesse sollten in einer Umgebung laufen, die identisch ist zu der Umgebung der üblichen [langlaufenden Prozesse](./processes). Sie laufen gegen einen [Release](./build-release-run) und benutzen dieselbe [Codebase](./codebase) und [config](./config) wie jeder Prozess, der gegen einen Release läuft. Administrationscode wird mit dem App-Code ausgeliefert um Synchronisationsprobleme zu vermeiden. +Einmalige Administrationsprozesse sollten in einer Umgebung laufen, die identisch ist zu der Umgebung der üblichen [langlaufenden Prozesse](./processes). Sie laufen gegen einen [Release](./build-release-run) und benutzen dieselbe [Codebase](./codebase) und [Konfiguration](./config) wie jeder Prozess, der gegen einen Release läuft. Administrationscode wird mit dem App-Code ausgeliefert um Synchronisationsprobleme zu vermeiden. Dieselben Techniken zur [Isolation von Abhängigkeiten](./dependencies) sollten für alle Prozessarten verwendet werden. Wenn zum Beispiel ein Ruby-Web-Prozess das Kommando `bundle exec thin start` verwendet, dann sollte eine Datenbankmigration `bundle exec rake db:migrate` verwenden. Wenn ein Python-Programm Virtualenv nutzt, sollte es sein mitgeliefertes `bin/python` sowohl zum Start des Tornado Webservers als auch für alle `manage.py` Admin-Prozesse verwenden. -Die Zwölf Faktoren bevorzugen Sprachen, die eine REPL Shell direkt mitbringen. Das erleichtert das Starten von einmal auszuführenden Skripten. In einem lokalen Deploy rufen Entwickler einmal auszuführende Admin-Prozesse direkt über ein Shell-Kommando im Checkout-Verzeichnis der App auf. In einem Produktions-Deploy können Entwickler ssh oder andere Kommando-Fernsteuerungs-Mechanismen benutzen, die die Ausführungsumgebung dieses Deploys für das Starten eines solchen Prozesses bereitstellt. \ No newline at end of file +Die Zwölf Faktoren bevorzugen Sprachen, die eine REPL Shell direkt mitbringen. Das erleichtert das Starten von einmal auszuführenden Skripten. In einem lokalen Deploy rufen Entwickler einmal auszuführende Admin-Prozesse direkt über ein Shell-Kommando im Checkout-Verzeichnis der App auf. In einem Produktions-Deploy können Entwickler ssh oder andere Kommando-Fernsteuerungs-Mechanismen benutzen, die die Ausführungsumgebung dieses Deploys für das Starten eines solchen Prozesses bereitstellt. diff --git a/content/de/backing-services.md b/content/de/backing-services.md index ca1b735b5..c3f1d0dbf 100644 --- a/content/de/backing-services.md +++ b/content/de/backing-services.md @@ -5,10 +5,10 @@ Ein *unterstützender Dienst* ist jeder Dienst, den die App über das Netzwerk i Unterstützende Dienste wie Datenbanken werden traditionell von denselben Systemadministratoren verwaltet, die die App deployen. Außer diesen intern verwalteten Diensten können der App auch von Dritten verwaltete Dienste zur Verfügung stehen. Dazu gehören SMTP-Dienste (wie [Postmark](http://postmarkapp.com/)), Metrik-Sammler (wie [New Relic](http://newrelic.com/) oder [Loggly](http://www.loggly.com/)), Binary-Asset-Dienste (wie [Amazon S3](http://aws.amazon.com/s3/)), und auch über eine API zugängliche Dienste (wie [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), oder [Last.fm](http://www.last.fm/api)). -**Der Code einer Zwölf-Faktor-App macht keinen Unterschied zwischen lokalen Diensten und solchen von Dritten.** Für die App sind sie beide unterstützende Dienste, zugreifbar über eine URL oder andere Lokatoren/Credentials, die in der [Konfiguration](./config) gespeichert sind. Ein [Deploy](./codebase) einer Zwölf-Faktoren-App könnte eine lokale MySQL-Datenbank durch eine von Dritten zur Verfügung gestellten ersetzen (wie [Amazon RDS](http://aws.amazon.com/rds/)). Genauso ohne Codeänderung kann ein lokaler SMTP-Server durch einen von Dritten zur Verfügung gestellten SMTP-Dienst ersetzt werden. In beiden Fällen muss sich nur der Resource-Handle in der Konfiguration ändern. +**Der Code einer Zwölf-Faktor-App macht keinen Unterschied zwischen lokalen Diensten und solchen von Dritten.** Für die App sind sie beide unterstützende Dienste, zugreifbar über eine URL oder andere Lokatoren/Credentials, die in der [Konfiguration](./config) gespeichert sind. Ein [Deploy](./codebase) einer Zwölf-Faktoren-App könnte eine lokale MySQL-Datenbank, durch eine von Dritten zur Verfügung gestellten, ersetzen (wie [Amazon RDS](http://aws.amazon.com/rds/)). Genauso ohne Codeänderung kann ein lokaler SMTP-Server durch einen von Dritten zur Verfügung gestellten SMTP-Dienst ersetzt werden. In beiden Fällen muss sich nur der Resource-Handle in der Konfiguration ändern. -Jeder einzelne unterstützende Dienst ist eine *Resource*. So ist zum Beispiel eine MySQL-Datenbank eine Ressource; zwei MySQL-Datenbanken (die für ein Sharding auf Applikationsebene verwendet werden) stellen zwei Ressourcen dar. Dass die Zwölf-Faktor-App diese Datenbanken als *angehängte Ressourcen* behandelt, zeigt ihre lose Kopplung zu dem Deploy an dem sie hängen. +Jeder einzelne unterstützende Dienst ist eine *Ressource*. So ist zum Beispiel eine MySQL-Datenbank eine Ressource; zwei MySQL-Datenbanken (die für ein Sharding auf Applikationsebene verwendet werden) stellen zwei Ressourcen dar. Dass die Zwölf-Faktor-App diese Datenbanken als *angehängte Ressourcen* behandelt, zeigt ihre lose Kopplung, zu dem Deploy an dem sie hängen. Ein Produktions-Deploy der an vier unterstützenden Diensten hängt. -Ressourcen können beliebig nach Belieben an Deploys an- und abgehängt werden. Wenn zum Beispiel die Datenbank einer App aufgrund von Hardwareproblemen aus der Rolle fällt, könnte der App-Administrator eine neue Datenbank aus einem Backup aufsetzen. Die aktuelle Produktionsdatenbank könnte abgehängt und die neue Datenbank angehängt werden -- ganz ohne Codeänderung. +Ressourcen können beliebig an Deploys an- und abgehängt werden. Wenn zum Beispiel die Datenbank einer App aufgrund von Hardwareproblemen aus der Rolle fällt, könnte der App-Administrator eine neue Datenbank aus einem Backup aufsetzen. Die aktuelle Produktionsdatenbank könnte abgehängt und die neue Datenbank angehängt werden -- ganz ohne Codeänderung. diff --git a/content/de/build-release-run.md b/content/de/build-release-run.md index 1839025b7..34e499f32 100644 --- a/content/de/build-release-run.md +++ b/content/de/build-release-run.md @@ -6,15 +6,13 @@ Eine [Codebase](./codebase) wird durch drei Phasen in einen (Nicht-Entwicklungs) * Die *Build-Phase* ist eine Transformation, die ein Code-Repository in ein ausführbarers Code-Bündel übersetzt, das man auch *Build* nennt. Ausgehend von einer Code-Version eines Commits, der im Deployment-Prozess festgelegt wurde, holt sie [Abhängigkeiten](./dependencies), verpackt sie zum Mitliefern, und kompiliert Binaries und Assets. * Die *Release-Phase* übernimmt den Build von der Build-Phase und kombiniert ihn mit der zum Deploy passenden [Konfiguration](./config). Der so erzeugte *Release* enthält sowohl den Build, als auch die Konfiguration und kann direkt in einer Ausführungsumgebung ausgeführt werden. -* Die *Run-Phase* (auch "Laufzeit" genannt) führt die App in einer Ausführungsumgebung aus indem sie eine Menge der [Prozesse](./processes) der App gegen einen ausgewählten Release ausführt. +* Die *Run-Phase* (auch "Laufzeit" genannt) führt die App in einer Ausführungsumgebung aus, indem sie eine Menge der [Prozesse](./processes) der App gegen einen ausgewählten Release ausführt. ![Code wird zum Build und zusammen mit einer Konfiguration ergibt sich ein Release](/images/release.png) -**Die Zwölf-Faktor-App trennt strikt zwischen Build-, Release- und Run-Phase.** Es ist nicht möglich, Code-Änderungen zur Laufzeit zu machen, weil es keinen Weg gibt, diese Änderungen zurück in die Build-Phase zu schicken. +**Die Zwölf-Faktor-App trennt strikt zwischen Build-, Release- und Run-Phase.** Es ist nicht möglich, Code-Änderungen zur Laufzeit zu machen, weil es keinen Weg gibt, diese Änderungen zurück in die Build-Phase zu schicken. -Deployment-Werkzeuge bieten meist eine Release-Verwaltung an. Am bekanntesten ist die Fähigkeit auf einen früheren Release zurückzusetzen. Zum Beispiel speichert das Deployment-Werkzeug [Capistrano](https://github.com/capistrano/capistrano/wiki) Releases in einem Unterverzeichnis mit Namen `releases`. Der aktuelle Release ist ein symbolischer Link auf aktuelle Release-Verzeichnis. Mit dem Kommando `rollback` kann einfach und schnell auf einen früheren Release zurückgesetzt werden. +Deployment-Werkzeuge bieten meist eine Release-Verwaltung an. Am bekanntesten ist die Funktion auf einen früheren Release zurückzusetzen. Zum Beispiel speichert das Deployment-Werkzeug [Capistrano](https://github.com/capistrano/capistrano/wiki) Releases in einem Unterverzeichnis mit Namen `releases`. Der aktuelle Release ist ein symbolischer Link auf aktuelle Release-Verzeichnis. Mit dem Kommando `rollback` kann einfach und schnell auf einen früheren Release zurückgesetzt werden. Jeder Release sollte eine eindeutige Release-ID haben, wie zum Beispiel einen Zeitstempel des Releases (`2011-04-06-20:32:17`) oder eine laufende Nummer (`v100`). Releases werden nie gelöscht und ein Release kann nicht verändert werden, wenn er einmal angelegt ist. Jede Änderung erzeugt einen neuen Release. Builds werden durch die Entwickler der App angestoßen, wenn neuer Code deployt wird. Im Gegensatz dazu kann die Ausführung zur Laufzeit automatisch erfolgen, wenn ein Server neu gebootet wird oder ein abgestürzter Prozess von der Prozessverwaltung neu gestartet wird. Deswegen sollte die Run-Phase auf so wenig bewegliche Teile wie möglich beschränkt sein, denn Probleme, die eine App vom Laufen abhalten, können sie mitten in der Nacht zusammenbrechen lassen, wenn keine Entwickler zur Verfügung stehen. Die Build-Phase kann komplexer sein, denn Fehler sind immer sichtbar für den Entwickler, der den Deploy vorantreibt. - - diff --git a/content/de/codebase.md b/content/de/codebase.md index 6e4037826..a6a3f7012 100644 --- a/content/de/codebase.md +++ b/content/de/codebase.md @@ -10,9 +10,8 @@ Eine *Codebase* ist jedes einzelne Repo (in einem zentralisierten Versionsmanage Es gibt immer eine eineindeutige Korrelation zwischen einer Codebase und einer App: * Wenn es mehrere Codebases gibt, ist es keine App -- sondern ein verteiltes System. Jede Komponente in einem verteilten System ist eine App, und Jede kann für sich den zwölf Faktoren entsprechen. -* Wenn mehrere Apps denselben Code teilen, verletzt dies die zwölf Faktoren. Lösen lässt sich dies indem man den gemeinsamen Code in Libraries auslagert, der über die [Abhängigkeitsverwaltung](./dependencies) geladen werden kann. +* Wenn mehrere Apps denselben Code teilen, verletzt dies die zwölf Faktoren. Lösen lässt sich dies, indem man den gemeinsamen Code in Bibliotheken auslagert und über die [Abhängigkeitsverwaltung](./dependencies) lädt. Es gibt nur eine Codebase pro App aber viele Deploys der App. Ein *Deploy* ist eine laufende Instanz der App. Meist gibt es ein Produktionssystem und eines oder mehrere Staging-Systeme. Zusätzlich hat jeder Entwickler eine Kopie der App in seiner lokalen Entwicklungsumgebung, das sind auch Deploys. Die Codebase ist über alle diese Deploys hinweg dieselbe, auch wenn bei jedem Deploy unterschiedliche Versionen aktiv sind. So hat zum Beispiel ein Entwickler manche Commits noch nicht nach Staging deployt; Staging hat manche Commits noch nicht nach Produktion deployt. Aber alle teilen dieselbe Codebase, was sie als verschiedene Deploys derselben App auszeichnet. - diff --git a/content/de/concurrency.md b/content/de/concurrency.md index 0e60c78c0..2eba41db6 100644 --- a/content/de/concurrency.md +++ b/content/de/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Nebenläufigkeit ### Mit dem Prozess-Modell skalieren -Jedes Computerprogramm wird, wenn es läuft, repräsentiert durch einen oder mehrere Prozesse. Webapps nutzen verschiedenste Arten der Prozess-Ausführung. Zum Beispiel laufen PHP-Prozesse als Kind-Prozesse von Apache und werden nach Bedarf gestartet, wenn Requests kommen. Java-Prozesse gehen anders vor: die JVM stellt einen massiven Über-Prozess zur Verfügung der große Mengen an Systemresourcen (Speicher und CPU) reserviert und die Nebenläufigkeit wird intern über Threads verwaltet. In beiden Fällen sind die laufenden Prozesse für die Entwickler der App nur minimal zu sehen. +Jedes Computerprogramm wird, wenn es läuft, repräsentiert durch einen oder mehrere Prozesse. Webapps nutzen verschiedenste Arten der Prozess-Ausführung. Zum Beispiel laufen PHP-Prozesse als Kind-Prozesse von Apache und werden nach Bedarf gestartet, wenn Requests kommen. Java-Prozesse gehen anders vor: die JVM stellt einen massiven Über-Prozess zur Verfügung der große Mengen an Systemressourcen (Speicher und CPU) reserviert und die Nebenläufigkeit wird intern über Threads verwaltet. In beiden Fällen sind die laufenden Prozesse für die Entwickler der App nur minimal zu sehen. ![Die Skalierung wird dargestellt als laufende Prozesse, die Diversität der Workload wird dargestellt als Prozesstypen.](/images/process-types.png) -**In der Zwölf-Faktor-App sind Prozesse First Class Citizens.** Die Prozesse der Zwölf-Faktor-App orientieren sich am [Unix-Prozess-Modell für Service Daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Mit diesem Model können Entwickler ihre App für die Bearbeitung verschienster Aufgaben konzipieren indem sie jeder Aufgabe einen *Prozesstyp* zuweisen. Zum Beispiel können HTTP Requests durch einen Web-Prozess bedient werden und langlaufende Hintergrundarbeiten durch einen Worker Prozess. +**In der Zwölf-Faktor-App sind Prozesse First Class Citizens.** Die Prozesse der Zwölf-Faktor-App orientieren sich am [Unix-Prozess-Modell für Service Daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Mit diesem Model können Entwickler ihre App für die Bearbeitung verschiedenster Aufgaben konzipieren in dem sie jeder Aufgabe einen *Prozesstyp* zuweisen. Zum Beispiel können HTTP-Requests durch einen Web-Prozess bedient werden und langlaufende Hintergrundarbeiten durch einen Worker-Prozess. -Dies hindert die einzelnen Prozesse nicht daran, ihr internes Multiplexing zu verwalten mittels Threads in der der Laufzeit-VM oder mit dem Async/Event-Modell von Werkzeugen wie [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) oder [Node.js](http://nodejs.org/). Aber eine einzelne VM ist in der Größe dadurch beschränkt (vertikale Skalierung), dass eine App noch in der Lage sein muss, mehrere Prozesse auf mehreren physikalischen Maschinen zu starten. +Dies hindert die einzelnen Prozesse nicht daran, ihr internes Multiplexing zu verwalten, mittels Threads in der Laufzeit-VM oder mit dem Async/Event-Modell von Werkzeugen wie [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) oder [Node.js](http://nodejs.org/). Aber eine einzelne VM ist in der Größe dadurch beschränkt (vertikale Skalierung), dass eine App noch in der Lage sein muss, mehrere Prozesse auf mehreren physikalischen Maschinen zu starten. -Das Prozess-Modell glänzt besonders, wenn es darum geht zu skalieren. Die [Share-Nothing, horizontal teilbare Art und Weise der Prozesse der Zwölf-Faktor-App](./processes) hat zur Folge, dass weitere Nebenläufigkeit einfach und zuverlässig hinzugefügt werden kann. Das Bündel von Prozesstypen und die Zahl der Prozesse wird auch *Prozess-Formation* genannt. +Das Prozess-Modell glänzt besonders, wenn es um Skalierung geht. Die [Share-Nothing, horizontal teilbare Art und Weise der Prozesse der Zwölf-Faktor-App](./processes) hat zur Folge, dass weitere Nebenläufigkeit einfach und zuverlässig hinzugefügt werden kann. Das Bündel von Prozesstypen und die Zahl der Prozesse wird auch *Prozess-Formation* genannt. -Die Prozesse einer Zwölf-Faktor-App [sollten nie als Daemons laufen](http://dustin.github.com/2010/02/28/running-processes.html) oder PID-Dateien schreiben. Stattdessen sollen sich auf den Prozessmanager des Betriebssystems verlassen (wie [Upstart](http://upstart.ubuntu.com/), den verteilten Prozessmanager einer Cloud-Plattform oder ein Werkzeug wie [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) während der Entwicklung) um [Output-Streams](./logs) zu verwalten, auf abgestürzte Prozesse zu reagieren und mit von Benutzern angestoßenen Restarts und Shutdowns umzugehen. +Die Prozesse einer Zwölf-Faktor-App [sollten nie als Daemons laufen](http://dustin.github.com/2010/02/28/running-processes.html) oder PID-Dateien schreiben. Stattdessen sollen sie sich auf den Prozessmanager des Betriebssystems verlassen (wie [Upstart](http://upstart.ubuntu.com/), den verteilten Prozessmanager einer Cloud-Plattform oder ein Werkzeug wie [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) während der Entwicklung) um [Output-Streams](./logs) zu verwalten, auf abgestürzte Prozesse zu reagieren und mit von Benutzern angestoßenen Restarts und Shutdowns umzugehen. diff --git a/content/de/config.md b/content/de/config.md index aae816698..f70c8a9c0 100644 --- a/content/de/config.md +++ b/content/de/config.md @@ -7,17 +7,17 @@ Die *Konfiguration* einer App ist alles, was sich wahrscheinlich zwischen den [D * Credentials für externe Dienste wie Amazon S3 oder Twitter * Direkt vom Deploy abhängige Werte wie der kanonische Hostname für den Deploy -Manchmal speichern Apps die Konfiguration als Konstanten im Code. Dies ist eine Verletzung der zwölf Faktoren, sie fordern **strikte Trennung der Konfiguration vom Code**. Die Konfiguration ändert sich deutlich von Deploy zu Deploy, ganz im Gegensatz zu Code. +Manchmal speichern Apps die Konfiguration als Konstanten im Code. Dies ist eine Verletzung der zwölf Faktoren. Sie fordern **strikte Trennung der Konfiguration vom Code**. Die Konfiguration ändert sich deutlich von Deploy zu Deploy, ganz im Gegensatz zu Code. -Ein Lackmustest ob eine App die Konfiguration vollständig ausgelagert hat ist, ob die Codebase jederzeit als Open Source veröffentlicht werden könnte ohne Credentials preiszugeben. +Ein Lackmustest, ob eine App die Konfiguration vollständig ausgelagert hat, ist, wenn die Codebase jederzeit als Open Source veröffentlicht werden könnte, ohne Credentials preiszugeben. -Es sei darauf hingewiesen, dass diese Definition von "Konfiguration" die interne Anwendungskonfiguration **nicht einschließt** wie `config/routes.rb` in Rails oder wie Code-Module [mit Spring verdrahtet sind](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html). Diese Art von Konfiguration ändert sich nicht von Deploy zu Deploy und gehört daher zum Code. +Es sei darauf hingewiesen, dass diese Definition von "Konfiguration" die interne Anwendungskonfiguration **nicht einschließt**, wie `config/routes.rb` in Rails oder wie Code-Module [mit Spring verdrahtet sind](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html). Diese Art von Konfiguration ändert sich nicht von Deploy zu Deploy und gehört daher zum Code. -Als Konfiguration könnte man auch Dateien verwenden, die nicht ins Versionsmanagement eingecheckt sind wie `config/database.yml` in Rails. Dies ist eine deutliche Verbesserung gegenüber der Verwendung von Konstanten, die ins Versionsmanagement eingecheckt sind. Es hat aber Schwächen: Es ist einfach, versehentlich eine Konfigurationsdatei ins Repo einzuchecken; es gibt die Tendenz, dass Konfigurationsdateien an verschiedenen Orten und in verschiedenen Format verstreut werden. Das macht es schwer die Konfiguration von einem Punkt aus zu managen. Desweiteren sind diese Formate oft sprach- oder plattformspezifisch. +Als Konfiguration könnte man auch Dateien verwenden, die nicht ins Versionsmanagement eingecheckt sind wie `config/database.yml` in Rails. Dies ist eine deutliche Verbesserung gegenüber der Verwendung von Konstanten, die ins Versionsmanagement eingecheckt sind, hat aber Schwächen. Es ist relativ einfach, versehentlich eine Konfigurationsdatei ins Repo einzuchecken. Zusätzlich gibt es Tendenzen, Konfigurationsdateien an verschiedenen Orten und in verschiedenen Formaten zu streuen. Das macht es schwer die Konfiguration von einem Punkt aus zu managen. Desweiteren sind diese Formate oft sprach- oder plattformspezifisch. **Die Zwölf-Faktor-App speichert die Konfiguration in *Umgebungsvariablen*** (kurz auch *env vars* oder *env*). Umgebungsvariablen von Deploy zu Deploy zu ändern ist einfach; im Gegensatz zu Konfigurationsdateien ist es unwahrscheinlich, dass sie versehentlich ins Code Repository eingecheckt werden und im Gegensatz zu speziellen Konfigurationsdateien oder anderen Konfigurationsmechanismen wie den Java Properties sind sie Sprach- und Betriebssystemunabhängig. -Ein anderer Aspekt des Konfigurationsmanagements ist die Gruppierung. Manchmal sammeln Apps die Konfiguration in benannten Gruppen (oft "Umgebungen" genannt)- benannt nach bestimmten Deploys wie zum Beispiel die Umgebungen `development`, `test` und `production` in Rails. Diese Methode skaliert nicht sauber: Je mehr Deploys einer App es gibt, desto mehr environment-Namen werden benötigt, wie zum Beispiel `staging` oder `qa`. Wenn das Projekt noch weiter wächst könnten Entwickler ihre eigenen speziellen Umgebungen wie `joes-staging` hinzufügen. Am Ende explodiert die Konfiguration kombinatorisch und die Verwaltung der Deploys wird fehleranfällig. +Ein anderer Aspekt des Konfigurationsmanagements ist die Gruppierung. Manchmal sammeln Apps die Konfiguration in benamten Gruppen (oft "Umgebungen" genannt), benannt nach bestimmten Deploys wie zum Beispiel die Umgebungen `development`, `test` und `production` in Rails. Diese Methode skaliert nicht sauber: Je mehr Deploys einer App es gibt, desto mehr Umgebungsnamen werden benötigt, wie zum Beispiel `staging` oder `qa`. Wenn das Projekt noch weiter wächst, könnten Entwickler ihre eigenen speziellen Umgebungen wie `joes-staging` hinzufügen. Am Ende explodiert die Konfiguration kombinatorisch und die Verwaltung der Deploys wird fehleranfällig. In einer Zwölf-Faktor-App sind Umgebungsvariablen greifbare Kontrollschrauben und vollständig orthogonal zueinander. Sie werden nie als "Umgebungen" zusammengefasst, sondern können für jeden Deploy unabhängig verwaltet werden. Dieses Modell skaliert reibungslos aufwärts, wenn die App sich natürlicherweise über ihre Lebenszeit hinweg auf mehr Deploys ausdehnt. diff --git a/content/de/dependencies.md b/content/de/dependencies.md index 2612b9d0c..a4c6f46e1 100644 --- a/content/de/dependencies.md +++ b/content/de/dependencies.md @@ -1,12 +1,12 @@ ## II. Abhängigkeiten ### Abhängigkeiten explizit deklarieren und isolieren -Die meisten Programmiersprachen bieten ein System an um unterstützende Bibliotheken zu verbreiten, wie [CPAN](http://www.cpan.org/) für Perl oder [Rubygems](http://rubygems.org/) 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"). +Die meisten Programmiersprachen bieten ein System an, um unterstützende Bibliotheken zu verbreiten, wie [CPAN](http://www.cpan.org/) für Perl oder [Rubygems](http://rubygems.org/) 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](https://bundler.io/) 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](http://www.pip-installer.org/en/latest/) für die Deklaration und [Virtualenv](http://www.virtualenv.org/en/latest/) für die Isolation. Selbst C hat [Autoconf](http://www.gnu.org/s/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 braucht 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](https://github.com/technomancy/leiningen#readme) ist es `lein deps`. +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](https://github.com/technomancy/leiningen#readme) 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. diff --git a/content/de/dev-prod-parity.md b/content/de/dev-prod-parity.md index a672c3ec7..6edaac5a6 100644 --- a/content/de/dev-prod-parity.md +++ b/content/de/dev-prod-parity.md @@ -69,8 +69,8 @@ Im Bereich der [unterstützenden Dienste](./backing-services) wie der Datenbank Für Entwickler ist es sehr elegant, einen leichtgewichtigen unterstützenden Dienst in der lokalen Umgebung zu benutzen, während ein ernst zu nehmender und robuster unterstützender Dienst in Produktion verwendet wird. So kann man SQLite lokal und PostgreSQL in Produktion benutzen; oder zum Cachen den lokalen Speicher in Entwicklung und Memcached in Produktion. -**Der Zwölf-Faktor-Entwickler widersteht dem Drang, verschiedene unterstützende Dienste in Entwicklung und Produktion zu verwenden**, selbst wenn Adapter über alle Unterschiede hinweg abstrahieren. Unterschiede zwischen den unterstützenden Diensten verursachen kleinste Inkompatiblitäten, und Code, der in Entwicklung oder Staging funktioniert und Tests besteht, scheitert in Produktion. Diese Reibungskosten und die dann notwendige Dämpfung des Continuous Deployment sind sehr hoch, wenn man sie über die Lebensdauer einer App aggregiert. +**Der Zwölf-Faktor-Entwickler widersteht dem Drang, verschiedene unterstützende Dienste in Entwicklung und Produktion zu verwenden**, selbst wenn Adapter über alle Unterschiede hinweg abstrahieren. Unterschiede zwischen den unterstützenden Diensten verursachen kleinste Inkompatiblitäten, und Code, der in Entwicklung oder Staging funktioniert und Tests besteht, scheitert in Produktion. Diese Reibungskosten und die dann notwendige Dämpfung des Continuous Deployment sind sehr hoch, wenn man sie über die Lebensdauer einer App aggregiert. Leichtgewichtige lokale Dienste überzeugen weniger als früher. Moderne unterstützende Dienste wie Memcached, PostgreSQL und RabbitMQ sind dank moderner Paketierungs-Systeme wie [Homebrew](http://mxcl.github.com/homebrew/) und [apt-get](https://help.ubuntu.com/community/AptGet/Howto) nicht schwierig zu installieren und zu starten. Auch deklarative Installationssysteme wie [Chef](http://www.opscode.com/chef/) oder [Puppet](http://docs.puppetlabs.com/) in Kombination mit leichtgewichtigen virtuellen Umgebungen wie [Vagrant](http://vagrantup.com/) setzen Entwickler in den Stand, lokale Umgebungen ans Laufen zu bringen, die nahe an Produktionsumgebungen herankommen. Die Installations- und Betriebskosten dieser Systeme sind gering verglichen mit dem Nutzen der Dev-Prod-Vergleichbarkeit und einem Continuous Deployment. -Adapter für unterschiedliche unterstützende Dienste sind weiterhin von Nutzen, weil sie das Portieren auf andere unterstützende Dienste schmerzlos machen. Aber alle Deploys der App (Entwicklungsumgebungen, Staging, Produktion) sollten denselben Typ und dieselbe Version eines jeden unterstützenden Diensts benutzen. +Adapter für unterschiedliche unterstützende Dienste sind weiterhin von Nutzen, weil sie das Portieren auf andere unterstützende Dienste schmerzlos machen. Aber alle Deploys der App (Entwicklungsumgebungen, Staging, Produktion) sollten denselben Typ und dieselbe Version eines jeden unterstützenden Dienstes benutzen. diff --git a/content/de/disposability.md b/content/de/disposability.md index ac596b739..1237d199c 100644 --- a/content/de/disposability.md +++ b/content/de/disposability.md @@ -1,12 +1,12 @@ ## IX. Einweggebrauch ### Robuster mit schnellem Start und problemlosen Stopp -**Die Prozesse einer Zwölf-Faktor-App** können **weggeworfen** werden, sie können also schnell gestartet und gestoppt werden.** Dies erleichtert schnelles elastisches Skalieren, schnelles Deployment von [Code](./codebase) oder [Konfigurationsänderungen](./config) und macht Produktionsdeployments robuster. +**Die Prozesse einer Zwölf-Faktor-App können *weggeworfen* werden, sie können also schnell gestartet und gestoppt werden.** Dies erleichtert schnelles elastisches Skalieren, schnelles Deployment von [Code](./codebase) oder [Konfigurationsänderungen](./config) und macht Produktionsdeployments robuster. -Prozesse sollten **möglichst geringe Startup-Zeiten** haben. Idealerweise braucht ein Prozess wenige Sekunden vom Startkommando bis der Prozess läuft und Requests oder Jobs entgegennehmen kann. Eine kurz Startup-Zeit gibt dem [Release-Prozess](./build-release-run) und der Skalierung mehr Agilität; sie hilft der Robustheit weil ein Prozessmanager bei Bedarf einfacher Prozesse auf neue physikalische Maschinen verschieben kann. +Prozesse sollten **möglichst geringe Startup-Zeiten** haben. Idealerweise braucht ein Prozess wenige Sekunden vom Startkommando bis der Prozess läuft und Requests oder Jobs entgegennehmen kann. Eine kurze Startup-Zeit gibt dem [Release-Prozess](./build-release-run) und der Skalierung mehr Agilität; sie hilft der Robustheit, weil ein Prozessmanager bei Bedarf einfacher Prozesse auf neue physikalische Maschinen verschieben kann. -Prozesse **fahren ohne Schwierigkeiten herunter, wenn sie ein [SIGTERM-Signal](http://en.wikipedia.org/wiki/SIGTERM)** vom Prozessmanager bekommen. Für einen Web-Prozess kann ein problemloses Herunterfahren erreicht werden, indem er aufhört an seinem Service-Port zu lauschen (und damit alle neuen Requests ablehnt), die laufenden Requests zuende bearbeitet und sich dann beendet. Diesem Modell eigen ist, dass HTTP-Requests kurz sind (höchstens ein paar Sekunden) oder im Falle von Long-Polling, der Client sich nahtlos neu verbindet wenn die Verbindung verloren geht. +Prozesse **fahren ohne Schwierigkeiten herunter, wenn sie ein [SIGTERM-Signal](http://en.wikipedia.org/wiki/SIGTERM)** vom Prozessmanager bekommen. Für einen Web-Prozess kann ein problemloses Herunterfahren erreicht werden, indem er aufhört an seinem Service-Port zu lauschen (und damit alle neuen Requests ablehnt), die laufenden Requests zuende bearbeitet und sich dann beendet. Diesem Modell eigen ist, dass HTTP-Requests kurz sind (höchstens ein paar Sekunden) oder im Falle von Long-Polling, der Client sich nahtlos neu verbindet, wenn die Verbindung verloren geht. -Für einen Worker-Prozess wird ein problemloser Stopp erreicht, indem er seinen laufenden Job an die Workqueue zurück gibt. Zum Beispiel kann bei [RabbitMQ](http://www.rabbitmq.com/) ein Worker einen [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); bei [Beanstalkd](http://kr.github.com/beanstalkd/) wird der Job automatisch an die Queue zurückgegeben wenn ein Worker die Verbindung beendet. Lock-basierte Systeme wie [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) sollten sicherstellen, dass ihr Lock im Job-Record freigegeben wird. Diesem Modell eigen ist, dass alle Jobs [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) sind, was üblicherweise erreicht wird indem man die Ergebnisse in eine Transaktion einpackt oder den Vorgang [idempotent](https://de.wikipedia.org/wiki/Idempotenz) gestaltet. +Für einen Worker-Prozess wird ein problemloser Stopp erreicht, indem er seinen laufenden Job an die Workqueue zurück gibt. Zum Beispiel kann bei [RabbitMQ](http://www.rabbitmq.com/) ein Worker einen [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); bei [Beanstalkd](http://kr.github.com/beanstalkd/) wird der Job automatisch an die Queue zurückgegeben, wenn ein Worker die Verbindung beendet. Lock-basierte Systeme wie [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) sollten sicherstellen, dass ihr Lock im Job-Record freigegeben wird. Diesem Modell eigen ist, dass alle Jobs [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) sind, was üblicherweise erreicht wird indem man die Ergebnisse in eine Transaktion einpackt oder den Vorgang [idempotent](https://de.wikipedia.org/wiki/Idempotenz) gestaltet. Prozesse sollte auch **robust gegen plötzlichen Tod** sein - falls die zugrundeliegende Hardware versagt. Auch wenn dies viel seltener ist als ein reguläres Herunterfahren mit `SIGTERM`, so kommt es dennoch vor. Wir empfehlen ein robustes Queue-Backend wie Beanstalkd, das Jobs an die Queue zurückgibt falls Clients die Verbindung beenden oder nicht mehr antworten. Wie auch immer ist eine Zwölf-Faktor-App darauf ausgelegt mit unerwarteten, irregulären Stopps umgehen zu können. [Crash-only design](http://lwn.net/Articles/191059/) führt dieses Konzept zu seinem [logischen Schluss](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/de/logs.md b/content/de/logs.md index f4ce2dbfb..68af07286 100644 --- a/content/de/logs.md +++ b/content/de/logs.md @@ -5,12 +5,12 @@ Logs sind der [Stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) von aggregierten, nach Zeit sortierten Ereignissen und zusammengefasst aus den Output Streams aller laufenden Prozesse und unterstützenden Dienste. Logs in ihrer rohen Form sind üblicherweise ein Textformat mit einem Ereignis pro Zeile (obwohl Backtraces von Exceptions über mehrere Zeilen gehen können) -**Eine Zwölf-Faktor-App kümmert sich nie um das Routing oder die Speicherung ihres Output Streams.** Sie sollte nicht versuchen, in Logdateien zu schreiben oder sie zu verwalten. Statt dessen schreibt jeder laufende Prozess seinen Stream von Ereignissen ungepuffert auf `stdout`. Bei einem lokalen Deployment sichtet ein Entwickler diesen Stream im Vordergrund seines Terminals um das Verhalten der App zu beobachten. +**Eine Zwölf-Faktor-App kümmert sich nie um das Routing oder die Speicherung ihres Output Streams.** Sie sollte nicht versuchen, in Logdateien zu schreiben oder diese zu verwalten. Statt dessen schreibt jeder laufende Prozess seinen Stream von Ereignissen ungepuffert auf `stdout`. Bei einem lokalen Deployment sichtet ein Entwickler diesen Stream im Vordergrund seines Terminals um das Verhalten der App zu beobachten. Auf Staging- oder Produktionsdeploys werden die Streams aller Prozesse von der Laufzeitumgebung erfasst, mit allen anderen Streams der App zusammengefasst und zu einem oder mehreren Zielen geleitet, zur Ansicht oder langzeitigen Archivierung. Diese Archivierungsziele sind für die App weder sichtbar noch konfigurierbar - sie werden vollständig von der Laufzeitumgebung aus verwaltet. Open-Source Log Router (wie [Logplex](https://github.com/heroku/logplex) und [Fluent](https://github.com/fluent/fluentd)) stehen dafür zur Verfügung. -Der Stream von Ereignissen für eine App kann in eine Datei geleitet werden oder mit einem Echtzeit-Tail in einem Terminal beobachtet werden. Sehr bedeutsam ist es, das der Stream in ein Log-Indexierungs und Analyse-System wie [Splunk](http://www.splunk.com/) oder in ein allgemein verwendbares Data Warehouse System wie [Hadoop/Hive](http://hive.apache.org/) gelenkt werden kann. Mit diesen System kann das Verhalten einer App leistungsfähig und flexibel beobachtet werden. Dies schließt ein: +Der Stream von Ereignissen für eine App kann in eine Datei geleitet werden oder mit einem Echtzeit-Tail in einem Terminal beobachtet werden. Sehr bedeutsam ist es, das der Stream in ein Log-Indexierungs- und Analyse-System wie [Splunk](http://www.splunk.com/) oder in ein allgemein verwendbares Data-Warehouse-System wie [Hadoop/Hive](http://hive.apache.org/) gelenkt werden kann. Mit diesem System kann das Verhalten einer App leistungsfähig und flexibel beobachtet werden. Dies schließt ein: -* Bestimmte Ereignisse in der Vergangenheit zu finden. -* Umfangreiche graphische Darstellungen (wie Requests pro Minute). -* Aktives Alarmieren aufgrund benutzerdefinierter Heuristiken (wie ein Alarm wenn die Anzahl von Fehlern pro Minute eine gewisse Grenze überschreitet). +* Bestimmte Ereignisse in der Vergangenheit zu finden +* Umfangreiche graphische Darstellungen (wie Requests pro Minute) +* Aktives Alarmieren aufgrund benutzerdefinierter Heuristiken (wie ein Alarm wenn die Anzahl von Fehlern pro Minute eine gewisse Grenze überschreitet) diff --git a/content/de/port-binding.md b/content/de/port-binding.md index 221d3efbf..aa9be0f1d 100644 --- a/content/de/port-binding.md +++ b/content/de/port-binding.md @@ -1,11 +1,11 @@ ## VII. Bindung an Ports ### Dienste durch das Binden von Ports exportieren -Webapps laufen manchmal in einem Webserver als Container. Zum Beispiel laufen PHP-Apps als Modul in [Apache HTTPD](http://httpd.apache.org/), oder Java-Apps laufen manchmal in [Tomcat](http://tomcat.apache.org/). +Web-Apps laufen manchmal in einem Webserver als Container. Zum Beispiel laufen PHP-Apps als Modul in [Apache HTTPD](http://httpd.apache.org/), oder Java-Apps laufen manchmal in [Tomcat](http://tomcat.apache.org/). -**Die Zwölf-Faktor-App ist vollständig eigenständig** und verlässt sich nicht darauf, dass ein externer Webserver zur Laufzeit injiziert wird um dem Web einen Dienst zur Verfügung zu stellen. Die Webapp **exportiert HTTP als Dienst, indem sie sich an einen Port bindet** und wartet an diesem Port auf Requests. +**Die Zwölf-Faktor-App ist vollständig eigenständig** und verlässt sich nicht darauf, dass ein externer Webserver zur Laufzeit injiziert wird, um dem Web einen Dienst zur Verfügung zu stellen. Die Web-App **exportiert HTTP als Dienst, indem sie sich an einen Port bindet** und wartet an diesem Port auf Requests. -In einer lokalen Entwicklungsumgebung besucht ein Entwickler eine Dienst-URL wie `http://localhost:5000/` um auf den Dienst der App zuzugreifen. Beim Deployment sorgt eine Routing-Schicht dafür, dass Requests von einem öffentlich sichtbaren Hostnamen zu den an die Ports gebundenen Prozessen kommen. +In einer lokalen Entwicklungsumgebung öffnet ein Entwickler eine Dienst-URL wie `http://localhost:5000/`, um auf den Dienst der App zuzugreifen. Beim Deployment sorgt eine Routing-Schicht dafür, dass Requests von einem öffentlich sichtbaren Hostnamen zu den an die Ports gebundenen Prozessen kommen. Üblicherweise wird dies mittels [Abhängigkeitsdeklaration](./dependencies) implementiert. Zu der App fügt man eine Webserver-Bibliothek hinzu wie [Tornado](http://www.tornadoweb.org/) für Python, [Thin](http://code.macournoyer.com/thin/) für Ruby oder [Jetty](http://jetty.codehaus.org/jetty/) für Java und andere JVM-basierenden Sprachen. Dies findet vollständig im *User Space* statt, also im Code der App. Der Vertrag mit der Laufzeitumgebung ist das Binden an einen Port um Requests zu bedienen. diff --git a/content/de/processes.md b/content/de/processes.md index 4775819d2..2c339b42e 100644 --- a/content/de/processes.md +++ b/content/de/processes.md @@ -7,8 +7,8 @@ Im einfachsten Fall ist der Code ein Stand-alone-Skript, die Ausführungsumgebun **Zwölf-Faktor-Apps sind zustandslos und [Shared Nothing](https://de.wikipedia.org/wiki/Shared_Nothing_Architecture).** Alle Daten werden in [unterstützenden Diensten](./backing-services) gespeichert, normalerweise einer Datenbank. -Der RAM oder das Dateisystem des Prozesses kann als kurzfristiger Cache für die Dauer einer Transaktion verwendet werden. Zum Beispiel kann ein Prozess eine Datei herunterladen, sie verarbeiten und die Ergebnisse in einer Datenbank speichern. Die Zwölf-Faktor-App geht nie davon aus, dass irgend etwas aus dem RAM oder im Dateisystem zwischengespeichertes für einen künftigen Request oder Job verfügbar sein wird. Es ist gut möglich, das ein künftiger Request von einem anderen Prozess bedient wird. Selbst wenn nur ein Prozess läuft, wird ein Neustart (verursacht durch Code Deployment, Konfigurationsänderung oder der Verlagerung der Ausführungsumgebung auf einen anderen physikalischen Ort) den gesamten lokalen Zustand (RAM und Dateisystem) löschen. +Der RAM oder das Dateisystem des Prozesses kann als kurzfristiger Cache für die Dauer einer Transaktion verwendet werden. Zum Beispiel kann ein Prozess eine Datei herunterladen, sie verarbeiten und die Ergebnisse in einer Datenbank speichern. Die Zwölf-Faktor-App geht nie davon aus, dass irgendetwas aus dem RAM oder im Dateisystem zwischengespeichertes für einen künftigen Request oder Job verfügbar sein wird. Es ist gut möglich, das ein künftiger Request von einem anderen Prozess bedient wird. Selbst wenn nur ein Prozess läuft, wird ein Neustart (verursacht durch Code Deployment, Konfigurationsänderung oder der Verlagerung der Ausführungsumgebung auf einen anderen physikalischen Ort) den gesamten lokalen Zustand (RAM und Dateisystem) löschen. -Asset-Paketierer (wie [Jammit](http://documentcloud.github.com/jammit/) oder [django-compressor](http://django-compressor.readthedocs.org/)) benutzen das Dateisystem als cache für kompilierte Assets. Eine Zwölf-Faktor-App wie die [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) würde dies Art von Kompilation eher in der [Build-Phase](./build-release-run) erledigen anstatt zur Laufzeit. +Asset-Paketierer (wie [Jammit](http://documentcloud.github.com/jammit/) oder [django-compressor](http://django-compressor.readthedocs.org/)) benutzen das Dateisystem als Cache für kompilierte Assets. Eine Zwölf-Faktor-App wie die [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) würde diese Art von Kompilation eher in der [Build-Phase](./build-release-run) erledigen anstatt zur Laufzeit. -Manche Web-Systeme verlassen sich auf ["Sticky Sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- sie cachen Benutzer-Session-Daten im RAM des App-Prozesses und erwarten, dass künftige Requests desselben Benutzers zum selben Prozess geschickt werden. Sticky Sessions sind eine Verletzung der zwölf Faktoren und eine guter Kandidat für einen Datenspeicher, der ein zeitabhängiges Löschen anbietet, wie [Memcached](http://memcached.org/) oder [Redis](http://redis.io/). \ No newline at end of file +Manche Web-Systeme verlassen sich auf ["Sticky Sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- sie cachen Benutzer-Session-Daten im RAM des App-Prozesses und erwarten, dass künftige Requests desselben Benutzers zum selben Prozess geschickt werden. Sticky Sessions sind eine Verletzung der zwölf Faktoren und eine guter Kandidat für einen Datenspeicher, der ein zeitabhängiges Löschen anbietet, wie [Memcached](http://memcached.org/) oder [Redis](http://redis.io/).