public/css/screen.css 0000644 0001750 0005670 00000004547 15226251677 013371 0 ustar 00 0000000 0000000 body {
margin: 0;
padding: 0;
font-family: Georgia, sans-serif;
line-height: 1.5em;
font-size: 12pt;
}
h1, h2, h3 {
padding: 0;
margin: 0;
}
h1, h2 {
line-height: 1.25em;
}
header {
margin: 0;
margin-bottom: 8pt;
padding-top: 12pt;
padding-bottom: 26pt;
border: 1px solid black;
color: #fff;
background: #000;
font-size: 19pt;
text-align: center;
box-shadow: 0px 2px 12px #888;
}
header h1 a {
background: url(/images/symbol.png) top center no-repeat;
color: #FFFFFF;
display: block;
margin-top: 0.25em;
padding-top: 100px;
text-decoration: none;
}
section {
padding-top: 16pt;
text-align: center;
}
section h1 {
font-size: 19pt;
}
article {
padding-top: 8pt;
}
article, nav {
margin: 0 auto;
text-align: justify;
}
article p a, article li a {
text-decoration: none;
border-bottom: 1px dashed #444;
color: #000;
}
article p a:hover, article li a:hover {
color: #337;
}
section.concrete {
background: #ccc;
margin-top: 24pt;
padding-top: 24pt;
padding-bottom: 32pt;
border-top: 8pt solid #aaa;
}
section.concrete h1 {
font-size: 28pt;
margin-bottom: 32pt;
text-align: center;
}
section.concrete h2 {
margin-top: 12pt;
}
section.concrete h2 a {
text-decoration: none;
color: #000;
}
section.concrete h2 a:hover {
border-bottom: 2px dashed #444;
color: #337;
}
section.concrete h3 {
color: #333;
font-weight: normal;
}
section#factor h2 {
font-size: 28pt;
margin-bottom: 12pt;
}
section#factor h3 {
font-size: 17pt;
font-weight: normal;
color: #555;
margin-bottom: 16pt;
}
nav {
margin-top: 16pt;
margin-bottom: 48pt;
}
nav #locales {
text-align: center;
}
nav #locales a {
color: #000;
}
nav #locales span {
font-weight: bold;
}
nav #next {
float: right;
}
nav #prev {
float: left;
}
nav #next a, nav #prev a {
display: block;
font-size: 19pt;
text-decoration: none;
color: #000;
}
code {
border: 1px solid #999;
background: #eee;
padding: 1pt 3pt;
}
table {
padding-left: 32pt;
}
td, th {
padding-right: 12pt;
padding-bottom: 4pt;
}
footer {
color: #999;
font-size: 10pt;
background: #000;
padding-top: 24pt;
padding-bottom: 16pt;
text-align: center;
padding-right: 64pt;
min-height: 56pt;
}
footer a {
color: #999;
}
article img {
float: right;
margin-left: 32pt;
}
article img.full {
float: none;
margin-left: 0;
}
content/fr/port-binding.md 0000644 0001750 0005670 00000004445 15226251677 014326 0 ustar 00 0000000 0000000 ## VII. Associations de ports
### Exportez les services via des associations de ports
Les applications web sont parfois exécutées à l'intérieur d'un container de serveur web. Par exemple, les applications PHP peuvent fonctionner comme un module à l'intérieur de [HTTPD, d'Apache](http://httpd.apache.org/), ou bien les applications Java peuvent fonctionner à l'intérieur de [Tomcat](http://tomcat.apache.org/).
**Les applications 12 facteurs sont complètement auto-contenues** et ne se basent pas sur l'injection au moment de l'exécution d'un serveur web dans l'environnement d'exécution pour créer les services exposés au web. L'application web **expose HTTP comme un service en l'associant à un port** et écoute les requêtes qui arrivent sur ce port.
Dans un environnement de développement local, le développeur visite l'URL d'un service tel que `http://localhost:5000/` pour accéder au service exporté par leur application. Durant le déploiement, une couche de routage gère le routage des requêtes depuis un nom d'hôte qui s'expose au public, vers les processus sur lequel est associé le port.
Ceci est typiquement implémenté en utilisant [la déclaration de dépendances](./dependencies) pour ajouter une bibliothèque de serveur web, tel que [Tornado](http://www.tornadoweb.org/) pour Python, [Thin](http://code.macournoyer.com/thin/) pour Ruby, ou [Jetty](http://www.eclipse.org/jetty/) pour Java et autres langages basés sur la JVM. Cela se déroule entièrement dans l'espace utilisateur, c'est-à -dire, dans le code de l'application. Le contrat avec l'environnement d'exécution, c'est l'association de port pour servir les requêtes.
HTTP n'est pas le seul service qui peut être exporté à l'aide d'association de ports. Presque tout type de serveur peut fonctionner à travers l'association à un port et l'écoute des requêtes entrantes. Il y a par exemple [ejabberd](http://www.ejabberd.im/) (qui parle [XMPP](http://xmpp.org/)), et [Redis](http://redis.io/) (qui parle le [protocole Redis](http://redis.io/topics/protocol)).
Notez également que l'approche par association de port signifie qu'une application peut devenir le [service externe](./backing-services) d'une autre application, en fournissant l'URL de l'application externe dans la configuration de l'application qui la consomme.
content/pl/dependencies.md 0000644 0001750 0005670 00000006165 15226251677 014365 0 ustar 00 0000000 0000000 ## II. Dependencies
### Jawnie zadeklaruj i wydziel zależności
Większość języków programowania oferuje narzędzia do dystrybucji dodatkowych bibliotek, takie jak [CPAN](http://www.cpan.org/) dla Perla lub [Rubygems](http://rubygems.org/) dla języka Ruby. Biblioteki zainstalowane w ten sposób mogą być dostępne dla całego systemu (określane jako "site packages") lub zakres ich działania może być ograniczony dla pojedynczego projektu lub aplikacji (określane jako "vendoring" lub "bundling").
**Aplikacja 12factor nigdy nie jest zależna od bibliotek zainstalowanych dla całego systemu.** Wszystkie zależności są dokładnie określone przez dokument zawierający ich kompletną listę (*dependency declaration manifest*). Ponadto taka aplikacja korzysta z narzędzia służącego do izolacji tych zależności podczas działania aplikacji. W ten sposób ma się pewność, że np. jakaś biblioteka nie jest przypadkiem jedną z tych zainstalowanych w zewnętrznym środowisku, w którym działa aplikacja. Inaczej podobna sytuacja mogłaby uniemożliwiać poprawne działanie aplikacji w innym środowisku, gdzie takiej biblioteki by brakowało. Pełna i dokładna specyfikacja bibliotek używanych przez aplikację jest identyczna dla zarówno środowiska developerskiego jak i produkcyjnego.
Np. [Bundler](https://bundler.io/) dla Ruby'ego używa pliku `Gemfile` dla deklaracji bibliotek z których korzysta aplikacja oraz komendę `bundle exec` do izolacji tych zależności. W Pythonie istnieją dwa oddzielne narzędzia dla tych zadań -- [Pip](http://www.pip-installer.org/en/latest/) jest używany do deklaracji oraz [Virtualenv](http://www.virtualenv.org/en/latest/) do izolacji. Nawet język C posiada narzędzie [Autoconf](http://www.gnu.org/s/autoconf/) do deklaracji zależności, a statyczne wiązania mogą zapewnić izolację zależności. Bez względu na użyte narzędzia, deklaracja i izolacja zależności muszą być zawsze stosowane razem. Użycie tylko jednej z nich nie jest wystarczające by spełnić wymogi 12factor.
Jedną z niewątpliwych korzyści deklaracji zależności jest uproszczenie początkowej konfiguracji aplikacji dla developera. Nowy programista może pobrać kod źródłowy z repozytorium. Następnie, posiadając wcześniej skonfigurowane środowisko danego języka i narzędzie do zarządzania jego bibliotekami, jest w stanie zainstalować wszystkie moduły i biblioteki potrzebne dla działania aplikacji przy pomocy jednej komendy. Taką komendą np. dla Ruby'ego/Bundlera jest `bundle install`, a dla Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) jest to `lein deps`.
Aplikacje zgodne z 12factor również nie są zależne od systemowych narzędzi. Wśród przykładów można wymienić ImageMagick czy też `curl`. Pomimo, że narzędzia te mogą być dostępne na wielu lub nawet większości systemów, nie ma gwarancji, że będą istniały na wszystkich środowiskach, w których będzie uruchamiana aplikacja w przyszłości lub że ich wersja będzie kompatybilna. Jeśli aplikacja korzysta z jakiegokolwiek systemowego narzędzia, powinno być ono osobno do niej dołączone.
content/tr/who.md 0000644 0001750 0005670 00000000242 15226251677 012534 0 ustar 00 0000000 0000000 Bu belgeyi kim okumalı?
=======================
Herhangi bir çalışan uygulama geliştirenler. Bu tür uygulamaları dağıtan ve yöneten Ops mühendisleri.
content/fr/intro.md 0000644 0001750 0005670 00000002424 15226251677 013060 0 ustar 00 0000000 0000000 Introduction
============
À l'époque actuelle, les logiciels sont régulièrement délivrés en tant que services : on les appelle des *applications web* (web apps), ou *logiciels en tant que service* (*software-as-a-service*). L'application 12 facteurs est une méthodologie pour concevoir des logiciels en tant que service qui :
* Utilisent des formats déclaratifs pour mettre en oeuvre l'automatisation, pour minimiser le temps et les coûts pour que de nouveaux développeurs rejoignent le projet;
* Ont un **contrat propre** avec le système d'exploitation sous-jacent, offrant une **portabilité maximum** entre les environnements d'exécution;
* Sont adaptés à des **déploiements** sur des **plateformes cloud** modernes, rendant inutile le besoin de serveurs et de l'administration de systèmes;
* **Minimisent la divergence** entre le développement et la production, ce qui permet le *déploiement continu* pour une agilité maximum;
* et peuvent **grossir verticalement** sans changement significatif dans les outils, l'architecture ou les pratiques de développement;
La méthodologie 12 facteurs peut être appliquée à des applications écrites dans tout langage de programmation, et qui utilisent tout type de services externes (base de données, file, cache mémoire, etc.)
content/pt_br/port-binding.md 0000644 0001750 0005670 00000004136 15226251677 015022 0 ustar 00 0000000 0000000 ## VII. VÃnculo de Portas
### Exporte serviços via vÃnculo de portas
Apps web as vezes são executadas dentro de container de servidor web. Por exemplo, apps PHP podem rodar como um módulo dentro do [Apache HTTPD](http://httpd.apache.org/), ou apps Java podem rodar dentro do [Tomcat](http://tomcat.apache.org/).
**O aplicativo doze-fatores é completamente auto-contido** e não depende de injeções de tempo de execução de um servidor web em um ambiente de execução para criar um serviço que defronte a web. O app web **exporta o HTTP como um serviço através da vÃnculação a uma porta**, e escuta as requisições que chegam na mesma.
Num ambiente de desenvolvimento local, o desenvolvedor visita a URL de um serviço como `http://localhost:5000/` para acessar o serviço exportado pelo seu app. Num deploy, uma camada de roteamento manipula as requisições de rotas vindas de um hostname público para os processos web atrelados às portas.
Isso é tipicamente implementado usando [declaração de dependências](./dependencies) para adicionar uma biblioteca de servidor ao app, tal como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, ou [Jetty](http://www.eclipse.org/jetty/) para Java e outra linguagens baseadas na JVM. Isso acontece completamente no *espaço do usuário*, isso é, dentro do código do app. O contrato com o ambiente de execução é vincular a uma porta para servir requisições.
HTTP não é o único serviço que pode ser exportado via vÃnculo de portas. Quase todos os tipos de software servidores podem rodar via um processo vinculado a uma porta e aguardar as requisições chegar. Exemplos incluem [ejabberd](http://www.ejabberd.im/) (comunicando via [XMPP](http://xmpp.org/)), e [Redis](http://redis.io/) (comunicando via [protocolo Redis](http://redis.io/topics/protocol)).
Note que a abordagem de vincular portas significa que um app pode se tornar o [serviço de apoio](./backing-services) para um outro app, provendo a URL do app de apoio como um identificador de recurso na [configuração](./config) para o app consumidor.
content/th/config.md 0000644 0001750 0005670 00000014500 15226251677 013174 0 ustar 00 0000000 0000000 ## III. Config
### จัดเà¸�็บà¸�ารตั้งค่า (config) ไว้ในสิ่งà¹�วดล้à¸à¸¡à¸‚à¸à¸‡à¸£à¸°à¸šà¸š
*à¸�ารตั้งค่า (config)* ขà¸à¸‡ app เป็นสิ่งที่เปลี่ยนà¹�ปลงระหว่าง [deploys](./codebase) (staging, production, developer environments เป็นต้น) รวมทั้ง:
* ทรัพยาà¸�รที่จัดà¸�ารà¸�ับà¸�านข้à¸à¸¡à¸¹à¸¥, Memcached, à¹�ละ [backing services](./backing-services) à¸à¸·à¹ˆà¸™à¹†
* ข้à¸à¸¡à¸¹à¸¥à¸›à¸£à¸°à¸ˆà¸³à¸•ัว (credentials) สำหรับบริà¸�ารภายนà¸à¸� à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ Amazon S3 หรืภTwitter
* ค่า Pre-deploy à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ canonical hostname สำหรับ deploy
บางครั้ง app เà¸�็บà¸�ารตั้งค่าเป็นค่าคงทีใน code เป็นà¸�ารละเมิด twelve-factor ซึ่งต้à¸à¸‡à¸�ารให้ **à¹�ยà¸�à¸�ารตั้งค่าà¸à¸à¸�จาà¸� code à¸à¸¢à¹ˆà¸²à¸‡à¸ªà¸¡à¸šà¸¹à¸£à¸“์** à¸�ารตั้งค่าสามารถเปลี่ยนà¹�ปลงได้ตาม deploy ที่ไม่à¸à¸¢à¸¹à¹ˆà¹ƒà¸™ code
à¸�ารทดสà¸à¸š litmus เพื่à¸à¸”ูว่า app มีà¸�ารเà¸à¸²à¸�ารตั้งค่าทั้งหมดà¸à¸à¸�จาà¸� code ถูà¸�ต้à¸à¸‡à¸«à¸£à¸·à¸à¹„ม่ ทำให้ codebase สามารถ open source ได้ตลà¸à¸”เวลา โดยไม่à¸�ระทบà¸�ับ credential ใดๆ
โปรดทราบว่าà¸�ารนิยามนี้ขà¸à¸‡ "à¸�ารตั้งค่า" **ไม่**รวมà¸�ารตั้งค่า internal application à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ `config/routes.rb` ใน Rails หรืภ[code modules เชื่à¸à¸¡à¸•่à¸à¸�ันà¸à¸¢à¹ˆà¸²à¸‡à¹„ร](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) ใน [Spring](http://spring.io/) ชนิดขà¸à¸‡à¸�ารตั้งค่าเหล่านี้ไม่เปลี่ยนà¹�ปลงตาม deploy à¹�ละควรจะà¸à¸¢à¸¹à¹ˆà¹ƒà¸™ code
à¸à¸µà¸�วิธีà¸�ารหนึ่งขà¸à¸‡à¸�ารตั้งค่าคืà¸à¸�ารใช้ไฟล์à¸�ารตั้งค่าซึ่งไม่รวมไว้ใน revision control à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ `config/database.yml` ใน Reals ซึ่งเป็นà¸�ารพัฒนาสำหรับà¸�ารใช้ค่าคงที่ซึ่งถูà¸�รวมเข้าไปใน code repo à¹�ต่à¸�็ยังมีจุดà¸à¹ˆà¸à¸™à¸„ืà¸à¸¡à¸±à¸™à¸ˆà¸°à¹€à¸�ิดความผิดพลาดจาà¸�à¸�ารที่รวมค่าà¸�ารตั้งค่านี้เข้าไปใน repo จะทำให้มีà¹�นวโน้มที่à¸�ารไฟล์à¸�ารตั้งค่าจะà¸�ระจายà¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¸—ี่à¹�ตà¸�ต่างà¸�ันà¹�ละà¹�ตà¸�ต่างรูปà¹�บบ ทำให้มันยาà¸�ที่จะดูà¹�ลà¹�ละจัดà¸�ารà¸�ารตั้งค่าทั้งหมดในหนึ่งที่ นà¸à¸�จาà¸�นี้รูปà¹�บบเหล่านี้ยังขึ้นà¸à¸¢à¸¹à¹ˆà¸�ับภาษาคà¸à¸¡à¸žà¸´à¸§à¹€à¸•à¸à¸£à¹Œ หรืภเฉพาะ framework.
**Twelve-factor app เà¸�็บà¸�ารตั้งค่าไว้ใน *environment variable*** (เรียà¸�สั้นๆ ว่า *env vars* หรืภ*env*) Env vars จะทำให้ง่ายที่จะเปลี่ยนà¹�ปลงระหว่าง deloy โดยปราศจาà¸�à¸�ารเปลี่ยนà¹�ปลงขà¸à¸‡ code ใดๆ ไม่เหมืà¸à¸™à¸�ับไฟล์à¸�ารตั้งค่าที่จะมีโà¸à¸�ารผิดพลาดที่จะรวมเข้าไปใน code repo ได้ à¹�ละไม่เหมืà¸à¸™à¸�ับไฟล์à¸�ารตั้งค่าที่à¸�ำหนดเà¸à¸‡à¸«à¸£à¸·à¸à¸�ลไà¸�à¸�ารตั้งค่าà¸à¸·à¹ˆà¸™à¹† à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ Java System Properties ที่เป็ขà¸à¸‡à¸ าษาคà¸à¸¡à¸žà¸´à¸§à¹€à¸•à¸à¸£à¹Œ à¹�ละมาตรà¸�านขà¸à¸‡à¸£à¸°à¸šà¸šà¸›à¸�ิบัติà¸�าร (OS-agnostic)
à¸à¸µà¸�à¹�ง่มุมขà¸à¸‡à¸�ารจัดà¸�ารà¸�ารตั้งค่าคืà¸à¸�ารจัดà¸�ลุ่ม (Grouping) บางครั้งà¸�ารตั้งค่า app à¹�บบà¸�ลุ่ม (batch) ในชื่à¸à¸‚à¸à¸‡à¸�ลุ่ม (เรียà¸�ว่า "environment") หลังจาà¸� deploy เฉพาะ à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ `development`, `test` à¹�ละ `production` environment ใน Rails วิธีà¸�ารนี้ทำให้à¸�ารขยายไม่เรียบร้à¸à¸¢à¸—ำให้มี deploy ขà¸à¸‡ app ถูà¸�สร้างมาà¸�ขึ้น, จำเป็นต้à¸à¸‡à¸•ั้งชื่à¸à¸‚à¸à¸‡ environment ใหม่ à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ `staging` หรืภ`qa` เป็นตั้น เมื่ภproject โตขึ้น developer à¸à¸²à¸ˆà¸ˆà¸°à¹€à¸žà¸´à¹ˆà¸¡ environments เฉพาะขà¸à¸‡à¸•ัวเà¸à¸‡à¸‚ึ้นมา เช่น `joes-staging` ผมà¸�็คืà¸à¸¡à¸µà¸�ารตั้งค่าจำนวนมาà¸�เà¸�ินไปซึ่งทำให้จัดà¸�าร deploy ขà¸à¸‡ app ทำได้ยาà¸�มาà¸�
ใน twelve-factor app, env vars เป็นราà¸�à¸�านà¸�ารควบควมขà¸à¸‡à¹�ต่ล่ะ evn vars à¸à¸·à¹ˆà¸™à¹† ไม่เคยมีà¸�ารจัดà¸�ลุ่มเป็น "environments" à¹�ต่จะจัดà¸�ารà¹�บบà¸à¸´à¸ªà¸£à¸°à¸ªà¸³à¸«à¸£à¸±à¸šà¹�ต่ล่ะ deploy à¹�ทน นี่เป็นรูปà¹�บบที่à¸�ารขยายทำได้à¸à¸¢à¹ˆà¸²à¸‡à¸£à¸²à¸šà¸£à¸·à¹ˆà¸™à¸‚à¸à¸‡ app เป็นà¸�ารขยายโดยธรรมชาติขà¸à¸‡ deploy มาà¸�ขึ้นตลà¸à¸”à¸à¸²à¸¢à¸¸à¸�ารทำงานขà¸à¸‡ app.
content/fr/dependencies.md 0000644 0001750 0005670 00000006123 15226251677 014353 0 ustar 00 0000000 0000000 ## II. Dépendances
### Déclarez explicitement et isolez les dépendances
La plupart des langages de programmation offrent des systèmes pour créer des paquets à partir de bibliothèques afin de les distribuer, tel que [CPAN](http://www.cpan.org/) pour Perl ou [Rubygems](http://rubygems.org/) pour Ruby. Les bibliothèques installées à travers un système de packaging peuvent être installées à travers tout le système, ou bien limitées au répertoire contenant l'application (que l'on appelle les "vendor" ou "bundles").
**Une application 12 facteurs ne dépend jamais de l'existence implicite de packages au niveau du système**. Elle déclare toutes ses dépendances, complètement et exactement, à travers un manifeste de *déclaration de dépendances*. De plus, elle utilise un outil d'isolation des dépendances durant l'exécution afin d'assurer qu'aucune dépendance implicite ne s'introduise depuis le système environnant. Les spécifications complètes et explicites sont appliquées uniformément en développement comme en production.
Par exemple, [Bundler](https://bundler.io/) pour Ruby fournit le format de manifeste `Gemfile` pour la déclaration des dépendances, ainsi que la commande `bundle exec` pour l'isolation des dépendances. En python, il y a deux outils séparés pour ces étapes -- [Pip](http://www.pip-installer.org/en/latest/) est utilisé pour la déclaration et [Virtualenv](http://www.virtualenv.org/en/latest/) pour l'isolation. Même le C dispose d'[Autoconf](http://www.gnu.org/s/autoconf/) pour les déclarations de dépendances, et la liaison statique peut fournir l'isolation des dépendances. Peu importe la chaîne d'outils, la déclaration et l'isolation des dépendances doivent toujours être utilisées ensemble -- seulement l'un ou l'autre ne suffit pas à satisfaire les 12 facteurs.
Un des bénéfices de la déclaration explicite des dépendances est que cela simplifie la mise en place pour les développeurs qui découvrent l'application. Les nouveaux développeurs peuvent jeter un œil à la base de code de l'application sur leur machine de développement, en ayant besoin uniquement d'avoir de quoi exécuter le langage ainsi que le gestionnaire de dépendances installé en pré-requis. Ils pourront mettre en place tout ce qui est nécessaire pour faire fonctionner le code de l'application de manière déterministe grâce à une *commande d'assemblage* (commande de build). Par exemple, la commande d'assemblage pour Ruby/Bundler est `bundle install`, alors que pour Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'est `lein deps`.
Les applications 12 facteurs ne s'appuient pas sur l'existence implicite d'outils système, par exemple ImageMagick ou `curl`. Bien que ces outils puissent exister sur beaucoup voire la plupart des systèmes d'exploitation, il n'y a pas de garantie qu'ils existeront sur tous les systèmes où l'application sera exécutée à l'avenir, ou si la version disponible sur un système futur sera compatible avec l'application. Si l'application dépend d'un outil système, cet outil doit être distribué avec l'application.
content/pl/port-binding.md 0000644 0001750 0005670 00000004430 15226251677 014324 0 ustar 00 0000000 0000000 ## VII. Przydzielanie portów
### Udostępniaj usługi przez przydzielanie portów
Zdarza się, że aplikacje internetowe uruchamiane są w ramach serwera web. Napisane w PHP np. działają jako moduł [Apache HTTPD](http://httpd.apache.org/), natomiast aplikacje w Javie mogą być uruchomiane wewnątrz serwera aplikacji, np. [Tomcat](http://tomcat.apache.org/).
**Aplikacja 12factor nie posiada zewnętrznych zależności** co czyni ją niezależną wobec innych modułów znajdujących się na serwerze. Aplikacja internetowa **udostępniać będzie np. HTTP w formie usługi przez przydzielenie portu**. Umożliwia jej to obsługę zapytań przychodzących do wybranego portu.
Aby skorzystać z usługi udostępnionej przez aplikację, developer może otworzyć adres URL jak np. `http://localhost:5000/`. W przypadku aplikacji wdrożonej w środowisku produkcyjnym zapytania do udostępnionej publicznie nazwy hosta są obsługiwane przez warstwę nawigacji. Kierowane są one później do procesu sieciowego udostępnionego na danym porcie.
Kwestię obsługi takich zapytań można rozwiązać dodając bibliotekę webservera jako kolejną [zewnętrzną zależność](./dependencies), jak np. [Tornado](http://www.tornadoweb.org/) w Pythonie, [Thin](http://code.macournoyer.com/thin/) w Ruby, lub [Jetty](http://www.eclipse.org/jetty/) dla Javy i innych języków opierających się na JVM. Obsługa zapytania jest całkowicie oprogramowana przez kod aplikacji, natomiast kontraktem ze środowiskiem wykonawczym jest przydzielenie portu w celu obsłużenia tego zapytania.
HTTP nie jest jedyną usługą, którą możną eksportować przez przydzielenie portu. Niemal każdy rodzaj oprogramowania serwerowego może być uruchomiony przez przydzielenie portu na którym jest uruchomiony proces i oczekiwać na przychodzące zapytania. Do przykładów należą [ejabberd](http://www.ejabberd.im/) (komunikujący się przez [XMPP](http://xmpp.org/)), oraz [Redis](http://redis.io/) (komunikujący się przez [Redis protocol](http://redis.io/topics/protocol)).
Warto również zauważyć, że przez przydzielnie portu aplikacja może pełnić funkcję [usługi wspierającej](./backing-services) dla innej aplikacji przez udostępnienie swojego adresu URL jako adres zasobu w [konfiguracji](./config) tejże aplikacji.
content/en/admin-processes.md 0000644 0001750 0005670 00000004067 15226251677 015021 0 ustar 00 0000000 0000000 ## XII. Admin processes
### Run admin/management tasks as one-off processes
The [process formation](./concurrency) is the array of processes that are used to do the app's regular business (such as handling web requests) as it runs. Separately, developers will often wish to do one-off administrative or maintenance tasks for the app, such as:
* Running database migrations (e.g. `manage.py migrate` in Django, `rake db:migrate` in Rails).
* Running a console (also known as a [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) to run arbitrary code or inspect the app's models against the live database. Most languages provide a REPL by running the interpreter without any arguments (e.g. `python` or `perl`) or in some cases have a separate command (e.g. `irb` for Ruby, `rails console` for Rails).
* Running one-time scripts committed into the app's repo (e.g. `php scripts/fix_bad_records.php`).
One-off admin processes should be run in an identical environment as the regular [long-running processes](./processes) of the app. They run against a [release](./build-release-run), using the same [codebase](./codebase) and [config](./config) as any process run against that release. Admin code must ship with application code to avoid synchronization issues.
The same [dependency isolation](./dependencies) techniques should be used on all process types. For example, if the Ruby web process uses the command `bundle exec thin start`, then a database migration should use `bundle exec rake db:migrate`. Likewise, a Python program using Virtualenv should use the vendored `bin/python` for running both the Tornado webserver and any `manage.py` admin processes.
Twelve-factor strongly favors languages which provide a REPL shell out of the box, and which make it easy to run one-off scripts. In a local deploy, developers invoke one-off admin processes by a direct shell command inside the app's checkout directory. In a production deploy, developers can use ssh or other remote command execution mechanism provided by that deploy's execution environment to run such a process.
content/en/dependencies.md 0000644 0001750 0005670 00000004776 15226251677 014362 0 ustar 00 0000000 0000000 ## II. Dependencies
### Explicitly declare and isolate dependencies
Most programming languages offer a packaging system for distributing support libraries, such as [CPAN](http://www.cpan.org/) for Perl or [Rubygems](http://rubygems.org/) for Ruby. Libraries installed through a packaging system can be installed system-wide (known as "site packages") or scoped into the directory containing the app (known as "vendoring" or "bundling").
**A twelve-factor app never relies on implicit existence of system-wide packages.** It declares all dependencies, completely and exactly, via a *dependency declaration* manifest. Furthermore, it uses a *dependency isolation* tool during execution to ensure that no implicit dependencies "leak in" from the surrounding system. The full and explicit dependency specification is applied uniformly to both production and development.
For example, [Bundler](https://bundler.io/) for Ruby offers the `Gemfile` manifest format for dependency declaration and `bundle exec` for dependency isolation. In Python there are two separate tools for these steps -- [Pip](http://www.pip-installer.org/en/latest/) is used for declaration and [Virtualenv](http://www.virtualenv.org/en/latest/) for isolation. Even C has [Autoconf](http://www.gnu.org/s/autoconf/) for dependency declaration, and static linking can provide dependency isolation. No matter what the toolchain, dependency declaration and isolation must always be used together -- only one or the other is not sufficient to satisfy twelve-factor.
One benefit of explicit dependency declaration is that it simplifies setup for developers new to the app. The new developer can check out the app's codebase onto their development machine, requiring only the language runtime and dependency manager installed as prerequisites. They will be able to set up everything needed to run the app's code with a deterministic *build command*. For example, the build command for Ruby/Bundler is `bundle install`, while for Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) it is `lein deps`.
Twelve-factor apps also do not rely on the implicit existence of any system tools. Examples include shelling out to ImageMagick or `curl`. While these tools may exist on many or even most systems, there is no guarantee that they will exist on all systems where the app may run in the future, or whether the version found on a future system will be compatible with the app. If the app needs to shell out to a system tool, that tool should be vendored into the app.
content/en/disposability.md 0000644 0001750 0005670 00000005256 15226251677 014605 0 ustar 00 0000000 0000000 ## IX. Disposability
### Maximize robustness with fast startup and graceful shutdown
**The twelve-factor app's [processes](./processes) are *disposable*, meaning they can be started or stopped at a moment's notice.** This facilitates fast elastic scaling, rapid deployment of [code](./codebase) or [config](./config) changes, and robustness of production deploys.
Processes should strive to **minimize startup time**. Ideally, a process takes a few seconds from the time the launch command is executed until the process is up and ready to receive requests or jobs. Short startup time provides more agility for the [release](./build-release-run) process and scaling up; and it aids robustness, because the process manager can more easily move processes to new physical machines when warranted.
Processes **shut down gracefully when they receive a [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** signal from the process manager. For a web process, graceful shutdown is achieved by ceasing to listen on the service port (thereby refusing any new requests), allowing any current requests to finish, and then exiting. Implicit in this model is that HTTP requests are short (no more than a few seconds), or in the case of long polling, the client should seamlessly attempt to reconnect when the connection is lost.
For a worker process, graceful shutdown is achieved by returning the current job to the work queue. For example, on [RabbitMQ](http://www.rabbitmq.com/) the worker can send a [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); on [Beanstalkd](https://beanstalkd.github.io), the job is returned to the queue automatically whenever a worker disconnects. Lock-based systems such as [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) need to be sure to release their lock on the job record. Implicit in this model is that all jobs are [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), which typically is achieved by wrapping the results in a transaction, or making the operation [idempotent](http://en.wikipedia.org/wiki/Idempotence).
Processes should also be **robust against sudden death**, in the case of a failure in the underlying hardware. While this is a much less common occurrence than a graceful shutdown with `SIGTERM`, it can still happen. A recommended approach is use of a robust queueing backend, such as Beanstalkd, that returns jobs to the queue when clients disconnect or time out. Either way, a twelve-factor app is architected to handle unexpected, non-graceful terminations. [Crash-only design](http://lwn.net/Articles/191059/) takes this concept to its [logical conclusion](http://docs.couchdb.org/en/latest/intro/overview.html).
content/it/logs.md 0000644 0001750 0005670 00000004770 15226251677 012704 0 ustar 00 0000000 0000000 ## XI. Log
### Tratta i log come stream di eventi
I *log* offrono una maggiore chiarezza riguardo un comportamento di un'app in esecuzione. In ambienti basati su server, questi sono tendenzialmente scritti su un file su disco (logfile). A ogni modo, è solo un formato.
Un log può essere definito infatti come uno [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) di eventi aggregati e ordinati cronologicamente. Tali eventi vengono presi da tutti i vari output stream presenti di tutti i processi attivi, oltre che dai vari backing service. Nella loro forma grezza, i log si presentano come un file di testo con un evento per ogni linea (con le dovute eccezioni). Non hanno un inizio o una fine ben definiti, ma un continuo di informazioni fin quando l'applicazione è al lavoro.
**Un'applicazione twelve-factor non dovrebbe preoccuparsi di lavorare con il proprio output stream.** Non dovrebbe lavorare o comunque gestire i vari logfile. Dovrebbe, invece, fare in modo che ogni processo si occupi di scrivere il proprio stream di eventi su "`stdout`". Durante lo sviluppo in locale, quindi, lo sviluppatore potrà visionare lo stream in modo completo direttamente dal terminale, per capire meglio il comportamento della sua applicazione.
In staging o in produzione, invece, ogni stream viene "preso" dall'ambiente di esecuzione ed elaborato insieme a tutti gli altri stream dell'applicazione, quindi indirizzato verso una o più "destinazioni" finali per la visualizzazione e archiviazione a lungo termine. Queste "destinazioni" non sono visibili o configurabili, ma vengono gestite totalmente dall'ambiente di esecuzione. Per questi scopi esistono strumenti come [Logplex](https://github.com/heroku/logplex) e [Fluentd](https://github.com/fluent/fluentd)).
Uno stream di eventi di un'applicazione può essere quindi indirizzato verso un file, o visionato in tempo reale su un terminale. Ancora, lo stream può essere inviato a un sistema di analisi e indicizzazione di log, come [Splunk](http://www.splunk.com/), oppure a un sistema di memorizzazione general-purpose come [Hadoop/Hive](http://hive.apache.org/). Questi sistemi hanno ottimi tool per effettuare un lavoro di analisi del comportamento dell'applicazione, come per esempio:
* Ricerca di specifici eventi nel passato;
* Grafici per rappresentare dei trend (es. richieste per minuto);
* Attivazione di alert specifici in base a regole definite dall'utente (es. alert avverte l'amministratore se il rate di eventi al minuto sale oltre una certa soglia);
content/ru/config.md 0000644 0001750 0005670 00000014634 15226251677 013217 0 ustar 00 0000000 0000000 ## III. Конфигураци�
### Сохран�йте конфигурацию в �реде выполнени�
*КонфигурациÑ�* приложениÑ� -- Ñ�то вÑ�Ñ‘, что может менÑ�тьÑ�Ñ� между [развёртываниÑ�ми](./codebase) (Ñ�реда разработки, промежуточное и рабочее развёртывание). Ðто включает в Ñ�ебÑ�:
* Идентификаторы подключени� к ре�ур�ам типа базы данных, к�ш-пам�ти и другим [�торонним �лужбам](./backing-services)
* Реги�трационные данные дл� подключени� к внешним �ерви�ам, например, к Amazon S3 или Twitter
* Значени� зави�имые от �реды развёртывани� такие, как канониче�кое им� хо�та
Иногда приложениÑ� хранÑ�Ñ‚ конфигурации как конÑ�танты в коде. Ðто нарушение методологии двенадцати факторов, котораÑ� требует **Ñ�трогого разделениÑ� конфигурации и кода**. КонфигурациÑ� может Ñ�ущеÑ�твенно различатьÑ�Ñ� между развёртываниÑ�ми, код не должен различатьÑ�Ñ�.
Лакму�овой бумажкой того, правильно ли разделены конфигураци� и код приложени�, �вл�ет�� факт того, что кодова� база приложени� может быть в любой момент открыта в �вободный до�туп без компрометации каких-либо приватных данных.
Обратите внимание, что Ñ�то определение "конфигурации" **не** включает внутренние конфигурации приложениÑ�, например такие как 'config/routes.rb' в Rails, или того как [оÑ�новные модули будут Ñ�вÑ�заны](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) в [Spring](http://spring.io/). Ðтот тип конфигурации не менÑ�етÑ�Ñ� между развёртываниÑ�ми и поÑ�тому лучше вÑ�его держать его в коде.
Другим подходом к конфигурации Ñ�влÑ�етÑ�Ñ� иÑ�пользование конфигурационных файлов, которые не Ñ�охранÑ�ÑŽÑ‚Ñ�Ñ� в Ñ�иÑ�тему контролÑ� верÑ�иÑ�, например 'config/database.yml' в Rails. Ðто огромное улучшение перед иÑ�пользованием конÑ�тант, которые Ñ�охранÑ�ÑŽÑ‚Ñ�Ñ� в коде, но по-прежнему и у Ñ�того метода еÑ�ть недоÑ�татки: легко по ошибке Ñ�охранить конфигурационный файл в репозиторий; Ñ�ущеÑ�твует тенденциÑ� когда конфигурационные файлы разброÑ�аны в разных меÑ�тах и в разных форматах, из за Ñ�того Ñ�тановитÑ�Ñ� трудно проÑ�матривать и управлÑ�ть вÑ�еми наÑ�тройками в одном меÑ�те. Кроме того форматы Ñ�тих файлов, как правило, Ñ�пецифичны длÑ� конкретного Ñ�зыка или фреймворка.
**Приложение двенадцати факторов хранит конфигурацию в *переменных окружени�*** (ча�то �окращает�� до *env vars* или *env*). Переменные окружени� легко изменить между развёртывани�ми, не измен�� код; в отличие от файлов конфигурации, менее веро�тно �лучайно �охранить их в репозиторий кода; и в отличие от пользователь�ких конфигурационных файлов или других механизмов конфигурации, таких как Java System Properties, они �вл�ют�� незави�имым от �зыка и операционной �и�темы �тандартом.
Другим подходом к управлению конфигурациÑ�ми Ñ�влÑ�етÑ�Ñ� группировка. Иногда приложениÑ� группируют конфигурации в именованные группы (чаÑ�то называемые "окружениÑ�ми") названые по названию конкретного развёртываниÑ�, например как `development`, `test` и `production` окружениÑ� в Rails. Ðтот метод не Ñ�влÑ�етÑ�Ñ� доÑ�таточно маÑ�штабируемым: чем больше различных развёртываний приложениÑ� Ñ�оздаётÑ�Ñ�, тем больше новых имён окружений необходимо, например `staging` и `qa`. При дальнейшем роÑ�те проекта, разработчики могут добавлÑ�ть Ñ�вои Ñ�обÑ�твенные Ñ�пециальные окружениÑ�, такие как `joes-staging`, в результате проиÑ�ходит комбинаторный взрыв конфигураций, который делает управление развёртываниÑ�ми приложениÑ� очень хрупким.
Ð’ приложении двенадцати факторов переменные окружениÑ� Ñ�влÑ�ÑŽÑ‚Ñ�Ñ� не Ñ�вÑ�занными между Ñ�обой Ñ�редÑ�твами управлениÑ�, где каждаÑ� переменнаÑ� окружениÑ� полноÑ�тью незавиÑ�има от других. Они никогда не группируютÑ�Ñ� вмеÑ�те в "окружениÑ�", а вмеÑ�то Ñ�того управлÑ�ÑŽÑ‚Ñ�Ñ� незавиÑ�имо длÑ� каждого развёртываниÑ�. Ðта модель котораÑ� маÑ�штабируетÑ�Ñ� поÑ�тепенно вмеÑ�те Ñ� еÑ�теÑ�твенным поÑ�влением большего количеÑ�тва развёртываний приложениÑ� за времÑ� его жизни.
views/layout.erb 0000644 0001750 0005670 00000003610 15226251677 012464 0 ustar 00 0000000 0000000
The Twelve-Factor App <%= I18n.t(:translation) %>
<% if ENV['GOOGLE_TAG_MANAGER_ACCOUNT'] %>
<% end %>
<%= yield %>
web.rb 0000644 0001750 0005670 00000003771 15226251677 010432 0 ustar 00 0000000 0000000 require 'sinatra'
require 'maruku'
require 'i18n'
require 'rack/ssl-enforcer'
configure do
# For Development use only!
set :host_authorization, { permitted_hosts: [] }
use Rack::SslEnforcer if ENV['FORCE_SSL']
I18n.enforce_available_locales = true
I18n.load_path += Dir[File.join(settings.root, 'locales', '*.yml')]
# I18n.available_locales = Dir[File.join(settings.root, 'locales', '*.yml')].map { |f| File.basename(f, '.yml').to_sym }
# I18n.available_locales = [:en, :pt]
I18n.backend.load_translations
I18n.default_locale = :en
end
before do
I18n.locale = I18n.default_locale
end
before '/:locale/*' do
locale = params[:locale].to_sym
if locale != I18n.default_locale && I18n.available_locales.include?(locale)
I18n.locale = locale
request.path_info = '/' + params[:splat][0]
end
end
get '/' do
erb :home
end
TOC = %w(codebase dependencies config backing-services build-release-run processes port-binding concurrency disposability dev-prod-parity logs admin-processes)
get '/:factor' do |factor|
halt 404 unless TOC.include?(factor)
@factor = factor
erb :factor
end
helpers do
def render_markdown(file)
markdown = File.read("content/#{I18n.locale}/#{file}.md", :encoding => 'utf-8')
Maruku.new(markdown).to_html
rescue Errno::ENOENT
puts "No content for #{I18n.locale}/#{file}, skipping"
end
def render_prev(factor)
idx = TOC.index(factor)
return if idx == 0
"« Previous "
end
def render_next(factor)
idx = TOC.index(factor)
return if idx == TOC.size-1
"Next » "
end
def render_locales(factor)
I18n.available_locales.map {|locale|
if locale == I18n.locale
"#{I18n.t(:language)} "
else
path_prefix = locale == I18n.default_locale ? "" : "/#{locale}"
"#{I18n.t(:language, :locale => locale)} "
end
}.join(" | ")
end
end
not_found do
"Page not found"
end
content/en/who.md 0000644 0001750 0005670 00000000262 15226251677 012513 0 ustar 00 0000000 0000000 Who should read this document?
==============================
Any developer building applications which run as a service. Ops engineers who deploy or manage such applications.
content/it/dev-prod-parity.md 0000644 0001750 0005670 00000011215 15226251677 014756 0 ustar 00 0000000 0000000 ## X. Parità tra Sviluppo e Produzione
### Mantieni lo sviluppo, staging e produzione simili il più possibile
Storicamente, ci sono sempre state differenze sostanziali tra gli ambienti di sviluppo (lo sviluppatore che effettua delle modifiche live a un [deployment](./codebase) in locale) e quello di produzione (un deployment in esecuzione raggiungibile dagli utenti finali). Differenze (o gap) che si possono raggruppare in tre categorie:
* **Tempo:** uno sviluppatore può lavorare sul codice per giorni, settimane o mesi prima di poter andare in produzione;
* **Personale**: gli sviluppatori scrivono il codice, gli ops effettuano il deployment;
* **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite e OS X, mentre in produzione per il deployment verrebbero installati Apache, MySQL e Linux.
**Un'applicazione twelve-factor è progettata per il [rilascio continuo](http://avc.com/2011/02/continuous-deployment/), tenendo così queste differenze al minimo possibile.** A proposito di queste tre tipologie di differenze appena viste:
* Rendi la differenze temporali minime: cerca di scrivere (o far scrivere) del codice da rilasciare nel giro di poche ore, se non minuti;
* Rendi le differenze a livello di personale minime: fai in modo che gli sviluppatori siano coinvolti anche nella fase di deploy, per permettere loro di osservare il comportamento di ciò che hanno scritto anche in produzione;
* Rendi le differenze a livello di strumenti minime: mantieni gli ambienti di lavoro il più simile possibile;
Riassumendo tutto in una tabella:
App Tradizionale
App Twelve-factor
Tempo tra i Deployment
Settimane
Ore
Sviluppatori e Ops
Sono diversi
Sono gli stessi
Sviluppo e Produzione
Divergenti
Il più simili possibile
I [backing service](./backing-services), come il database dell'applicazione o la cache, sono una delle aree in cui la parità degli ambienti è molto importante. Molti linguaggi offrono delle librerie che facilitano l'accesso a questi servizi, tra cui anche degli adattatori per questi tipi di servizi. Eccone alcuni:
Tipologia
Linguaggio
Libreria
Adattatore
Database
Ruby/Rails
ActiveRecord
MySQL, PostgreSQL, SQLite
Code
Python/Django
Celery
RabbitMQ, Beanstalkd, Redis
Cache
Ruby/Rails
ActiveSupport::Cache
Memory, filesystem, Memcached
Gli sviluppatori, inoltre, trovano utile usare dei servizi "leggeri" in fase di sviluppo, passando quindi a qualcosa di più serio e robusto in produzione. Per esempio, usando SQLite localmente e PostgreSQL in produzione. Ancora, un sistema di cache in locale in fase di sviluppo e Memcached in produzione.
**Lo sviluppatore twelve-factor "resiste" a questa necessità **, anche se gli adapter ci sono e funzionano in modo tale da astrarre in modo sufficiente tutte le differenze nella gestione. Nulla impedisce, infatti, a qualche altra incompatibilità di uscire allo scoperto quando meno ce lo si aspetta, soprattutto se in ambiente di sviluppo funziona tutto e poi, magari, in produzione i test non vengono superati. Il costo di questa differenza può risultare abbastanza alto, soprattutto in situazioni in cui si effettua il rilascio continuo.
Rispetto al passato, usare dei sistemi "light" in locale è una prassi poco convincente. Si pensi al fatto che alcuni servizi moderni come Memcached o PostgreSQL si possono installare e usare senza difficoltà tramite alcuni sistemi di packaging come [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). In alternativa, esistono anche alcuni tool di provisioning come [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/), che combinati con sistemi di ambienti virtuali come [Vagrant](http://vagrantup.com/) permettono agli sviluppatori di riprodurre in locale delle macchine molto simili, se non identiche, a quelle in produzione. Ne risente quindi positivamente il costo di deployment.
Tutto questo, sia chiaro, non rende gli adapter meno utili: grazie ad essi infatti il porting verso nuovi servizi, in un secondo momento, rimane un processo indolore. Nonostante questo, comunque, rimane scontato che sarebbe buona norma usare uno stesso backing service su tutti i deployment di un'applicazione.
content/zh_cn/concurrency.md 0000644 0001750 0005670 00000004405 15226251677 014752 0 ustar 00 0000000 0000000 ## VIII. 并�
### 通过进程模型进行扩展
任何计算机程åº�,一旦å�¯åŠ¨ï¼Œå°±ä¼šç”Ÿæˆ�一个或多个进程。互è�”网应用采用多ç§�进程è¿�行方å¼�。例如,PHP 进程作为 Apache çš„å�进程å˜åœ¨ï¼Œéš�请求按需å�¯åŠ¨ã€‚Java 进程则采å�–了相å��的方å¼�,在程åº�å�¯åЍ之åˆ� JVM å°±æ��供了一个超级进程储备了大é‡�的系统资æº�(CPU 和内å˜),并通过多线程实现内部的并å�‘管ç�†ã€‚上述 2 个例å�ä¸ï¼Œè¿›ç¨‹æ˜¯å¼€å�‘人员å�¯ä»¥æ“�作的最å°�å�•ä½�。

**在 12-factor 应用ä¸ï¼Œè¿›ç¨‹æ˜¯ä¸€ç‰å…¬æ°‘。**12-Factor 应用的进程主è¦�借鉴于 [unix 守护进程模型](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开å�‘人员å�¯ä»¥è¿�用这个模型去设计应用架构,将ä¸�å�Œçš„工作分é…�ç»™ä¸�å�Œçš„ *进程类型* 。例如,HTTP 请求å�¯ä»¥äº¤ç»™ web 进程æ�¥å¤„ç�†ï¼Œè€Œå¸¸é©»çš„å�Žå�°å·¥ä½œåˆ™äº¤ç”± worker 进程负责。
这并ä¸�包括个别较为特殊的进程,例如通过虚拟机的线程处ç�†å¹¶å�‘的内部è¿�算,或是使用诸如 [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异æ¥/事件触å�‘模型。但一å�°ç‹¬ç«‹çš„虚拟机的扩展有瓶颈(垂直扩展),所以应用程åº�å¿…é¡»å�¯ä»¥åœ¨å¤šå�°ç‰©ç�†æœºå™¨é—´è·¨è¿›ç¨‹å·¥ä½œã€‚
上述进程模型会在系统急需扩展时大放异彩。 [12-Factor åº”ç”¨çš„è¿›ç¨‹æ‰€å…·å¤‡çš„æ— å…±äº«ï¼Œæ°´å¹³åˆ†åŒºçš„ç‰¹æ€§](./processes) æ„�味ç�€æ·»åŠ å¹¶å�‘会å�˜å¾—简å�•而稳妥。这些进程的类型以å�Šæ¯�个类型ä¸è¿›ç¨‹çš„æ•°é‡�就被称作 *进程构æˆ�* 。
12-Factor 应用的进程 [ä¸�需è¦�守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入 PID 文件。相å��的,应该借助æ“�作系统的进程管ç�†å™¨(例如 [systemd](https://www.freedesktop.org/wiki/Software/systemd/) ,分布å¼�的进程管ç�†äº‘å¹³å�°ï¼Œæˆ–是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),æ�¥ç®¡ç�† [输出æµ�](./logs) ,å“�应崩溃的进程,以å�Šå¤„ç�†ç”¨æˆ·è§¦å�‘çš„é‡�å�¯å’Œå…³é—超级进程的请求。
content/de/dev-prod-parity.md 0000644 0001750 0005670 00000011154 15226251677 014734 0 ustar 00 0000000 0000000 ##X. Dev-Prod-Vergleichbarkeit
### Entwicklung, Staging und Produktion so ähnlich wie möglich halten
Historisch gibt es große Lücken zwischen Entwicklung (wo ein Entwickler live an einem lokalen [Deploy](./codebase) der App Änderungen macht) und Produktion (ein laufender Deploy der App, auf den Endbenutzer zugreifen). Diese Lücken zeigen sich auf drei Gebieten:
* **Die Zeit-Lücke** Ein Entwickler arbeitet an Code der Tage, Wochen oder sogar Monate braucht um in Produktion zu gehen.
* **Die Personal-Lücke**: Entwickler schreiben Code, Operatoren deployen ihn.
* **Die Werkzeug-Lücke**: Entwickler nutzen vielleicht einen Stack wie Nginx, SQLite und OS X - die Produktion nutzt Apache, MySQL und Linux.
**Die Zwölf-Faktor-App ist ausgelegt auf [Continuous Deployment](http://avc.com/2011/02/continuous-deployment/) indem sie die Lücke zwischen Entwicklung und Produktion klein hält.** Mit Blick auf die oben beschriebenen drei Lücken:
* Die Zeit-Lücke klein halten: Ein Entwickler kann Code schreiben, der Stunden oder sogar Minuten später deployed wird.
* Die Personal-Lücke klein halten: Entwickler die Code schreiben sind intensiv am Deployment und der Überwachung des Verhaltens auf Produktion beteiligt.
* Die Werkzeug-Lücke klein halten: Entwicklung und Produktion so ähnlich wie möglich halten.
Das Gesagte in einer Tabelle:
Traditionelle App
Zwölf-Faktor-App
Zeit zwischen Deployments
Wochen
Stunden
Code-Autoren und Code-Deployer
Andere Menschen
Dieselben Menschen
Entwicklungs- und Produktions-Umgebung
Unterschiedlich
So ähnlich wie möglich
Im Bereich der [unterstützenden Dienste](./backing-services) wie der Datenbank der App, dem Queue-System oder dem Cache ist die Dev-Prod-Vergleichbarkeit wichtig. Viele Sprachen bieten Bibliotheken, die den Zugriff auf die unterstützenden Dienste vereinfachen und ebenso *Adapter* für unterschiedliche Arten von Diensten.
Art
Sprache
Bibliothek
Adapter
Datenbank
Ruby/Rails
ActiveRecord
MySQL, PostgreSQL, SQLite
Queue
Python/Django
Celery
RabbitMQ, Beanstalkd, Redis
Cache
Ruby/Rails
ActiveSupport::Cache
Speicher, Dateisystem, Memcached
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.
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 Dienstes benutzen.
content/ru/logs.md 0000644 0001750 0005670 00000010746 15226251677 012716 0 ustar 00 0000000 0000000 ## XI. Журналирование (Logs)
### Ра��матривайте журнал как поток �обытий
*Журналирование* обе�печивает нагл�дное пред�тавление поведени� работающего приложени�. Обычно в �ерверной �реде журнал запи�ывает�� в файл на ди�ке ("logfile"), но �то только один из форматов вывода.
Журнал -- �то [поток](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упор�доченных по времени �обытий, �обранных из потоков вывода в�ех запущенных проце��ов и в�помогательных �ерви�ов. Журнал в �воём �ыром виде обычно пред�тавлен тек�товым форматом � одним �обытием на �трочку (хот� тра��ировки и�ключений могут занимать не�колько �трок). Журнал не имеет фик�ированного начала и конца, поток �ообщений непрерывен, пока работает приложение.
**Приложение двенадцати факторов никогда не занимает�� маршрутизацией и хранением �воего потока вывода.** Приложение не должно запи�ывать журнал в файл и управл�ть файлами журналов. Вме�то �того каждый выполн�ющий�� проце�� запи�ывает �вой поток �обытий без буферизации в �тандартный вывод `stdout`. Во врем� локальной разработки разработчик имеет возможно�ть про�матривать �тот поток в терминале, чтобы наблюдать за поведением приложени�.
При промежуточном и рабочем развёртывании поток вывода каждого процеÑ�Ñ�а будет захвачен Ñ�редой выполнениÑ�, Ñ�обран вмеÑ�те Ñ�о вÑ�еми другими потоками вывода приложениÑ� и перенаправлен к одному или неÑ�кольким конечным пунктам назначениÑ� длÑ� проÑ�мотра и долгоÑ�рочной архивации. Ðти конечные пункты архивации не Ñ�влÑ�ÑŽÑ‚Ñ�Ñ� видимыми длÑ� приложениÑ� и наÑ�траиваемыми приложением, вмеÑ�то Ñ�того они полноÑ�тью управлÑ�ÑŽÑ‚Ñ�Ñ� Ñ�редой выполнениÑ�. Маршрутизаторы журналов Ñ� открытым иÑ�ходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluentd](https://github.com/fluent/fluentd)) могут быть иÑ�пользованы длÑ� Ñ�той цели.
Поток Ñ�обытий приложениÑ� может быть перенаправлен в файл или проÑ�матриватьÑ�Ñ� в терминале в режиме реального времени. Ð�аиболее значимым Ñ�влÑ�етÑ�Ñ� то, что поток Ñ�обытий может быть направлен в Ñ�иÑ�тему индекÑ�ированиÑ� и анализа журналов, такую как [Splunk](http://www.splunk.com/), или Ñ�иÑ�тему хранениÑ� данных общего назначениÑ�, такую как [Hadoop/Hive](http://hive.apache.org/). Ðти Ñ�иÑ�темы обладают большими возможноÑ�Ñ‚Ñ�ми и гибкоÑ�тью длÑ� доÑ�конального анализа поведениÑ� приложение в течении времени, что включает в Ñ�ебÑ�:
* Пои�к конкретных �обытий в прошлом.
* Крупнома�штабные графики трендов (например, запро�ов в минуту).
* �ктивные оповещени� �огла�но �ври�тиче�ким правилам, определ�емых пользователем (например, оповещение, когда количе�тво ошибок в минуту превышает определённый порог).
content/zh_cn/intro.md 0000644 0001750 0005670 00000001522 15226251677 013550 0 ustar 00 0000000 0000000 简介
============
如今,软件通常会作为一��务�交付,它们被称为网络应用程�,或软件��务(SaaS)。12-Factor 为构建如下的 SaaS 应用�供了方法论:
* 使用**æ ‡å‡†åŒ–**æµ�程自动é…�置,从而使新的开å�‘者花费最少的å¦ä¹ æˆ�æœ¬åŠ å…¥è¿™ä¸ªé¡¹ç›®ã€‚
* å’Œæ“�作系统之间尽å�¯èƒ½çš„**划清界é™�**,在å�„ä¸ªç³»ç»Ÿä¸æ��ä¾›**最大的å�¯ç§»æ¤�性**。
* 适�**部署**在现代的**云计算平�**,从而在�务器和系统管�方�节�资�。
* 将开å�‘环境和生产环境的**差异é™�至最低**,并使用**æŒ�ç»äº¤ä»˜**实施æ•�æ�·å¼€å�‘。
* �以在工具�架构和开��程��生明显�化的��下实现**扩展**。
这套ç�†è®ºé€‚用于任æ„�è¯è¨€å’Œå�Žç«¯æœ�务(数æ�®åº“ã€�消æ�¯é˜Ÿåˆ—ã€�缓å˜ç‰ï¼‰å¼€å�‘的应用程åº�。
content/ja/port-binding.md 0000644 0001750 0005670 00000005411 15226251677 014303 0 ustar 00 0000000 0000000 ## VII. �ート�インディング
### �ート�インディングを通��サービスを公開�る
Webアプリケーション�Webサー�ーコンテナ�内部�実行�れる����る。例���PHPアプリケーション�[Apache HTTPD](http://httpd.apache.org/)内部�モジュール���実行�れる�も�れ����Javaアプリケーション�[Tomcat](http://tomcat.apache.org/)�内部�実行�れる�も�れ��。
**Twelve-Factor Appã�¯å®Œå…¨ã�«è‡ªå·±å®Œçµ�** ã�—ã€�Webã�«å…¬é–‹ã�•れるサービスを作æˆ�ã�™ã‚‹ã�Ÿã‚�ã�«ã€�コンテナã�Œå®Ÿè¡Œç’°å¢ƒã�«Webサーãƒ�ーランタイムを注入ã�™ã‚‹ã�“ã�¨ã‚’é ¼ã‚Šã�«ã�—ã�ªã�„。Webアプリケーションã�¯ **ãƒ�ートã�«ãƒ�インドã�™ã‚‹ã�“ã�¨ã�§HTTPをサービスã�¨ã�—ã�¦å…¬é–‹ã�—ã€�** ã��ã�®ãƒ�ートã�«ãƒªã‚¯ã‚¨ã‚¹ãƒˆã�Œæ�¥ã‚‹ã�®ã‚’å¾…ã�¤ã€‚
ãƒãƒ¼ã‚«ãƒ«ã�®é–‹ç™ºç’°å¢ƒã�§ã�¯ã€�開発者ã�¯ã‚¢ãƒ—リケーションã�«ã‚ˆã�£ã�¦å…¬é–‹ã�•れã�Ÿã‚µãƒ¼ãƒ“スã�«ã‚¢ã‚¯ã‚»ã‚¹ã�™ã‚‹ã�Ÿã‚�ã�«ã€�`http://localhost:5000/`ã�®ã‚ˆã�†ã�ªã‚µãƒ¼ãƒ“スã�®URLã�«ã‚¢ã‚¯ã‚»ã‚¹ã�™ã‚‹ã€‚本番環境ã�§ã�¯ãƒ«ãƒ¼ãƒ†ã‚£ãƒ³ã‚°å±¤ã�Œã€�外å�‘ã��ã�®ãƒ›ã‚¹ãƒˆå��ã�‹ã‚‰ãƒ�ートã�«ãƒ�インドã�•れã�ŸWebプãƒã‚»ã‚¹ã�¸ã�¨ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’ルーティングã�™ã‚‹ã€‚
ã�“れã�¯ä¸€èˆ¬ã�«ã€�[ä¾�å˜é–¢ä¿‚宣言](./dependencies)を使ã�£ã�¦Webサーãƒ�ーライブラリをアプリケーションã�«è¿½åŠ ã�™ã‚‹ã�“ã�¨ã�§å®Ÿè£…ã�•れる。Webサーãƒ�ーライブラリã�®ä¾‹ã�¨ã�—ã�¦ã€�Pythonã�«ã�Šã�‘ã‚‹[Tornado](http://www.tornadoweb.org/)ã€�Rubyã�«ã�Šã�‘ã‚‹[Thin](http://code.macournoyer.com/thin/)ã€�Javaã‚„ã��ã�®ä»–ã�®JVMベースã�®è¨€èªžã�«ã�Šã�‘ã‚‹[Jetty](http://www.eclipse.org/jetty/)ã�ªã�©ã�Œã�‚る。ã�“れã�¯ *ユーザー空間* ã�™ã�ªã‚�ã�¡ã‚¢ãƒ—リケーションã�®ã‚³ãƒ¼ãƒ‰å†…ã�§å®Œçµ�ã�™ã‚‹ã€‚リクエストを処ç�†ã�™ã‚‹ã�Ÿã‚�ã�®å®Ÿè¡Œç’°å¢ƒã�¨ã�®å¥‘ç´„ã�¯ã€�ãƒ�ートをãƒ�インドã�™ã‚‹ã�“ã�¨ã�§ã�‚る。
ãƒ�ートãƒ�インディングã�«ã‚ˆã�£ã�¦å…¬é–‹ã�•れるサービスã�¯HTTPã� ã�‘ã�§ã�¯ã�ªã�„。ã�»ã�¼ã�™ã�¹ã�¦ã�®ã‚µãƒ¼ãƒ�ーソフトウェアã�¯ã€�ãƒ�ートをãƒ�インドã�™ã‚‹ãƒ—ãƒã‚»ã‚¹ã‚’用ã�„ã�¦å‹•作ã�—ã€�リクエストã�Œæ�¥ã‚‹ã�®ã‚’å¾…ã�¤ã€‚例ã�¨ã�—ã�¦ã€�[ejabberd](http://www.ejabberd.im/)([XMPP](http://xmpp.org/)を話ã�™ï¼‰ã‚„ [Redis](http://redis.io/)([Redisプãƒãƒˆã‚³ãƒ«](http://redis.io/topics/protocol)を話ã�™ï¼‰ã�ªã�©ã�Œã�‚る。
ã�“ã�“ã�§æ³¨ç›®ã�™ã�¹ã��ã�¯ã€�ãƒ�ートãƒ�インディングã�®æ–¹æ³•ã�«ã‚ˆã�£ã�¦ã€�ã�‚るアプリケーションã�Œä»–ã�®ã‚¢ãƒ—リケーションã�«ã�¨ã�£ã�¦ã�®[ãƒ�ックエンドサービス](./backing-services)ã�«ã�ªã‚Œã‚‹ç‚¹ã�§ã�‚る。ãƒ�ックエンドアプリケーションã�¸ã�®URLã‚’æ��ä¾›ã�—ã€�利用ã�™ã‚‹ã‚¢ãƒ—リケーションã�®[è¨å®š](./config)ã�«ãƒªã‚½ãƒ¼ã‚¹ãƒ�ンドルã�¨ã�—ã�¦æ ¼ç´�ã�™ã‚Œã�°ã‚ˆã�„。
content/th/background.md 0000644 0001750 0005670 00000005662 15226251677 014057 0 ustar 00 0000000 0000000 ประวัติ
==========
ผู้มีส่วนร่วมขà¸à¸‡à¹€à¸à¸�สารนี้ได้มีส่วนเà¸�ี่ยวข้à¸à¸‡à¹‚ดยตรงà¸�ับà¸�ารพัฒนาà¹�ละà¸�ารใช้งานà¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชันจำนวนมาà¸� à¹�ละเà¸�ี่ยวข้à¸à¸‡à¸—างà¸à¹‰à¸à¸¡à¸ªà¸³à¸«à¸£à¸±à¸šà¸�ารพัฒนา à¸�ารดำเนินงาน à¹�ละà¸�ารขยายขนาดขà¸à¸‡à¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชันจำนวมมหาศาลผ่านงานขà¸à¸‡à¹€à¸£à¸²à¸—ี่à¹�พลตฟà¸à¸£à¹Œà¸¡ Heroku
เà¸à¸�สารนี้สังเคราะห์จาà¸�ประสบà¸�ารณ์à¹�ละà¸�ารสังเà¸�ตทั้งหมดขà¸à¸‡à¸žà¸§à¸�เราบนà¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชัน software-as-a-service ที่หลาà¸�หลายจำนวนมาà¸� เป็นสามเหลียมขà¸à¸‡à¹�นวทางปà¸�ิบัตในà¸à¸¸à¸”มคติสำหรับà¸�ารพัฒนาà¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชัน ให้ความสนใจเป็นพิเศษà¸�ับพลวัตขà¸à¸‡à¸�ารเจริà¸�เติบโตขà¸à¸‡à¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชันในช่วงเวลาหนึ่ง พลวัตขà¸à¸‡à¸�ารมีส่วนร่วมระหว่างนัà¸�พัฒนาที่ทำงานà¸�ับ codebase ขà¸à¸‡à¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชัน à¹�ละหลีà¸�เลี่ยงà¸�ารใช้จ่ายขà¸à¸‡à¸‹à¸à¸Ÿà¸•์à¹�วร์ .
à¹�รงจูงใจขà¸à¸‡à¹€à¸£à¸²à¹€à¸žà¸·à¹ˆà¸à¸ªà¸£à¹‰à¸²à¸‡à¸„วามตระหนัà¸�ขà¸à¸‡à¸›à¸±à¸�หาระบบบางà¸à¸¢à¹ˆà¸²à¸‡à¸—ี่เราเห็นในà¸�ารพัฒนาà¹�à¸à¸žà¸žà¸¥à¸´à¹€à¸„ชันสมัยใหม่ เพื่à¸à¹ƒà¸«à¹‰à¸„ำศัพย์ที่ใช้ร่วมà¸�ันสำหรับà¸�ารพูดคุยเà¸�ี่ยวà¸�ับปัà¸�หาเหล่านี้ à¹�ละนำเสนà¸à¹�นวทางà¹�à¸�้ไขà¹�นวà¸�ว้างสำหรับปัà¸�หาเหล่านี้พร้à¸à¸¡à¸�ับคำศัพท์ที่ใช้ประà¸�à¸à¸šà¸�ัน รูปà¹�บบนี้ได้รับà¹�รงบันดาลใจจาà¸�หนังสืà¸à¸‚à¸à¸‡ Martin Fowler *Patterns of Enterprise Application Architecture * à¹�ละ *Refactoring *.
content/zh_cn/dev-prod-parity.md 0000644 0001750 0005670 00000007612 15226251677 015451 0 ustar 00 0000000 0000000 ## X. å¼€å�‘环境与线上环境ç‰ä»·
### 尽�能的��开�,预�布,线上环境相�
从以往ç»�验æ�¥çœ‹ï¼Œå¼€å�‘环境(å�³å¼€å�‘人员的本地 [部署](./codebase))和线上环境(外部用户访问的真实部署)之间å˜åœ¨ç�€å¾ˆå¤šå·®å¼‚。这些差异表现在以下三个方é�¢ï¼š
* **时间差异:** å¼€å�‘人员æ£åœ¨ç¼–写的代ç �å�¯èƒ½éœ€è¦�å‡ å¤©ï¼Œå‡ å‘¨ï¼Œç”šè‡³å‡ ä¸ªæœˆæ‰�会上线。
* **人员差异:** å¼€å�‘人员编写代ç �,è¿�维人员部署代ç �。
* **工具差异:** 开�人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以� Linux。
**12-Factor 应用想è¦�å�šåˆ° [æŒ�ç»éƒ¨ç½²](http://avc.com/2011/02/continuous-deployment/) 就必须缩å°�本地与线上差异。** å†�回头看上é�¢æ‰€æ��述的三个差异:
* 缩å°�时间差异:开å�‘人员å�¯ä»¥å‡ å°�æ—¶ï¼Œç”šè‡³å‡ åˆ†é’Ÿå°±éƒ¨ç½²ä»£ç �。
* 缩å°�人员差异:开å�‘人员ä¸�å�ªè¦�编写代ç �,更应该密切å�‚与部署过程以å�Šä»£ç �在线上的表现。
* 缩�工具差异:尽���开�环境以�线上环境的一致性。
将上述总结å�˜ä¸ºä¸€ä¸ªè¡¨æ ¼å¦‚下:
ä¼ ç»Ÿåº”ç”¨
12-Factor 应用
�次部署间隔
数周
å‡ å°�æ—¶
开�人员 vs �维人员
��的人
相�的人
开�环境 vs 线上环境
��
尽�接近
[å�Žç«¯æœ�务](./backing-services) 是ä¿�æŒ�å¼€å�‘与线上ç‰ä»·çš„é‡�è¦�部分,例如数æ�®åº“,队列系统,以å�Šç¼“å˜ã€‚许多è¯è¨€éƒ½æ��供了简化获å�–å�Žç«¯æœ�务的类库,例如ä¸�å�Œç±»åž‹æœ�务的 *适é…�器* ã€‚ä¸‹åˆ—è¡¨æ ¼æ��供了一些例å�。
类型
è¯è¨€
类库
适�器
数�库
Ruby/Rails
ActiveRecord
MySQL, PostgreSQL, SQLite
队列
Python/Django
Celery
RabbitMQ, Beanstalkd, Redis
缓å˜
Ruby/Rails
ActiveSupport::Cache
Memory, filesystem, Memcached
å¼€å�‘人员有时会觉得在本地环境ä¸ä½¿ç”¨è½»é‡�çš„å�Žç«¯æœ�务具有很强的å�¸å¼•力,而那些更é‡�é‡�级的å�¥å£®çš„å�Žç«¯æœ�务应该使用在生产环境。例如,本地使用 SQLite 线上使用 PostgreSQLï¼›å�ˆå¦‚本地缓å˜åœ¨è¿›ç¨‹å†…å˜ä¸è€Œçº¿ä¸Šå˜å…¥ Memcached。
**12-Factor 应用的开å�‘人员应该å��对在ä¸�å�ŒçŽ¯å¢ƒé—´ä½¿ç”¨ä¸�å�Œçš„å�Žç«¯æœ�务** ,å�³ä½¿é€‚é…�器已ç»�å�¯ä»¥å‡ ä¹Žæ¶ˆé™¤ä½¿ç”¨ä¸Šçš„å·®å¼‚ã€‚è¿™æ˜¯å› ä¸ºï¼Œä¸�å�Œçš„å�Žç«¯æœ�务æ„�味ç�€ä¼šçª�然出现的ä¸�兼容,从而导致测试ã€�预å�‘布都æ£å¸¸çš„代ç �在线上出现问题。这些错误会给æŒ�ç»éƒ¨ç½²å¸¦æ�¥é˜»åŠ›ã€‚ä»Žåº”ç”¨ç¨‹åº�的生命周期æ�¥çœ‹ï¼Œæ¶ˆé™¤è¿™ç§�阻力需è¦�花费很大的代价。
与æ¤å�Œæ—¶ï¼Œè½»é‡�的本地æœ�务也ä¸�åƒ�以å‰�é‚£æ ·å¼•äººæ³¨ç›®ã€‚å€ŸåŠ©äºŽ[Homebrew](http://mxcl.github.com/homebrew/),[apt-get](https://help.ubuntu.com/community/AptGet/Howto)ç‰çŽ°ä»£çš„æ‰“åŒ…ç³»ç»Ÿï¼Œè¯¸å¦‚Memcachedã€�PostgreSQLã€�RabbitMQ ç‰å�Žç«¯æœ�务的安装与è¿�行也并ä¸�å¤�æ�‚。æ¤å¤–,使用类似 [Chef](http://www.opscode.com/chef/) å’Œ [Puppet](http://docs.puppetlabs.com/) 的声明å¼�é…�置工具,结å�ˆåƒ� [Vagrant](http://vagrantup.com/) è¿™æ ·è½»é‡�的虚拟环境就å�¯ä»¥ä½¿å¾—å¼€å�‘äººå‘˜çš„æœ¬åœ°çŽ¯å¢ƒä¸Žçº¿ä¸ŠçŽ¯å¢ƒæ— é™�接近。与å�Œæ¥çŽ¯å¢ƒå’ŒæŒ�ç»éƒ¨ç½²æ‰€å¸¦æ�¥çš„益处相比,安装这些系统显然是值得的。
ä¸�å�Œå�Žç«¯æœ�务的适é…�器ä»�ç„¶æ˜¯æœ‰ç”¨çš„ï¼Œå› ä¸ºå®ƒä»¬å�¯ä»¥ä½¿ç§»æ¤�å�Žç«¯æœ�务å�˜å¾—简å�•。但应用的所有部署,这其ä¸åŒ…括开å�‘ã€�预å�‘布以å�Šçº¿ä¸ŠçŽ¯å¢ƒï¼Œéƒ½åº”è¯¥ä½¿ç”¨å�Œä¸€ä¸ªå�Žç«¯æœ�务的相å�Œç‰ˆæœ¬ã€‚
public/images/symbol.png 0000644 0001750 0005670 00000003705 15226251677 014063 0 ustar 00 0000000 0000000 ‰PNG
IHDR ( J ÉÂ<