From d4e9dc1d3f89025541780f9af9180352976b8266 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 00:05:08 +0800 Subject: [PATCH 001/472] translate intro.md to zh_CN --- content/intro.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/content/intro.md b/content/intro.md index eff1d33d4..c56d975ad 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,12 +1,11 @@ -Introduction +��� ============ +��ǰ����������*����Ӧ��(web apps)*��*������Ӫ��SaaS��*��ͨ���Ľ�����׼��twelve-factorΪ�������µ�SaaSӦ���ṩ�˷����ۣ� -In the modern era, software is commonly delivered as a service: called *web apps*, or *software-as-a-service*. The twelve-factor app is a methodology for building software-as-a-service apps that: +* ʹ��**��׼��**�����Զ����ã��Ӷ�ʹ�µĿ����߻������ٵ�ѧϰ�ɱ����������Ŀ�� +* �Ͳ���ϵͳ֮�価���ܵ�**�������**���ڸ���ϵͳ���ṩ**���Ŀ���ֲ��**�� +* �ʺ�**����**���ִ���**�Ƽ���ƽ̨**���Ӷ��ڷ�������ϵͳ���������ʡ��Դ�� +* ��С���з��Ͳ�Ʒ������**ì��**�����**��������**������������ԣ� +* �������ڹ��ߡ��ܹ��Ϳ������̲��������Ա仯��ǰ����ʵ����չ�� -* Use **declarative** formats for setup automation, to minimize time and cost for new developers joining the project; -* Have a **clean contract** with the underlying operating system, offering **maximum portability** between execution environments; -* Are suitable for **deployment** on modern **cloud platforms**, obviating the need for servers and systems administration; -* **Minimize divergence** between development and production, enabling **continuous deployment** for maximum agility; -* And can **scale up** without significant changes to tooling, architecture, or development practices. - -The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc). +�������ۿ�����ʹ���������ԣ��Լ������˷���database, queue, memory cache,�ȵȣ���������Ӧ��ʱ�������á� \ No newline at end of file From 29f85d5d9afe2b76e11ef8832c11275ed9e0de5d Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 00:31:23 +0800 Subject: [PATCH 002/472] fix the missing ** around 'scale up' --- content/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/intro.md b/content/intro.md index c56d975ad..797447250 100644 --- a/content/intro.md +++ b/content/intro.md @@ -6,6 +6,6 @@ * �Ͳ���ϵͳ֮�価���ܵ�**�������**���ڸ���ϵͳ���ṩ**���Ŀ���ֲ��**�� * �ʺ�**����**���ִ���**�Ƽ���ƽ̨**���Ӷ��ڷ�������ϵͳ���������ʡ��Դ�� * ��С���з��Ͳ�Ʒ������**ì��**�����**��������**������������ԣ� -* �������ڹ��ߡ��ܹ��Ϳ������̲��������Ա仯��ǰ����ʵ����չ�� +* �������ڹ��ߡ��ܹ��Ϳ������̲��������Ա仯��ǰ����ʵ��**��չ**�� �������ۿ�����ʹ���������ԣ��Լ������˷���database, queue, memory cache,�ȵȣ���������Ӧ��ʱ�������á� \ No newline at end of file From 7864bbbfaa8a6f04c3c4f9412ac485d2f924bcc8 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 00:42:48 +0800 Subject: [PATCH 003/472] test markdown format --- content/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/intro.md b/content/intro.md index 797447250..f1678bd5b 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,6 +1,6 @@ ��� ============ -��ǰ����������*����Ӧ��(web apps)*��*������Ӫ��SaaS��*��ͨ���Ľ�����׼��twelve-factorΪ�������µ�SaaSӦ���ṩ�˷����ۣ� +��ǰ��������������Ӧ��(*web apps*)��������Ӫ(*software-as-a-service*)��ͨ���Ľ�����׼��twelve-factorΪ�������µ�SaaSӦ���ṩ�˷����ۣ� * ʹ��**��׼��**�����Զ����ã��Ӷ�ʹ�µĿ����߻������ٵ�ѧϰ�ɱ����������Ŀ�� * �Ͳ���ϵͳ֮�価���ܵ�**�������**���ڸ���ϵͳ���ṩ**���Ŀ���ֲ��**�� From a17d338181e9ca6938017ae35935ff7e883e49f8 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:30:08 +0800 Subject: [PATCH 004/472] translate background.md to zh_CN --- content/background.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/content/background.md b/content/background.md index af26e1431..7d802f93d 100644 --- a/content/background.md +++ b/content/background.md @@ -1,9 +1,10 @@ -Background +���� ========== -The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. +���ĵIJ����߲�������԰ټƵ�Ӧ�ó���Ŀ����Ͳ��𣬲�ͨ��[Heroku](http://www.heroku.com/)ƽ̨��Ӽ�֤����ʮ��Ӧ�ó���Ŀ����������Լ���չ�Ĺ��̡� -This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ����[����������Ⱦ]��http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/���� -Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ����������� +��ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* ��*[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� From aec13cd44875bb12f374508abe8e81c8070eec72 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:35:48 +0800 Subject: [PATCH 005/472] fix format --- content/background.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/content/background.md b/content/background.md index 7d802f93d..c0ff94c2d 100644 --- a/content/background.md +++ b/content/background.md @@ -3,8 +3,6 @@ ���ĵIJ����߲�������԰ټƵ�Ӧ�ó���Ŀ����Ͳ��𣬲�ͨ��[Heroku](http://www.heroku.com/)ƽ̨��Ӽ�֤����ʮ��Ӧ�ó���Ŀ����������Լ���չ�Ĺ��̡� -�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ����[����������Ⱦ]��http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/���� +�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ���α���������Ⱦ����[avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)�� -���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ����������� - -��ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* ��*[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� +���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* & *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� From 148f6a5d24a84b43b66d927a8c78d12acc5be8e2 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:38:11 +0800 Subject: [PATCH 006/472] fix format --- content/background.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/background.md b/content/background.md index c0ff94c2d..1ac247731 100644 --- a/content/background.md +++ b/content/background.md @@ -3,6 +3,6 @@ ���ĵIJ����߲�������԰ټƵ�Ӧ�ó���Ŀ����Ͳ��𣬲�ͨ��[Heroku](http://www.heroku.com/)ƽ̨��Ӽ�֤����ʮ��Ӧ�ó���Ŀ����������Լ���չ�Ĺ��̡� -�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ���α���������Ⱦ����[avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)�� +�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ���α���������Ⱦ([avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/))�� -���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* & *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� +���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� From a21ff9c40f0acd45601bd7324876111742589659 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:40:53 +0800 Subject: [PATCH 007/472] fix format --- content/background.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/background.md b/content/background.md index 1ac247731..5b8c916f3 100644 --- a/content/background.md +++ b/content/background.md @@ -3,6 +3,6 @@ ���ĵIJ����߲�������԰ټƵ�Ӧ�ó���Ŀ����Ͳ��𣬲�ͨ��[Heroku](http://www.heroku.com/)ƽ̨��Ӽ�֤����ʮ��Ӧ�ó���Ŀ����������Լ���չ�Ĺ��̡� -�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ���α���������Ⱦ([avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/))�� +�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ����[����������Ⱦ](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) �� -���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*�� +���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* �� *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* �� From 8dbe1995dfef560b27562a3a2af206f854b92739 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:44:01 +0800 Subject: [PATCH 008/472] translate who.md to zh_CN --- content/who.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/who.md b/content/who.md index 49eb40fd5..1a4b37885 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ -Who should read this document? +����Ӧ������Щ�ˣ� ============================== -Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. +�κ�SaaSӦ�õĿ�����Ա������͹������Ӧ�õ���ά����ʦ�� From 10c3eca1d466a856712302e47ab978b707caa16f Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 30 Apr 2012 21:48:18 +0800 Subject: [PATCH 009/472] change translation of intro.md --- content/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/intro.md b/content/intro.md index f1678bd5b..5e58c67f7 100644 --- a/content/intro.md +++ b/content/intro.md @@ -8,4 +8,4 @@ * ��С���з��Ͳ�Ʒ������**ì��**�����**��������**������������ԣ� * �������ڹ��ߡ��ܹ��Ϳ������̲��������Ա仯��ǰ����ʵ��**��չ**�� -�������ۿ�����ʹ���������ԣ��Լ������˷���database, queue, memory cache,�ȵȣ���������Ӧ��ʱ�������á� \ No newline at end of file +�������ۿ��������������Լ������˷���database, queue, memory cache,�ȵȣ��Ŀ���Ӧ���з������á� \ No newline at end of file From 36432746e89ed7669c82e03b56290edaf9488920 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 1 May 2012 00:51:06 +0800 Subject: [PATCH 010/472] translate codebase.md to zh_CN --- content/codebase.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index a194c98b9..bfec95ee8 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,18 +1,18 @@ ## I. Codebase -### One codebase tracked in revision control, many deploys +### һ��ʹ�ð汾���Ƶ�codebase����ݲ��� -A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. +ʹ��twelve-factor�����Ӧ��������������[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), �� [Subversion](http://subversion.apache.org/)�İ汾����ϵͳ��һ���������ٴ��������޶��汾�����ݿⱻ����*code repository* ��ͨ����Ϊ*code repo*����ֻ����*repo* �� -A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). +*codebase*��ָ������repo(������Subversion�ļ���ʽ�汾��������)����һ��ӵ�й�ͬ���ȵ�repo��������Git�ķֲ�ʽ�汾����ϵͳ�У��� -![One codebase maps to many deploys](/images/codebase-deploys.png) +![һ��codebase��Ӧ��ݲ���](/images/codebase-deploys.png) -There is always a one-to-one correlation between the codebase and the app: +codebase��Ӧ��֮�����DZ���һһ��Ӧ�Ĺ�ϵ�� -* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. -* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](/dependencies). +* һ���ж��codebase���Ͳ��ܳ�Ϊһ��Ӧ�� ���� ׼ȷ��˵����Ӧ����һ���ֲ�ʽϵͳ�� �ֲ�ʽϵͳ�е�ÿһ�������һ��Ӧ�ã�����ÿһ��Ӧ�ö�Ӧ�ö�������twelve-factor�� +* ���Ӧ�ù���һ�ݴ�����Υ��twelve-factor�ġ���������ǽ������Ĵ���ֽ⵽��ͬ��Ŀ¼��Ȼ��ʹ��[��������](/dependencies)����ȥ�������ǡ� -There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. +����ÿ��Ӧ�ö�Ӧһ��codebase��������ͬʱ���ڶ�ݲ���ÿ��*����*�൱��������һ��Ӧ�õ�ʵ����ͨ��������һ������������һ������Ԥ�������������⣬ÿ��������Ա�������Լ����ػ�������һ��Ӧ�ã���Щ���൱��һ�ݲ��� -The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. +���в����codebase��ͬ����ÿ�ݲ������ʹ���䲻ͬ�İ汾�����磬������Ա������һЩ�ύ��û��ͬ����Ԥ����������Ԥ��������Ҳ��һЩ�ύû��ͬ�������������������Ƕ�����һ��codebase�����Ǿ���Ϊ����ֻ����ͬӦ�õIJ�ͬ������ѡ� From 3ecb0c55db63e666064f274a858cf5b7e96fbd2f Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 1 May 2012 00:54:09 +0800 Subject: [PATCH 011/472] format markdown --- content/codebase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index bfec95ee8..a95ab0ed4 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,9 +1,9 @@ ## I. Codebase ### һ��ʹ�ð汾���Ƶ�codebase����ݲ��� -ʹ��twelve-factor�����Ӧ��������������[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), �� [Subversion](http://subversion.apache.org/)�İ汾����ϵͳ��һ���������ٴ��������޶��汾�����ݿⱻ����*code repository* ��ͨ����Ϊ*code repo*����ֻ����*repo* �� +ʹ��twelve-factor�����Ӧ��������������[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), �� [Subversion](http://subversion.apache.org/)�İ汾����ϵͳ��һ���������ٴ��������޶��汾�����ݿⱻ����*code repository* ��ͨ����Ϊ*code repo* ����ֻ���� *repo* �� -*codebase*��ָ������repo(������Subversion�ļ���ʽ�汾��������)����һ��ӵ�й�ͬ���ȵ�repo��������Git�ķֲ�ʽ�汾����ϵͳ�У��� +*codebase* ��ָ������repo(������Subversion�ļ���ʽ�汾��������)����һ��ӵ�й�ͬ���ȵ�repo��������Git�ķֲ�ʽ�汾����ϵͳ�У��� ![һ��codebase��Ӧ��ݲ���](/images/codebase-deploys.png) From 341132cb72a9052f7796c8e0fde4d10c060ee30e Mon Sep 17 00:00:00 2001 From: liangshan Date: Wed, 2 May 2012 15:11:15 +0800 Subject: [PATCH 012/472] encode utf8 --- content/codebase.md | 18 +++++++++--------- content/intro.md | 16 ++++++++-------- content/who.md | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index a95ab0ed4..eca7788b4 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,18 +1,18 @@ ## I. Codebase -### һ��ʹ�ð汾���Ƶ�codebase����ݲ��� +### 一份使用版本控制的codebase,多份部署 -ʹ��twelve-factor�����Ӧ��������������[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), �� [Subversion](http://subversion.apache.org/)�İ汾����ϵͳ��һ���������ٴ��������޶��汾�����ݿⱻ����*code repository* ��ͨ����Ϊ*code repo* ����ֻ���� *repo* �� +使用twelve-factor概念的应用总是引入类似[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), 或 [Subversion](http://subversion.apache.org/)的版本控制系统。一份用来跟踪代码所有修订版本的数据库被称作*code repository* ,通常简化为*code repo* 或者只保留 *repo* 。 -*codebase* ��ָ������repo(������Subversion�ļ���ʽ�汾��������)����һ��ӵ�й�ͬ���ȵ�repo��������Git�ķֲ�ʽ�汾����ϵͳ�У��� +*codebase* 是指单独的repo(在类似Subversion的集中式版本控制器中),或一组拥有共同祖先的repo(在类似Git的分布式版本控制系统中)。 -![һ��codebase��Ӧ��ݲ���](/images/codebase-deploys.png) +![一份codebase对应多份部署](/images/codebase-deploys.png) -codebase��Ӧ��֮�����DZ���һһ��Ӧ�Ĺ�ϵ�� +codebase和应用之间总是保持一一对应的关系: -* һ���ж��codebase���Ͳ��ܳ�Ϊһ��Ӧ�� ���� ׼ȷ��˵����Ӧ����һ���ֲ�ʽϵͳ�� �ֲ�ʽϵͳ�е�ÿһ�������һ��Ӧ�ã�����ÿһ��Ӧ�ö�Ӧ�ö�������twelve-factor�� -* ���Ӧ�ù���һ�ݴ�����Υ��twelve-factor�ġ���������ǽ������Ĵ���ֽ⵽��ͬ��Ŀ¼��Ȼ��ʹ��[��������](/dependencies)����ȥ�������ǡ� +* 一旦有多个codebase,就不能称为一个应用 —— 准确的说,它应该是一个分布式系统。 分布式系统中的每一个组件是一个应用,并且每一个应用都应该独立遵守twelve-factor。 +* 多个应用共享一份代码是违背twelve-factor的。解决方案是将共享的代码分解到不同的目录,然后使用[依赖管理](/dependencies)策略去加载它们。 -����ÿ��Ӧ�ö�Ӧһ��codebase��������ͬʱ���ڶ�ݲ���ÿ��*����*�൱��������һ��Ӧ�õ�ʵ����ͨ��������һ������������һ������Ԥ�������������⣬ÿ��������Ա�������Լ����ػ�������һ��Ӧ�ã���Щ���൱��һ�ݲ��� +尽管每个应用对应一个codebase,但可以同时存在多份部署。每份*部署*相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 -���в����codebase��ͬ����ÿ�ݲ������ʹ���䲻ͬ�İ汾�����磬������Ա������һЩ�ύ��û��ͬ����Ԥ����������Ԥ��������Ҳ��һЩ�ύû��ͬ�������������������Ƕ�����һ��codebase�����Ǿ���Ϊ����ֻ����ͬӦ�õIJ�ͬ������ѡ� +所有部署的codebase相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份codebase,我们就认为它们只是相同应用的不同部署而已。 diff --git a/content/intro.md b/content/intro.md index 5e58c67f7..bf55ddc37 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,11 +1,11 @@ -��� +简介 ============ -��ǰ��������������Ӧ��(*web apps*)��������Ӫ(*software-as-a-service*)��ͨ���Ľ�����׼��twelve-factorΪ�������µ�SaaSӦ���ṩ�˷����ۣ� +当前的软件领域,网络应用(*web apps*)或软件运营(*software-as-a-service*)是通常的交付标准。twelve-factor为构建如下的SaaS应用提供了方法论: -* ʹ��**��׼��**�����Զ����ã��Ӷ�ʹ�µĿ����߻������ٵ�ѧϰ�ɱ����������Ŀ�� -* �Ͳ���ϵͳ֮�価���ܵ�**�������**���ڸ���ϵͳ���ṩ**���Ŀ���ֲ��**�� -* �ʺ�**����**���ִ���**�Ƽ���ƽ̨**���Ӷ��ڷ�������ϵͳ���������ʡ��Դ�� -* ��С���з��Ͳ�Ʒ������**ì��**�����**��������**������������ԣ� -* �������ڹ��ߡ��ܹ��Ϳ������̲��������Ա仯��ǰ����ʵ��**��չ**�� +* 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目; +* 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**; +* 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源; +* 最小化研发和产品发布的**矛盾**,最大化**持续交付**所带来的灵活性; +* 并可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**; -�������ۿ��������������Լ������˷���database, queue, memory cache,�ȵȣ��Ŀ���Ӧ���з������á� \ No newline at end of file +这套理论可以在任意语言以及任意后端服务(database, queue, memory cache,等等)的开发应用中发挥作用。 diff --git a/content/who.md b/content/who.md index 1a4b37885..88ad90614 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ -����Ӧ������Щ�ˣ� +读者应该是哪些人? ============================== -�κ�SaaSӦ�õĿ�����Ա������͹������Ӧ�õ���ά����ʦ�� +任何SaaS应用的开发人员。部署和管理相关应用的运维工程师。 From d95b69321af0b2b6ca9436c386cd45427ef61f9f Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Wed, 2 May 2012 18:23:20 +0800 Subject: [PATCH 013/472] translate dependencies.md --- content/background.md | 9 +++++---- content/codebase.md | 2 +- content/dependencies.md | 14 +++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/content/background.md b/content/background.md index 5b8c916f3..5020b3231 100644 --- a/content/background.md +++ b/content/background.md @@ -1,8 +1,9 @@ -���� +背景 ========== -���ĵIJ����߲�������԰ټƵ�Ӧ�ó���Ŀ����Ͳ��𣬲�ͨ��[Heroku](http://www.heroku.com/)ƽ̨��Ӽ�֤����ʮ��Ӧ�ó���Ŀ����������Լ���չ�Ĺ��̡� +本文的参与者参与过数以百计的应用程序的开发和部署,并通过[Heroku](http://www.heroku.com/)平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 -�����ۺ������ǹ���SaaSӦ�ü������еľ�����ǻۣ��ǿ�������Ӧ�õ�����ʵ����׼�����ر��ע��Ӧ�ó�����α������Գɳ���������֮����ν�����Ч�Ĵ���Э�����Լ����[����������Ⱦ](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) �� +本文综合了我们关于SaaS应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何[避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 + +我们的初衷是分享在现代应用程序开发过程中发现的一些系统性问题,并加深对这些问题的认识,提供讨论这些问题时所需的共享词汇,同时使用相关术语提供一套针对这些问题的广义解决方案。格式的灵感来自于Martin Fowler的书籍: *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* , *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* 。 -���ǵij����Ƿ������ִ�Ӧ�ó��򿪷������з��ֵ�һЩϵͳ�����⣬���������Щ�������ʶ���ṩ������Щ����ʱ����Ĺ����ʻ㣬ͬʱʹ����������ṩһ�������Щ����Ĺ�������������ʽ�����������Martin Fowler���鼮�� *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* �� *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* �� diff --git a/content/codebase.md b/content/codebase.md index eca7788b4..f14f54a3b 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -12,7 +12,7 @@ codebase和应用之间总是保持一一对应的关系: * 一旦有多个codebase,就不能称为一个应用 —— 准确的说,它应该是一个分布式系统。 分布式系统中的每一个组件是一个应用,并且每一个应用都应该独立遵守twelve-factor。 * 多个应用共享一份代码是违背twelve-factor的。解决方案是将共享的代码分解到不同的目录,然后使用[依赖管理](/dependencies)策略去加载它们。 -尽管每个应用对应一个codebase,但可以同时存在多份部署。每份*部署*相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 +尽管每个应用对应一个codebase,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 所有部署的codebase相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份codebase,我们就认为它们只是相同应用的不同部署而已。 diff --git a/content/dependencies.md b/content/dependencies.md index b5bcb0343..48f05e660 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -1,12 +1,12 @@ -## II. Dependencies -### Explicitly declare and isolate dependencies +## II. 依赖 +### 明确的声明和剥离依赖 -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"). +大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。打包系统安装的这些类库可以选择全系统生效(称之为"site packages")或仅在需要时将路径包含进来(称之为"vendoring"或"bunding")。 -**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. +**一个应用遵守twelve-factor意味着永远不信任系统类库中的隐藏内容** 它一定通过 *依赖声明* 清单,完整而又准确的声明了所有依赖。此外,在运行过程中通过一个 *依赖剥离* 工具来确保系统中没有“遗漏”的依赖冲突。完整而明确的依赖规范,统一适用于生产和开发环境。 -For example, [Gem Bundler](http://gembundler.com/) 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. +例如, [Gem Bundler](http://gembundler.com/) 为Ruby提供了`Gemfile`清单从而规范了依赖声明的格式,以及`bundle exec`来剥离依赖。在Python中,有2个独立的工具来分别做这2件事情 -- [Pip](http://www.pip-installer.org/en/latest/) 用来声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用来剥离。甚至C语言也有 [Autoconf](http://www.gnu.org/s/autoconf/) 来声明依赖,静态链接提供剥离帮助。无论用什么工具,依赖的声明和剥离总是一起使用 -- 其中的任意一个都不是满足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`. +明确的声明依赖所带来的好处之一是,为应用的新开发者简化了配置流程。新的开发者可以签出应用的codebase到开发机器,仅仅需要一个编程语言环境和它对应的依赖管理工具即可开始工作。只需要一些固定的 *构建命令* ,它们可以帮你装好代码中所需的一切。例如,Ruby/Bundler的构建命令是`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 对应的则是`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. +Twelve-factor应用同样不会不信任那些隐藏着的系统工具。这其中包括ImageMagick或是`curl`。即使这些工具存在于很多甚至决大多数系统,但终究无法保证所有系统都能支持应用顺利运行,或者说将来的系统是否兼容现有版本。假设应用必须使用系统工具,那么就将这个工具完整的包含进来。 From bf66789da1a216586551f7dc4be0654884613ef9 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 3 May 2012 09:28:42 +0800 Subject: [PATCH 014/472] decide to translate the keyword 'codebase' self --- content/codebase.md | 16 ++++++++-------- content/dependencies.md | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index f14f54a3b..82d80dc9c 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,18 +1,18 @@ -## I. Codebase -### 一份使用版本控制的codebase,多份部署 +## I. 代码库 +### 一份使用版本控制的代码库(*Codebase*),多份部署 使用twelve-factor概念的应用总是引入类似[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), 或 [Subversion](http://subversion.apache.org/)的版本控制系统。一份用来跟踪代码所有修订版本的数据库被称作*code repository* ,通常简化为*code repo* 或者只保留 *repo* 。 -*codebase* 是指单独的repo(在类似Subversion的集中式版本控制器中),或一组拥有共同祖先的repo(在类似Git的分布式版本控制系统中)。 +*代码库* 是指单独的repo(在类似Subversion的集中式版本控制器中),或一组拥有共同祖先的repo(在类似Git的分布式版本控制系统中)。 -![一份codebase对应多份部署](/images/codebase-deploys.png) +![一份代码库对应多份部署](/images/代码库-deploys.png) -codebase和应用之间总是保持一一对应的关系: +代码库和应用之间总是保持一一对应的关系: -* 一旦有多个codebase,就不能称为一个应用 —— 准确的说,它应该是一个分布式系统。 分布式系统中的每一个组件是一个应用,并且每一个应用都应该独立遵守twelve-factor。 +* 一旦有多个代码库,就不能称为一个应用 —— 准确的说,它应该是一个分布式系统。 分布式系统中的每一个组件是一个应用,并且每一个应用都应该独立遵守twelve-factor。 * 多个应用共享一份代码是违背twelve-factor的。解决方案是将共享的代码分解到不同的目录,然后使用[依赖管理](/dependencies)策略去加载它们。 -尽管每个应用对应一个codebase,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 +尽管每个应用对应一个代码库,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 -所有部署的codebase相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份codebase,我们就认为它们只是相同应用的不同部署而已。 +所有部署的代码库相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份代码库,我们就认为它们只是相同应用的不同部署而已。 diff --git a/content/dependencies.md b/content/dependencies.md index 48f05e660..5fd22b464 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -1,5 +1,5 @@ ## II. 依赖 -### 明确的声明和剥离依赖 +### 明确的声明和剥离依赖(*dependency*) 大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。打包系统安装的这些类库可以选择全系统生效(称之为"site packages")或仅在需要时将路径包含进来(称之为"vendoring"或"bunding")。 @@ -7,6 +7,6 @@ 例如, [Gem Bundler](http://gembundler.com/) 为Ruby提供了`Gemfile`清单从而规范了依赖声明的格式,以及`bundle exec`来剥离依赖。在Python中,有2个独立的工具来分别做这2件事情 -- [Pip](http://www.pip-installer.org/en/latest/) 用来声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用来剥离。甚至C语言也有 [Autoconf](http://www.gnu.org/s/autoconf/) 来声明依赖,静态链接提供剥离帮助。无论用什么工具,依赖的声明和剥离总是一起使用 -- 其中的任意一个都不是满足twelve-factor的充分条件。 -明确的声明依赖所带来的好处之一是,为应用的新开发者简化了配置流程。新的开发者可以签出应用的codebase到开发机器,仅仅需要一个编程语言环境和它对应的依赖管理工具即可开始工作。只需要一些固定的 *构建命令* ,它们可以帮你装好代码中所需的一切。例如,Ruby/Bundler的构建命令是`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 对应的则是`lein deps`。 +明确的声明依赖所带来的好处之一是,为应用的新开发者简化了配置流程。新的开发者可以签出应用的代码库到开发机器,仅仅需要一个编程语言环境和它对应的依赖管理工具即可开始工作。只需要一些固定的 *构建命令* ,它们可以帮你装好代码中所需的一切。例如,Ruby/Bundler的构建命令是`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 对应的则是`lein deps`。 Twelve-factor应用同样不会不信任那些隐藏着的系统工具。这其中包括ImageMagick或是`curl`。即使这些工具存在于很多甚至决大多数系统,但终究无法保证所有系统都能支持应用顺利运行,或者说将来的系统是否兼容现有版本。假设应用必须使用系统工具,那么就将这个工具完整的包含进来。 From fb43c0c05bd720b6b720c7384609e363d3050123 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 3 May 2012 13:48:28 +0800 Subject: [PATCH 015/472] translate config.md to zh_CN --- content/codebase.md | 2 +- content/config.md | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index 82d80dc9c..64edfe6de 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,7 +1,7 @@ ## I. 代码库 ### 一份使用版本控制的代码库(*Codebase*),多份部署 -使用twelve-factor概念的应用总是引入类似[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), 或 [Subversion](http://subversion.apache.org/)的版本控制系统。一份用来跟踪代码所有修订版本的数据库被称作*code repository* ,通常简化为*code repo* 或者只保留 *repo* 。 +twelve-factor应用(译者注:应该是说一个使用本文概念来设计的应用,下同)总是引入类似[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), 或 [Subversion](http://subversion.apache.org/)的版本控制系统。一份用来跟踪代码所有修订版本的数据库被称作*code repository* ,通常简化为*code repo* 或者只保留 *repo* 。 *代码库* 是指单独的repo(在类似Subversion的集中式版本控制器中),或一组拥有共同祖先的repo(在类似Git的分布式版本控制系统中)。 diff --git a/content/config.md b/content/config.md index c32d6a22c..e9ecae5aa 100644 --- a/content/config.md +++ b/content/config.md @@ -1,23 +1,23 @@ -## III. Config -### Store config in the environment +## III. 配置 +### 在环境中存储配置(*Config*) -An app's *config* is everything that is likely to vary between [deploys](/codebase) (staging, production, developer environments, etc). This includes: +通常,应用的*配置*在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: -* Resource handles to the database, Memcached, and other [backing services](/backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy +* 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 +* Amazon S3或是Twitter等第三方服务的证书 +* 每种部署独特的域名等各个部署间不同的内容 -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. +有些应用将配置在代码中写为常量。这与twelve-factor所要求的 **代码和配置严格分离** 显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. +衡量一个应用是否正确的将配置排除在代码之外的一个有效方法是,该应用的代码库是否可以随时开源而不做任何修改。 -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). This type of config does not vary between deploys, and so is best done in the code. +需要特别注意的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,又或是 [Spring](http://www.springsource.org/) 的 how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以存在代码中是最好的选择。 -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. +另外一个解决配置的方式是使用配置文件,但不把它们签入版本控制系统,就像Rails的 `config/database.yml` 。这相对将常量直接签入代码库已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的一个趋势是它们分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. +**Twelve-factor推崇将应用的配置存储于 *环境变量*** (通常称之为 *env vars* 或 *env*) 。Env vars可以非常方便的在不同部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如Java System properties)相比,它们与语言和系统无关。 -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. +配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的爆炸,从而给管理部署增加了很多不确定因素。 -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments," but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +Twelve-factor应用中,env vars的粒度足够小,相互之间也是相对独立的。它们永远不会合体组成一个所谓的“环境”,而是独立管理每个部署。这是应用的生命周期中扩展出更多部署时较为平滑的模型。 From 6da6e99079403669b515ed0af375448b667e9a82 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 3 May 2012 13:52:08 +0800 Subject: [PATCH 016/472] fix typos --- content/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/config.md b/content/config.md index e9ecae5aa..380968490 100644 --- a/content/config.md +++ b/content/config.md @@ -1,7 +1,7 @@ ## III. 配置 ### 在环境中存储配置(*Config*) -通常,应用的*配置*在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: +通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: * 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 * Amazon S3或是Twitter等第三方服务的证书 @@ -11,7 +11,7 @@ 衡量一个应用是否正确的将配置排除在代码之外的一个有效方法是,该应用的代码库是否可以随时开源而不做任何修改。 -需要特别注意的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,又或是 [Spring](http://www.springsource.org/) 的 how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以存在代码中是最好的选择。 +需要特别注意的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,又或是 [Spring](http://www.springsource.org/) 的 [how code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以存在代码中是最好的选择。 另外一个解决配置的方式是使用配置文件,但不把它们签入版本控制系统,就像Rails的 `config/database.yml` 。这相对将常量直接签入代码库已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的一个趋势是它们分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 From b3cdd8888a074a8f580d65a8f820004e91d2d8dc Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 3 May 2012 15:36:57 +0800 Subject: [PATCH 017/472] translate backing-services to zh_CN --- content/backing-services.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/backing-services.md b/content/backing-services.md index 1b6f77c1d..bc7b95eda 100644 --- a/content/backing-services.md +++ b/content/backing-services.md @@ -1,15 +1,15 @@ -## IV. Backing Services -### Treat backing services as attached resources +## IV. 后端服务 +### 把后端服务(*backing services*)当作附加资源 -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). +*后端服务* 是指任何需要应用程序通过网络与之通讯来维持应用自身正常运行的服务。示例包括数据存储(例如 [MySQL](http://dev.mysql.com/) 或 [CouchDB](http://couchdb.apache.org/)),消息/队列系统(例如 [RabbitMQ](http://www.rabbitmq.com/) 或 [Beanstalkd](http://kr.github.com/beanstalkd/)),发送外部邮件用到的SMPT服务([Postfix](http://www.postfix.org/)),以及缓存系统(例如 [Memcached](http://memcached.org/))。 -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). +类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括SMPT(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)), 以及使用API访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](/config). A [deploy](/codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. +**twelve-factor应用的代码不会区分本地和第三方服务。** 对应用程序而言,两种都是附加资源,通过一个url或是其他存储在 [配置](/config) 中的服务定位/证书来获取数据。Twelve-factor应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,任意将本地MySQL数据库换作一个第三方的对应服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地SMTP服务应该也可以和第三方SMTP服务(例如Postmark)互换。上述2个例子中,仅仅配置中相关资源地址需要修改。 -Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. +每个不同的后端服务是一份 *资源* 。例如,一个MySQL数据库是一个资源,两个MySQL数据库(用来数据分区)就被当作是2个不同的资源。Twelve-factor应用将这些数据库都视作 *附加资源* ,这些资源和它们附属的部署保持松耦合。 -A production deploy attached to four backing services. +一种部署附加4个后端服务 -Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. +资源可以按需的加载或卸载。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 -- 整个过程都不需要修改代码。 From af5951be01c30bfdb9cc30982bc2c0a08e055a11 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Fri, 4 May 2012 14:40:56 +0800 Subject: [PATCH 018/472] translate build-release-run.md to zh_CN --- content/build-release-run.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/content/build-release-run.md b/content/build-release-run.md index b0ed3ed90..a65cb2e71 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -1,19 +1,19 @@ -## V. Build, release, run -### Strictly separate build and run stages +## V. 构建,发布,运行 +### 严格分离构建和运行 -A [codebase](/codebase) is transformed into a (non-development) deploy through three stages: +[代码库](/codebase) 转化为一份部署(非开发环境)需要以下三个步骤: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](/dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](/config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](/processes) against a selected release. +* *构建步骤* 是指将代码仓库转化为可执行包的 *构建* 过程。构建使用了部署过程中某次指定的代码版本,包含了获取、 [包含](/dependencies) 、编译文件以及资源文件。 +* *发布步骤* 将构建的结果和当前部署所需 [配置](/config) 结合。 *发布* 的结果应当包含构建的结果、配置以及具备随时在执行环境运行的能力。 +* *运行步骤* (或者说“运行状态”)是指针对选定的发布版本,在执行环境中启动一系列应用程序的进程。 -![Code becomes a build, which is combined with config to create a release.](/images/release.png) +![代码被构建,然后和配置结合成为发布版本](/images/release.png) -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. +**Twelve-facfor应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. +部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录。当前的发布版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以轻易实现回退版本的功能。 -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. +每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,并且一旦发布就不可修改。任何的变动应该产生一个先的发布。 -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. +当代码发生变化时,应用程序的开发者随时都可以选择构建操作。 与之对应的是,运行则应该当服务器重启,或是进程管理者重启了一个崩溃的进程时才会被触发。因此,运行步骤应该尽可能保持少一些步骤,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会花费太多时间。构建过程倒是可以相对复杂一些,因为负责部署的开发人员就可以及时看到报错信息。 From 6c627f6d67bbd521f24d95d7925546ccd434660e Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Fri, 4 May 2012 14:45:25 +0800 Subject: [PATCH 019/472] fix translates --- content/build-release-run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/build-release-run.md b/content/build-release-run.md index a65cb2e71..8516a036e 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -13,7 +13,7 @@ 部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录。当前的发布版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以轻易实现回退版本的功能。 -每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,并且一旦发布就不可修改。任何的变动应该产生一个先的发布。 +每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,并且一旦发布就不可修改。任何的变动应该产生一个新的发布。 -当代码发生变化时,应用程序的开发者随时都可以选择构建操作。 与之对应的是,运行则应该当服务器重启,或是进程管理者重启了一个崩溃的进程时才会被触发。因此,运行步骤应该尽可能保持少一些步骤,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会花费太多时间。构建过程倒是可以相对复杂一些,因为负责部署的开发人员就可以及时看到报错信息。 +当代码发生变化时,应用程序的开发者随时都可以选择构建操作。 与之对应的是,当服务器重启,或是进程管理者重启了一个崩溃的进程时运行步骤才会被触发。因此,运行步骤应该保持尽可能少的流程,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会花费太多精力。构建过程倒是可以相对复杂一些,因为负责部署的开发人员就可以及时看到报错信息。 From 975ce296a2cf1e94b683c4fdf09c026fa816159e Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Fri, 4 May 2012 18:22:31 +0800 Subject: [PATCH 020/472] part of processes.md --- content/processes.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/processes.md b/content/processes.md index 2477d6080..89637721c 100644 --- a/content/processes.md +++ b/content/processes.md @@ -1,3 +1,12 @@ +## VI. 进程 +### 以一个或多个无状态进程(*process*)运行应用 + +在运行环境中,以一个或多个无状态进程运行应用程序 + +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己装了运行环境的笔记本,进程由一条命令行(例如 `python my_script.py`)启动。相对的,另外一个极端情况是复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是多个进程实例。 + +**Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 + ## VI. Processes ### Execute the app as one or more stateless processes From f1fd3d1e093421a9ce59a69cf687dbce328bdd0b Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Sat, 5 May 2012 10:58:49 +0800 Subject: [PATCH 021/472] other part of processes.md --- content/processes.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/content/processes.md b/content/processes.md index 89637721c..9173fd25e 100644 --- a/content/processes.md +++ b/content/processes.md @@ -7,18 +7,9 @@ **Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 -## VI. Processes -### Execute the app as one or more stateless processes +内存或硬盘的空间对于进程而言,应该是一个简单的,单项的缓存。例如用来下载一个很大的文件,对其操作并将结果写入数据库。Twelve-factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使只有一个进程,你也别指望这些缓存的内容可以在机器重启(比如部署新的代码,修改配置文件,或是更换运行环境)后还可以保留。 -The app is executed in the execution environment as one or more *processes*. +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。Twelve-factor应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails asset pipline](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](/concurrency). - -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](/backing-services), typically a database. - -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. - -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. - -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并希望将来的同一用户被指向同一个进程。粘性Session是twelve-factor极力反对的。Session中可以用来记录诸如 [Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 过期时间的数据。 From 9273f096a96f5ea4a34983413b53538ece9afe59 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Sat, 5 May 2012 11:05:01 +0800 Subject: [PATCH 022/472] fix typos --- content/processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/processes.md b/content/processes.md index 9173fd25e..b419f96f7 100644 --- a/content/processes.md +++ b/content/processes.md @@ -1,9 +1,9 @@ ## VI. 进程 ### 以一个或多个无状态进程(*process*)运行应用 -在运行环境中,以一个或多个无状态进程运行应用程序 +在运行环境中,以一个或多个无状态进程运行应用程序。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己装了运行环境的笔记本,进程由一条命令行(例如 `python my_script.py`)启动。相对的,另外一个极端情况是复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是多个进程实例。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)启动。相对的,另外一个极端情况是复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是多个进程实例。 **Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 From ca20988ffcfa61641d541618807dcfd1fecc0cae Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 11:38:52 +0800 Subject: [PATCH 023/472] Update content/intro.md --- content/intro.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/intro.md b/content/intro.md index bf55ddc37..6956bc3cc 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,11 +1,11 @@ 简介 ============ -当前的软件领域,网络应用(*web apps*)或软件运营(*software-as-a-service*)是通常的交付标准。twelve-factor为构建如下的SaaS应用提供了方法论: +如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”(SaaS)。“十二要素应用程序”(12-Factor App)正是一种如何构建SaaS应用的方法论: * 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目; * 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**; * 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源; -* 最小化研发和产品发布的**矛盾**,最大化**持续交付**所带来的灵活性; -* 并可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**; +* 将开发环境和生产环境的**差异降至最低**,并使用**持续交付**实施敏捷开发; +* 可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**; -这套理论可以在任意语言以及任意后端服务(database, queue, memory cache,等等)的开发应用中发挥作用。 +这套理论适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序。 From 6deccbd7704c16908de1c6da82ed5b9313047a1e Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 11:59:58 +0800 Subject: [PATCH 024/472] Update content/background.md --- content/background.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/background.md b/content/background.md index 5020b3231..157c17a1d 100644 --- a/content/background.md +++ b/content/background.md @@ -1,9 +1,9 @@ 背景 ========== -本文的参与者参与过数以百计的应用程序的开发和部署,并通过[Heroku](http://www.heroku.com/)平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 +本文的贡献者曾参与开发和部署数以百计的应用程序,并在[Heroku](http://www.heroku.com/)平台见证了数十万应用程序的开发、运作、以及扩展过程。 本文综合了我们关于SaaS应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何[避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 -我们的初衷是分享在现代应用程序开发过程中发现的一些系统性问题,并加深对这些问题的认识,提供讨论这些问题时所需的共享词汇,同时使用相关术语提供一套针对这些问题的广义解决方案。格式的灵感来自于Martin Fowler的书籍: *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* , *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* 。 +我们的初衷是分享在现代软件开发过程中发现的一些系统性问题,并加深对这些问题的认识。我们提供了讨论这些问题时所需的共享词汇,同时使用相关术语给出一套针对这些问题的广义解决方案。本文格式的灵感来自于Martin Fowler的书籍: *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* , *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* 。 From 32d0d4c21ab07ad9eedba83547d2defac23e7a5b Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 12:04:55 +0800 Subject: [PATCH 025/472] Update content/who.md --- content/who.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/who.md b/content/who.md index 88ad90614..8946e6ad5 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ 读者应该是哪些人? ============================== -任何SaaS应用的开发人员。部署和管理相关应用的运维工程师。 +任何SaaS应用的开发人员。部署和管理此类应用的运维工程师。 From dc3991a7a152479532bbbeac2674c51d14d109ce Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 12:31:29 +0800 Subject: [PATCH 026/472] Update content/codebase.md --- content/codebase.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index 64edfe6de..d0c17a49a 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,18 +1,17 @@ -## I. 代码库 -### 一份使用版本控制的代码库(*Codebase*),多份部署 +## I. 基准代码 +### 一份代码,多份部署 -twelve-factor应用(译者注:应该是说一个使用本文概念来设计的应用,下同)总是引入类似[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), 或 [Subversion](http://subversion.apache.org/)的版本控制系统。一份用来跟踪代码所有修订版本的数据库被称作*code repository* ,通常简化为*code repo* 或者只保留 *repo* 。 +12-Factor App(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作*代码库*(code repository, code repo, repo)。 -*代码库* 是指单独的repo(在类似Subversion的集中式版本控制器中),或一组拥有共同祖先的repo(在类似Git的分布式版本控制系统中)。 +在类似SVN这样的集中式版本控制系统中,*基准代码*就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中,*基准代码*则是指最上游的那份代码库。 ![一份代码库对应多份部署](/images/代码库-deploys.png) -代码库和应用之间总是保持一一对应的关系: +基准代码和应用之间总是保持一一对应的关系: -* 一旦有多个代码库,就不能称为一个应用 —— 准确的说,它应该是一个分布式系统。 分布式系统中的每一个组件是一个应用,并且每一个应用都应该独立遵守twelve-factor。 -* 多个应用共享一份代码是违背twelve-factor的。解决方案是将共享的代码分解到不同的目录,然后使用[依赖管理](/dependencies)策略去加载它们。 +* 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用12-Factor进行开发。 +* 多个应用共享一份基准代码是有悖于12-Factor原则的。解决方案是将共享的代码拆分为独立的类库,然后使用[依赖管理](/dependencies)策略去加载它们。 -尽管每个应用对应一个代码库,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常都会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一份应用,这些都相当于一份部署。 - -所有部署的代码库相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份代码库,我们就认为它们只是相同应用的不同部署而已。 +尽管每个应用只对应一份基准代码,但可以同时存在多份部署。所谓 *部署* 指的是应用的一个运行实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 +不同的部署使用的是同一份基准代码,只是代码版本会有所不同。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码,我们就认为它们只是相同应用的不同部署。 From 8c10b308a8327b3c5d323ffbf9ad54ff27e469ed Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 14:20:52 +0800 Subject: [PATCH 027/472] Update content/dependencies.md --- content/dependencies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/dependencies.md b/content/dependencies.md index 5fd22b464..77702953e 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -1,12 +1,12 @@ ## II. 依赖 -### 明确的声明和剥离依赖(*dependency*) +### 显式声明依赖关系 -大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。打包系统安装的这些类库可以选择全系统生效(称之为"site packages")或仅在需要时将路径包含进来(称之为"vendoring"或"bunding")。 +大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为"site packages"),或仅供某个应用程序使用,部署在相应的目录中(称之为"vendoring"或"bunding")。 -**一个应用遵守twelve-factor意味着永远不信任系统类库中的隐藏内容** 它一定通过 *依赖声明* 清单,完整而又准确的声明了所有依赖。此外,在运行过程中通过一个 *依赖剥离* 工具来确保系统中没有“遗漏”的依赖冲突。完整而明确的依赖规范,统一适用于生产和开发环境。 +**12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它会通过一份 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 -例如, [Gem Bundler](http://gembundler.com/) 为Ruby提供了`Gemfile`清单从而规范了依赖声明的格式,以及`bundle exec`来剥离依赖。在Python中,有2个独立的工具来分别做这2件事情 -- [Pip](http://www.pip-installer.org/en/latest/) 用来声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用来剥离。甚至C语言也有 [Autoconf](http://www.gnu.org/s/autoconf/) 来声明依赖,静态链接提供剥离帮助。无论用什么工具,依赖的声明和剥离总是一起使用 -- 其中的任意一个都不是满足twelve-factor的充分条件。 +例如, Ruby的[Gem Bundler](http://gembundler.com/) 使用`Gemfile`作为依赖项声明清单,使用`bundle exec`来进行依赖隔离。Python中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至C语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 -明确的声明依赖所带来的好处之一是,为应用的新开发者简化了配置流程。新的开发者可以签出应用的代码库到开发机器,仅仅需要一个编程语言环境和它对应的依赖管理工具即可开始工作。只需要一些固定的 *构建命令* ,它们可以帮你装好代码中所需的一切。例如,Ruby/Bundler的构建命令是`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 对应的则是`lein deps`。 +显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler下使用`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是`lein deps`。 -Twelve-factor应用同样不会不信任那些隐藏着的系统工具。这其中包括ImageMagick或是`curl`。即使这些工具存在于很多甚至决大多数系统,但终究无法保证所有系统都能支持应用顺利运行,或者说将来的系统是否兼容现有版本。假设应用必须使用系统工具,那么就将这个工具完整的包含进来。 +12-Factor应用同样不会隐式依赖某些系统工具,如ImageMagick或是`curl`。虽然几乎所有的系统中都会包含这两种工具,但终究无法保证未来的某个系统中也包含这些工具,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file From 8d8e8986629f9cbe79b4cf2fefd36c6cdb67596f Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 14:22:05 +0800 Subject: [PATCH 028/472] Update content/codebase.md --- content/codebase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/codebase.md b/content/codebase.md index d0c17a49a..e175a4157 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,9 +1,9 @@ ## I. 基准代码 ### 一份代码,多份部署 -12-Factor App(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作*代码库*(code repository, code repo, repo)。 +12-Factor App(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 -在类似SVN这样的集中式版本控制系统中,*基准代码*就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中,*基准代码*则是指最上游的那份代码库。 +在类似SVN这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 ![一份代码库对应多份部署](/images/代码库-deploys.png) From 9a54da7af5e90c5bd8955e2029f848e169291611 Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 15:01:46 +0800 Subject: [PATCH 029/472] Update content/config.md --- content/config.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/content/config.md b/content/config.md index 380968490..1ecaa31a3 100644 --- a/content/config.md +++ b/content/config.md @@ -1,23 +1,22 @@ ## III. 配置 ### 在环境中存储配置(*Config*) -通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: +在不同的环境中(预发布环境、生产环境、开发环境等)[部署](/codebase)应用,主要的差异来自应用的 *配置* 。这其中包括: * 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 -* Amazon S3或是Twitter等第三方服务的证书 -* 每种部署独特的域名等各个部署间不同的内容 +* 第三方服务的证书,如Amazon S3、Twitter等 +* 每份部署特有的配置,如域名等 -有些应用将配置在代码中写为常量。这与twelve-factor所要求的 **代码和配置严格分离** 显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 +有些应用在代码中使用常量保存配置,这与12-Factor所要求的 **代码和配置严格分离** 是相违背的。配置文件在各部署间存在大幅差异,但代码不会。 -衡量一个应用是否正确的将配置排除在代码之外的一个有效方法是,该应用的代码库是否可以随时开源而不做任何修改。 +判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。 -需要特别注意的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,又或是 [Spring](http://www.springsource.org/) 的 [how code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以存在代码中是最好的选择。 +需要指出的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,或是使用[Spring](http://www.springsource.org/)时[代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 -另外一个解决配置的方式是使用配置文件,但不把它们签入版本控制系统,就像Rails的 `config/database.yml` 。这相对将常量直接签入代码库已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的一个趋势是它们分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 +另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像Rails的 `config/database.yml` 。这相对于在代码中使用常量已经是很大的进步了,但仍然有缺点:开发者会不小心将配置文件提交至代码库;配置文件可能会散落在不同的目录,并有着不同的格式,很难在一个地方统一管理所有配置。更糟糕的是,这些配置文件往往是针对特定语言或框架的。 -**Twelve-factor推崇将应用的配置存储于 *环境变量*** (通常称之为 *env vars* 或 *env*) 。Env vars可以非常方便的在不同部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如Java System properties)相比,它们与语言和系统无关。 +**12-Factor推荐将应用的配置存储于 *环境变量* 中** (*env vars*, *env*) 。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,环境变量不太会被提交至代码库;与一些传统的解决配置问题的机制(比如Java的属性配置文件)相比,环境变量与语言和系统无关。 -配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的爆炸,从而给管理部署增加了很多不确定因素。 - -Twelve-factor应用中,env vars的粒度足够小,相互之间也是相对独立的。它们永远不会合体组成一个所谓的“环境”,而是独立管理每个部署。这是应用的生命周期中扩展出更多部署时较为平滑的模型。 +配置管理的另一个方面是分组。有时,应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:产生新的部署时,会需要新的环境名称,例如 `staging` 或 `qa` 。 随着项目的不断扩展,开发人员可能还会添加他们自己的环境名称,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 +12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 \ No newline at end of file From e002cb93ebfbb1828c03ec6a5d7c0b265d1e3fb3 Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 15:36:27 +0800 Subject: [PATCH 030/472] Update content/backing-services.md --- content/backing-services.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/content/backing-services.md b/content/backing-services.md index bc7b95eda..f8eaa8837 100644 --- a/content/backing-services.md +++ b/content/backing-services.md @@ -1,15 +1,14 @@ ## IV. 后端服务 ### 把后端服务(*backing services*)当作附加资源 -*后端服务* 是指任何需要应用程序通过网络与之通讯来维持应用自身正常运行的服务。示例包括数据存储(例如 [MySQL](http://dev.mysql.com/) 或 [CouchDB](http://couchdb.apache.org/)),消息/队列系统(例如 [RabbitMQ](http://www.rabbitmq.com/) 或 [Beanstalkd](http://kr.github.com/beanstalkd/)),发送外部邮件用到的SMPT服务([Postfix](http://www.postfix.org/)),以及缓存系统(例如 [Memcached](http://memcached.org/))。 +*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP邮件发送服务([Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 -类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括SMPT(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)), 以及使用API访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 +类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如[Amazon S3](http://http://aws.amazon.com/s3/)),以及使用API访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 -**twelve-factor应用的代码不会区分本地和第三方服务。** 对应用程序而言,两种都是附加资源,通过一个url或是其他存储在 [配置](/config) 中的服务定位/证书来获取数据。Twelve-factor应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,任意将本地MySQL数据库换作一个第三方的对应服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地SMTP服务应该也可以和第三方SMTP服务(例如Postmark)互换。上述2个例子中,仅仅配置中相关资源地址需要修改。 +**12-Factor应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个url或是其他存储在 [配置](/config) 中的服务定位/服务证书来获取数据。12-Factor应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,将本地MySQL数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地SMTP服务应该也可以和第三方SMTP服务(例如Postmark)互换。上述2个例子中,仅需修改配置中的资源地址。 每个不同的后端服务是一份 *资源* 。例如,一个MySQL数据库是一个资源,两个MySQL数据库(用来数据分区)就被当作是2个不同的资源。Twelve-factor应用将这些数据库都视作 *附加资源* ,这些资源和它们附属的部署保持松耦合。 一种部署附加4个后端服务 -资源可以按需的加载或卸载。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 -- 整个过程都不需要修改代码。 - +部署中可以按需加载或卸载资源。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 -- 整个过程都不需要修改代码。 From c10f132ba52443cc34506b52c3bc0e6bdf418098 Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 16:22:20 +0800 Subject: [PATCH 031/472] Update content/build-release-run.md --- content/build-release-run.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/content/build-release-run.md b/content/build-release-run.md index 8516a036e..e747f4601 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -1,19 +1,18 @@ ## V. 构建,发布,运行 ### 严格分离构建和运行 -[代码库](/codebase) 转化为一份部署(非开发环境)需要以下三个步骤: +[基准代码](/codebase) 转化为一份部署(非开发环境)需要以下三个阶段: -* *构建步骤* 是指将代码仓库转化为可执行包的 *构建* 过程。构建使用了部署过程中某次指定的代码版本,包含了获取、 [包含](/dependencies) 、编译文件以及资源文件。 -* *发布步骤* 将构建的结果和当前部署所需 [配置](/config) 结合。 *发布* 的结果应当包含构建的结果、配置以及具备随时在执行环境运行的能力。 -* *运行步骤* (或者说“运行状态”)是指针对选定的发布版本,在执行环境中启动一系列应用程序的进程。 +* *构建阶段* 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包[依赖项](/dependencies),编译成二进制文件和资源文件。 +* *发布阶段* 会将构建的结果和当前部署所需 [配置](/config) 相结合,并能够立刻在运行环境中投入使用。 +* *运行阶段* (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序[进程](/processes)。 ![代码被构建,然后和配置结合成为发布版本](/images/release.png) **Twelve-facfor应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 -部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录。当前的发布版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以轻易实现回退版本的功能。 +部署工具通常都提供了发布管理工具,最重要的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只是一个符号链接。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 -每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,并且一旦发布就不可修改。任何的变动应该产生一个新的发布。 - -当代码发生变化时,应用程序的开发者随时都可以选择构建操作。 与之对应的是,当服务器重启,或是进程管理者重启了一个崩溃的进程时运行步骤才会被触发。因此,运行步骤应该保持尽可能少的流程,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会花费太多精力。构建过程倒是可以相对复杂一些,因为负责部署的开发人员就可以及时看到报错信息。 +每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 +新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样如果半夜发生系统故障,又没有可用的开发人员,也不会造成太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,得到妥善处理。 \ No newline at end of file From 4fdfd6321e62a03a3ddc5141484cce5436721bf1 Mon Sep 17 00:00:00 2001 From: Ji Zhang Date: Sun, 6 May 2012 17:01:00 +0800 Subject: [PATCH 032/472] Update content/processes.md --- content/processes.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/content/processes.md b/content/processes.md index b419f96f7..69d8b2509 100644 --- a/content/processes.md +++ b/content/processes.md @@ -1,15 +1,14 @@ ## VI. 进程 ### 以一个或多个无状态进程(*process*)运行应用 -在运行环境中,以一个或多个无状态进程运行应用程序。 +运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)启动。相对的,另外一个极端情况是复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是多个进程实例。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)启动。另一个极端是,生产环境中的应用程序非常复杂,使用了多种[进程类型](/concurrency) ,实例化为零个或多个进程。 **Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 -内存或硬盘的空间对于进程而言,应该是一个简单的,单项的缓存。例如用来下载一个很大的文件,对其操作并将结果写入数据库。Twelve-factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使只有一个进程,你也别指望这些缓存的内容可以在机器重启(比如部署新的代码,修改配置文件,或是更换运行环境)后还可以保留。 +内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用不会去假设内存中或磁盘上的数据会在处理下一个请求时能够被调用——因为当有多个进程运行时,很有可能下一次请求就会由另一个进程处理。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。Twelve-factor应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails asset pipline](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 - -一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并希望将来的同一用户被指向同一个进程。粘性Session是twelve-factor极力反对的。Session中可以用来记录诸如 [Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 过期时间的数据。 +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。Twelve-factor应用更倾向于在 [构建步骤](/build-release-run) 中进行这一操作,就像 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) 的做法一样,而不是在运行阶段。 +一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性Session是twelve-factor极力反对的。Session中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 \ No newline at end of file From 5a11906a7a4d32df05302f66d73d14ab50bf7f46 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Sun, 6 May 2012 20:01:26 +0800 Subject: [PATCH 033/472] fix typos and add .ignore --- .gitignore | 2 ++ content/background.md | 2 +- content/backing-services.md | 2 +- content/build-release-run.md | 6 +++--- content/codebase.md | 6 +++--- content/config.md | 12 ++++++------ content/dependencies.md | 8 ++++---- content/intro.md | 2 +- content/port-binding.md | 9 +++++++++ content/processes.md | 6 +++--- 10 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..45355c105 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.bak +*.swp diff --git a/content/background.md b/content/background.md index 157c17a1d..8c9ed301e 100644 --- a/content/background.md +++ b/content/background.md @@ -1,7 +1,7 @@ 背景 ========== -本文的贡献者曾参与开发和部署数以百计的应用程序,并在[Heroku](http://www.heroku.com/)平台见证了数十万应用程序的开发、运作、以及扩展过程。 +本文的贡献者者参与过数以百计的应用程序的开发和部署,并通过[Heroku](http://www.heroku.com/)平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 本文综合了我们关于SaaS应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何[避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 diff --git a/content/backing-services.md b/content/backing-services.md index f8eaa8837..3a7a8ff6c 100644 --- a/content/backing-services.md +++ b/content/backing-services.md @@ -11,4 +11,4 @@ 一种部署附加4个后端服务 -部署中可以按需加载或卸载资源。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 -- 整个过程都不需要修改代码。 +部署可以按需加载或卸载资源。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 -- 整个过程都不需要修改代码。 diff --git a/content/build-release-run.md b/content/build-release-run.md index e747f4601..9af378350 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -11,8 +11,8 @@ **Twelve-facfor应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 -部署工具通常都提供了发布管理工具,最重要的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只是一个符号链接。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 +部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 -每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 +每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 -新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样如果半夜发生系统故障,又没有可用的开发人员,也不会造成太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,得到妥善处理。 \ No newline at end of file +新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,从而得到妥善处理。 \ No newline at end of file diff --git a/content/codebase.md b/content/codebase.md index e175a4157..e7f4b3a42 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,5 +1,5 @@ ## I. 基准代码 -### 一份代码,多份部署 +### 一份基准代码(*Codebase*),多份部署(*deploy*) 12-Factor App(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 @@ -12,6 +12,6 @@ * 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用12-Factor进行开发。 * 多个应用共享一份基准代码是有悖于12-Factor原则的。解决方案是将共享的代码拆分为独立的类库,然后使用[依赖管理](/dependencies)策略去加载它们。 -尽管每个应用只对应一份基准代码,但可以同时存在多份部署。所谓 *部署* 指的是应用的一个运行实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 +尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 -不同的部署使用的是同一份基准代码,只是代码版本会有所不同。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码,我们就认为它们只是相同应用的不同部署。 +所有部署的基准代码相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码,我们就认为它们只是相同应用的不同部署而已。 diff --git a/content/config.md b/content/config.md index 1ecaa31a3..8764b8051 100644 --- a/content/config.md +++ b/content/config.md @@ -1,22 +1,22 @@ ## III. 配置 ### 在环境中存储配置(*Config*) -在不同的环境中(预发布环境、生产环境、开发环境等)[部署](/codebase)应用,主要的差异来自应用的 *配置* 。这其中包括: +通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: * 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 * 第三方服务的证书,如Amazon S3、Twitter等 * 每份部署特有的配置,如域名等 -有些应用在代码中使用常量保存配置,这与12-Factor所要求的 **代码和配置严格分离** 是相违背的。配置文件在各部署间存在大幅差异,但代码不会。 +有些应用在代码中使用常量保存配置,这与12-factor所要求的 **代码和配置严格分离** 显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。 需要指出的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,或是使用[Spring](http://www.springsource.org/)时[代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 -另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像Rails的 `config/database.yml` 。这相对于在代码中使用常量已经是很大的进步了,但仍然有缺点:开发者会不小心将配置文件提交至代码库;配置文件可能会散落在不同的目录,并有着不同的格式,很难在一个地方统一管理所有配置。更糟糕的是,这些配置文件往往是针对特定语言或框架的。 +另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像Rails的 `config/database.yml` 。这相对于在代码中使用常量已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的可能会分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 -**12-Factor推荐将应用的配置存储于 *环境变量* 中** (*env vars*, *env*) 。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,环境变量不太会被提交至代码库;与一些传统的解决配置问题的机制(比如Java的属性配置文件)相比,环境变量与语言和系统无关。 +**12-Factor推荐将应用的配置存储于 *环境变量* 中** (*env vars*, *env*) 。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如Java的属性配置文件)相比,环境变量与语言和系统无关。 -配置管理的另一个方面是分组。有时,应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:产生新的部署时,会需要新的环境名称,例如 `staging` 或 `qa` 。 随着项目的不断扩展,开发人员可能还会添加他们自己的环境名称,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 +配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 -12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 \ No newline at end of file +12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 \ No newline at end of file diff --git a/content/dependencies.md b/content/dependencies.md index 77702953e..d08d643bd 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -1,12 +1,12 @@ ## II. 依赖 -### 显式声明依赖关系 +### 显式声明依赖关系(*dependency*) 大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为"site packages"),或仅供某个应用程序使用,部署在相应的目录中(称之为"vendoring"或"bunding")。 -**12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它会通过一份 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 +**12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它一定通过 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 例如, Ruby的[Gem Bundler](http://gembundler.com/) 使用`Gemfile`作为依赖项声明清单,使用`bundle exec`来进行依赖隔离。Python中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至C语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 -显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler下使用`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是`lein deps`。 +显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler下使用`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是`lein deps`。 -12-Factor应用同样不会隐式依赖某些系统工具,如ImageMagick或是`curl`。虽然几乎所有的系统中都会包含这两种工具,但终究无法保证未来的某个系统中也包含这些工具,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file +12-Factor应用同样不会隐式依赖某些系统工具,如ImageMagick或是`curl`。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file diff --git a/content/intro.md b/content/intro.md index 6956bc3cc..ed81a1876 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,6 +1,6 @@ 简介 ============ -如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”(SaaS)。“十二要素应用程序”(12-Factor App)正是一种如何构建SaaS应用的方法论: +如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”(SaaS)。“十二要素应用程序”(12-Factor App)为构建如下的SaaS应用提供了方法论: * 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目; * 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**; diff --git a/content/port-binding.md b/content/port-binding.md index ed1a4b1b2..2b973729f 100644 --- a/content/port-binding.md +++ b/content/port-binding.md @@ -1,3 +1,12 @@ +## VII. �˿ڰ� +### ͨ���˿ڰ�(*Port binding*)���ṩ���� + + +WebӦ����ʱ��������web������������PHP������Ϊ [Apache HTTPD](http://httpd.apache.org/) ��һ��ģ�������У�����Java������ [Tomcat](http://tomcat.apache.org/) �� + + + + ## VII. Port binding ### Export services via port binding diff --git a/content/processes.md b/content/processes.md index 69d8b2509..e981fd32e 100644 --- a/content/processes.md +++ b/content/processes.md @@ -3,12 +3,12 @@ 运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)启动。另一个极端是,生产环境中的应用程序非常复杂,使用了多种[进程类型](/concurrency) ,实例化为零个或多个进程。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是零个或多个进程实例。 **Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 -内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用不会去假设内存中或磁盘上的数据会在处理下一个请求时能够被调用——因为当有多个进程运行时,很有可能下一次请求就会由另一个进程处理。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 +内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。Twelve-factor应用更倾向于在 [构建步骤](/build-release-run) 中进行这一操作,就像 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) 的做法一样,而不是在运行阶段。 +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-factor应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性Session是twelve-factor极力反对的。Session中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 \ No newline at end of file From d17ff7d85c2a985d6f226e7d0041f0d7fb14c734 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Sun, 6 May 2012 21:57:35 +0800 Subject: [PATCH 034/472] translate port-binding.md to zh_CN --- content/port-binding.md | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/content/port-binding.md b/content/port-binding.md index 2b973729f..a4829e1b5 100644 --- a/content/port-binding.md +++ b/content/port-binding.md @@ -1,23 +1,14 @@ ## VII. �˿ڰ� ### ͨ���˿ڰ�(*Port binding*)���ṩ���� +������Ӧ����ʱ�������ڷ�����������֮�С�����PHP������Ϊ [Apache HTTPD](http://httpd.apache.org/) ��һ��ģ�������У�����Java������ [Tomcat](http://tomcat.apache.org/) �� -WebӦ����ʱ��������web������������PHP������Ϊ [Apache HTTPD](http://httpd.apache.org/) ��һ��ģ�������У�����Java������ [Tomcat](http://tomcat.apache.org/) �� +**12-factorӦ����ȫ���Ҽ���** �����������κ�����������Ϳ��Դ���һ����������ķ��񡣻�����Ӧ�� **ͨ���˿ڰ����ṩ����** ���������������ö˿ڵ����� +���ػ����У�������Աͨ���������� `http://localhost:5000/` �����ʷ��������ϻ����У�����ͳһ������������������·�������˶˿ڵ�������̡� +ͨ����ʵ��˼·�ǣ���������������ͨ�� [��������](/dependencies) ����Ӧ�á����磬Python��[Tornado](http://www.tornadoweb.org/), Ruby��[Thin](http://code.macournoyer.com/thin/) , Java�Լ���������JVM���Ե� [Jetty](http://jetty.codehaus.org/jetty/) ����ȫ�� *�û���* ��ȷ�е�˵Ӧ����Ӧ�õĴ��룬�������󡣺����л���Լ���ð󶨵Ķ˿ڼ��ɴ�����Щ���� +HTTP������Ψһһ�������ɶ˿ڰ��ṩ�ķ�����ʵ�������з���������������ͨ�����̰󶨶˿����ȴ��������磬ʹ�� [XMPP](http://xmpp.org/) �� [ejabberd](http://www.ejabberd.im/) �� �Լ�ʹ�� [RedisЭ��](http://redis.io/topics/protocol) �� [Redis](http://redis.io/) �� -## VII. Port binding -### Export services via port binding - -Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). - -**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. - -In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. - -This is typically implemented by using [dependency declaration](/dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. - -HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). - -Note also that the port-binding approach means that one app can become the [backing service](/backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](/config) for the consuming app. +��Ҫָ�����ǣ��˿ڰ����ַ�ʽҲ��ζ��һ��Ӧ�ÿ��Գ�Ϊ����һ��Ӧ�õ� [��˷���](/backing-services) �����÷��������ṩ����ӦURL������Դ���� [����](/config) �Ա��������á� \ No newline at end of file From d18d923d0e95284d9e66b129c9c3d569950ddf1d Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Sun, 6 May 2012 22:01:29 +0800 Subject: [PATCH 035/472] fix translate --- content/port-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/port-binding.md b/content/port-binding.md index a4829e1b5..3fbceec63 100644 --- a/content/port-binding.md +++ b/content/port-binding.md @@ -5,7 +5,7 @@ **12-factorӦ����ȫ���Ҽ���** �����������κ�����������Ϳ��Դ���һ����������ķ��񡣻�����Ӧ�� **ͨ���˿ڰ����ṩ����** ���������������ö˿ڵ����� -���ػ����У�������Աͨ���������� `http://localhost:5000/` �����ʷ��������ϻ����У�����ͳһ������������������·�������˶˿ڵ�������̡� +���ػ����У�������Աͨ������ `http://localhost:5000/` �ĵ�ַ�����ʷ��������ϻ����У�����ͳһ������������������·�������˶˿ڵ�������̡� ͨ����ʵ��˼·�ǣ���������������ͨ�� [��������](/dependencies) ����Ӧ�á����磬Python��[Tornado](http://www.tornadoweb.org/), Ruby��[Thin](http://code.macournoyer.com/thin/) , Java�Լ���������JVM���Ե� [Jetty](http://jetty.codehaus.org/jetty/) ����ȫ�� *�û���* ��ȷ�е�˵Ӧ����Ӧ�õĴ��룬�������󡣺����л���Լ���ð󶨵Ķ˿ڼ��ɴ�����Щ���� From d8406f2581190b34d89745cb18555cda1a336595 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 7 May 2012 15:00:43 +0800 Subject: [PATCH 036/472] translate concurrency.md to zh_CN --- content/concurrency.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/concurrency.md b/content/concurrency.md index 8d84064ec..85d9ec8ff 100644 --- a/content/concurrency.md +++ b/content/concurrency.md @@ -1,14 +1,14 @@ -## VIII. Concurrency -### Scale out via the process model +## VIII. 并发 +### 通过进程模型进行扩展 -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. +任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP进程作为Apache的子进程存在,随请求按需启动。Java进程则采取了相反的方式,在程序启动之初JVM就提供了一个超级进程储备了大量的系统资源(CPU和内存),并通过多线程实现内部的并发管理。上述2个例子中,进程是开发人员可以操作的最小单位。 -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) +![扩展表现为运行中的进程,工作多样性表现为进程类型。](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**在12-factor应用中,进程是一等公民。** 12-factor应用的进程主要借鉴于 [unix守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP请求可以交给web进程来处理,而常驻的后台工作则交由worker进程负责。 -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](/processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +上述进程模型会在系统急需扩展时大放异彩。 [12-factor应用的进程所具备的无共享,水平分区的特性](/processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](/logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +12-factor应用的进程 [不需要守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入PID文件。相反的,应该借助操作系统的进程管理器(例如 [Upstart](http://upstart.ubuntu.com/) ,分布式的进程管理云平台,或是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),来管理 [输出流](/logs) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 From 441f83d86bf8aa0f64981dc46cad7da5c4cdd6fc Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Mon, 7 May 2012 18:44:53 +0800 Subject: [PATCH 037/472] translate disposability.md --- content/disposability.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/content/disposability.md b/content/disposability.md index e19bb945b..89056e016 100644 --- a/content/disposability.md +++ b/content/disposability.md @@ -1,14 +1,13 @@ -## IX. Disposability -### Maximize robustness with fast startup and graceful shutdown +## IX. 易处理 +### 快速启动和优雅终止可最大化健壮性 -**The twelve-factor app's [processes](/processes) are *disposable*, meaning they can be started or stopped a moment's notice.** This facilitates fast elastic scaling, rapid deployment of [code](/codebase) or [config](/config) changes, and robustness of production deploys. +**12-factor应用的 [进程](/processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](/codebase) 或 [配置](/config) ,稳健的部署应用。 -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. Small 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. +进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](/build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 -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. +进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 -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](http://kr.github.com/beanstalkd/), 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://couchdb.apache.org/docs/overview.html). +对于worker进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker可以发送一个 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) 信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 +进程还应当 **在面对突然死亡时保持健壮** ,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-factor应用都应该可以设计能够应对意外的、不优雅的终结。 [Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 From 0ff6deeadb8f236a6c6de1f8da642118e55886a0 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 15:09:30 +0800 Subject: [PATCH 038/472] dev-prod-parity.md to zh_CN --- content/dev-prod-parity.md | 64 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/content/dev-prod-parity.md b/content/dev-prod-parity.md index bfea489f7..e0dcd99bb 100644 --- a/content/dev-prod-parity.md +++ b/content/dev-prod-parity.md @@ -1,54 +1,54 @@ -## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +## X. 开发环境与线上环境等价 +### 尽可能的保持开发,预发布,线上环境相同 -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](/codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +从以往经验来看,开发环境(即开发人员的本地 [部署](/codebase))和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. +* **时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 +* **人员差异:** 开发人员编写代码,运维人员部署代码。 +* **工具差异:** 开发人员或许使用Nginx,SQLite,OS X,而线上环境使用Apache,MySQL以及Linux。 -**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: +**12-factor应用想要做到 [持续部署](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. +* 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 +* 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 +* 缩小工具差异:尽量保证开发环境以及线上环境的一致性。 -Summarizing the above into a table: +将上述总结变为一个表格如下: - - + + - - - + + + - - - + + + - - - + + +
Traditional appTwelve-factor app传统应用12-factor应用
Time between deploysWeeksHours每次部署间隔数周几小时
Code authors vs code deployersDifferent peopleSame people开发人员 vs 运维人员不同的人相同的人
Dev vs production environmentsDivergentAs similar as possible开发环境 vs 线上环境不同尽量接近
-[Backing services](/backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[后端服务](/backing-services) 是保持开发与线上等价的重要部分,例如数据库,队列系统,以及缓存。许多语言都提供了简化获取后端服务的类库,例如不同类型服务的 *适配器* 。下列表格提供了一些例子。 - - - - + + + + - + @@ -67,10 +67,10 @@ Summarizing the above into a table:
TypeLanguageLibraryAdapters类型语言类库适配器
Database数据库 Ruby/Rails ActiveRecord MySQL, PostgreSQL, SQLite
-Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. +开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力,而那些更重量级的健壮的后端服务应该使用在生产环境。例如,本地使用SQLite线上使用PostgreSQL;又如本地缓存在进程内存中而线上存入Memcached。 -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. +**12-factor应用的开发人员应该反对在不同环境间使用不同的后端服务** ,即使适配器已经可以几乎消除使用上的差异。这是因为不同的后端服务意味着会突然出现的不兼容,而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看,消除这种持续部署带来的阻力需要花费很大的代价。 -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. +与此同时,轻量的本地服务也不像以前那样引人注目。借助于 [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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近了。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. +不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的同一个版本。 From 36d3bc0d74584189ee80df2b3d255931990518fe Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 15:17:10 +0800 Subject: [PATCH 039/472] fix translate of dev-prod-parity --- content/dev-prod-parity.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/dev-prod-parity.md b/content/dev-prod-parity.md index e0dcd99bb..5d3b15109 100644 --- a/content/dev-prod-parity.md +++ b/content/dev-prod-parity.md @@ -54,13 +54,13 @@ MySQL, PostgreSQL, SQLite - Queue + 队列 Python/Django Celery RabbitMQ, Beanstalkd, Redis - Cache + 缓存 Ruby/Rails ActiveSupport::Cache Memory, filesystem, Memcached @@ -69,8 +69,8 @@ 开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力,而那些更重量级的健壮的后端服务应该使用在生产环境。例如,本地使用SQLite线上使用PostgreSQL;又如本地缓存在进程内存中而线上存入Memcached。 -**12-factor应用的开发人员应该反对在不同环境间使用不同的后端服务** ,即使适配器已经可以几乎消除使用上的差异。这是因为不同的后端服务意味着会突然出现的不兼容,而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看,消除这种持续部署带来的阻力需要花费很大的代价。 +**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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近了。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 +与此同时,轻量的本地服务也不像以前那样引人注目。借助于 [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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 -不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的同一个版本。 +不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的相同版本。 From 12394de1481abbf15bcef3d660ed8e5734966f69 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 15:36:54 +0800 Subject: [PATCH 040/472] toc.md to zh_CN & encode of port-binding.md --- content/port-binding.md | 16 ++++++------- content/toc.md | 50 ++++++++++++++++++++--------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/content/port-binding.md b/content/port-binding.md index 3fbceec63..b97157e44 100644 --- a/content/port-binding.md +++ b/content/port-binding.md @@ -1,14 +1,14 @@ -## VII. �˿ڰ� -### ͨ���˿ڰ�(*Port binding*)���ṩ���� +## VII. 端口绑定 +### 通过端口绑定(*Port binding*)来提供服务 -������Ӧ����ʱ�������ڷ�����������֮�С�����PHP������Ϊ [Apache HTTPD](http://httpd.apache.org/) ��һ��ģ�������У�����Java������ [Tomcat](http://tomcat.apache.org/) �� +互联网应用有时会运行于服务器的容器之中。例如PHP经常作为 [Apache HTTPD](http://httpd.apache.org/) 的一个模块来运行,正如Java运行于 [Tomcat](http://tomcat.apache.org/) 。 -**12-factorӦ����ȫ���Ҽ���** �����������κ�����������Ϳ��Դ���һ����������ķ��񡣻�����Ӧ�� **ͨ���˿ڰ����ṩ����** ���������������ö˿ڵ����� +**12-factor应用完全自我加载** 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 **通过端口绑定来提供服务** ,并监听发送至该端口的请求。 -���ػ����У�������Աͨ������ `http://localhost:5000/` �ĵ�ַ�����ʷ��������ϻ����У�����ͳһ������������������·�������˶˿ڵ�������̡� +本地环境中,开发人员通过类似 `http://localhost:5000/` 的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 -ͨ����ʵ��˼·�ǣ���������������ͨ�� [��������](/dependencies) ����Ӧ�á����磬Python��[Tornado](http://www.tornadoweb.org/), Ruby��[Thin](http://code.macournoyer.com/thin/) , Java�Լ���������JVM���Ե� [Jetty](http://jetty.codehaus.org/jetty/) ����ȫ�� *�û���* ��ȷ�е�˵Ӧ����Ӧ�õĴ��룬�������󡣺����л���Լ���ð󶨵Ķ˿ڼ��ɴ�����Щ���� +通常的实现思路是,将网络服务器类库通过 [依赖声明](/dependencies) 载入应用。例如,Python的[Tornado](http://www.tornadoweb.org/), Ruby的[Thin](http://code.macournoyer.com/thin/) , Java以及其他基于JVM语言的 [Jetty](http://jetty.codehaus.org/jetty/) 。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 -HTTP������Ψһһ�������ɶ˿ڰ��ṩ�ķ�����ʵ�������з���������������ͨ�����̰󶨶˿����ȴ��������磬ʹ�� [XMPP](http://xmpp.org/) �� [ejabberd](http://www.ejabberd.im/) �� �Լ�ʹ�� [RedisЭ��](http://redis.io/topics/protocol) �� [Redis](http://redis.io/) �� +HTTP并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 -��Ҫָ�����ǣ��˿ڰ����ַ�ʽҲ��ζ��һ��Ӧ�ÿ��Գ�Ϊ����һ��Ӧ�õ� [��˷���](/backing-services) �����÷��������ṩ����ӦURL������Դ���� [����](/config) �Ա��������á� \ No newline at end of file +还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](/backing-services) ,调用方将服务方提供的相应URL当作资源存入 [配置](/config) 以备将来调用。 \ No newline at end of file diff --git a/content/toc.md b/content/toc.md index fc2ede4bb..6ee4854a9 100644 --- a/content/toc.md +++ b/content/toc.md @@ -1,38 +1,38 @@ -The Twelve Factors +12-factors ================== -## [I. Codebase](/codebase) -### One codebase tracked in revision control, many deploys +## [I. 基准代码](/codebase) +### 一份基准代码,多份部署 -## [II. Dependencies](/dependencies) -### Explicitly declare and isolate dependencies +## [II. 依赖](/dependencies) +### 显式声明依赖关系 -## [III. Config](/config) -### Store config in the environment +## [III. 配置](/config) +### 在环境中存储配置 -## [IV. Backing Services](/backing-services) -### Treat backing services as attached resources +## [IV. 后端服务](/backing-services) +### 把后端服务当作附加资源 -## [V. Build, release, run](/build-release-run) -### Strictly separate build and run stages +## [V. 构建,发布,运行](/build-release-run) +### 严格分离构建和运行 -## [VI. Processes](/processes) -### Execute the app as one or more stateless processes +## [VI. 进程](/processes) +### 以一个或多个无状态进程运行应用 -## [VII. Port binding](/port-binding) -### Export services via port binding +## [VII. 端口绑定](/port-binding) +### 通过端口绑定提供服务 -## [VIII. Concurrency](/concurrency) -### Scale out via the process model +## [VIII. 并发](/concurrency) +### 通过进程模型进行扩展 -## [IX. Disposability](/disposability) -### Maximize robustness with fast startup and graceful shutdown +## [IX. 易处理](/disposability) +### 快速启动和优雅终止可最大化健壮性 -## [X. Dev/prod parity](/dev-prod-parity) -### Keep development, staging, and production as similar as possible +## [X. 开发环境与线上环境等价](/dev-prod-parity) +### 尽可能的保持开发,预发布,线上环境相同 -## [XI. Logs](/logs) -### Treat logs as event streams +## [XI. 日志](/logs) +### 把日志当作事件流 -## [XII. Admin processes](/admin-processes) -### Run admin/management tasks as one-off processes +## [XII. 管理进程](/admin-processes) +### 后台管理任务当作一次性进程运行 From 2686ed7e11fadeabba623a4c145218342f027eff Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 16:33:49 +0800 Subject: [PATCH 041/472] logs.md to zh_CN --- content/logs.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/logs.md b/content/logs.md index 231a28c27..c5add1912 100644 --- a/content/logs.md +++ b/content/logs.md @@ -1,16 +1,16 @@ -## XI. Logs -### Treat logs as event streams +## XI. 日志 +### 把日志当作事件流 -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. +*日志* 使得应用程序运行的动作变得透明。在基于服务器的环境中,日志通常被写在硬盘的一个文件里,但这只是一种输出格式。 -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continously as long as the app is operating. +日志应该是 [事件流](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) 的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行,日志最原始的格式确实是一个事件一行。日志没有确定开始和结束,但随着应用在运行会持续的增加。 -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +**12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(`stdout`)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. +在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 [Logplex](https://github.com/heroku/logplex) 和 [Fluent](https://github.com/fluent/fluentd) 的开源工具可以达到这个目的。 -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: +这些事件流可以输出至文件,或者在终端实时观察。最重要的,输出流可以发送到 [Splunk](http://www.splunk.com/) 这样的日志索引及分析系统,或 [Hadoop/Hive](http://hive.apache.org/) 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括: -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). +* 找出过去一段时间特殊的事件。 +* 图形化一个大规模的趋势,比如每分钟的请求量。 +* 根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。 From d19944cd76f0238b8ba9a2c0d2384dc3908e9944 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 16:34:30 +0800 Subject: [PATCH 042/472] fix typos --- content/config.md | 4 ++-- content/processes.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/config.md b/content/config.md index 8764b8051..a3e7209a3 100644 --- a/content/config.md +++ b/content/config.md @@ -1,5 +1,5 @@ ## III. 配置 -### 在环境中存储配置(*Config*) +### 在环境中存储配置 通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: @@ -19,4 +19,4 @@ 配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 -12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 \ No newline at end of file +12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 diff --git a/content/processes.md b/content/processes.md index e981fd32e..aaf13b956 100644 --- a/content/processes.md +++ b/content/processes.md @@ -1,5 +1,5 @@ ## VI. 进程 -### 以一个或多个无状态进程(*process*)运行应用 +### 以一个或多个无状态进程运行应用 运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 @@ -11,4 +11,4 @@ 源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-factor应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 -一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性Session是twelve-factor极力反对的。Session中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 \ No newline at end of file +一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性Session是twelve-factor极力反对的。Session中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 From 799d4ae2461fedbb353ed0850dbc087077ec03a0 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 17:20:10 +0800 Subject: [PATCH 043/472] admin-processes.md to zh_CN --- content/admin-processes.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/admin-processes.md b/content/admin-processes.md index 3ae04eeea..a25556817 100644 --- a/content/admin-processes.md +++ b/content/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Admin processes -### Run admin/management tasks as one-off processes +## XII. 管理进程 +### 后台管理任务当作一次性进程运行 -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: +[进程构成] 是指用来处理应用的常规业务(比如处理web请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: -* Running database migrations (e.g. `manage.py syncdb` 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 `erl`) 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`). +* 运行数据移植(Django中的`manage.py syncdb`, Rails中的`rake db:migrate`)。 +* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个REPL工具(`python` 或 `erl`) ,或是其他命令(Ruby使用 `irb`, Rails使用 `rails console` )。 +* 运行一些提交到代码仓库的一次性脚本。 -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 [code](/code) and [config](/config) as any process run against that release. Admin code must ship with application code to avoid synchronization issues. +一次性管理进程应该和正常的 [常驻进程](/processes) 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 [代码](/codebase) 和 [配置](/config) ,基于某个 [发布版本](/build-release-run)运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。 -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. +所有进程类型应该使用同样的 [依赖隔离](/dependencies) 技术。例如,如果Ruby的web进程使用了命令 `bundle exec thin start` ,那么数据库移植应使用 `bundle exec rake db:migrate` 。同样的,如果一个Python程序使用了Virtualenv,则需要在运行Tornado Web服务器和任何 `manage.py` 管理进程时引入 ‵bin/python‵ 。 -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. +12-factor尤其青睐那些提供了REPL shell的语言,因为那会让运行一次性脚本变得简单。在本地部署中,开发人员直接在命令行使用shell命令调用一次性管理进程。在线上部署中,开发人员依旧可以使用ssh或是运行环境提供的其他机制来运行这样的进程。 From 958d8ff787de731531e7d3299e7e3c9eb2156491 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Tue, 8 May 2012 17:26:38 +0800 Subject: [PATCH 044/472] fix typos --- content/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/admin-processes.md b/content/admin-processes.md index a25556817..0ce8b3233 100644 --- a/content/admin-processes.md +++ b/content/admin-processes.md @@ -1,7 +1,7 @@ ## XII. 管理进程 ### 后台管理任务当作一次性进程运行 -[进程构成] 是指用来处理应用的常规业务(比如处理web请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: +[进程构成](/concurrency) 是指用来处理应用的常规业务(比如处理web请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: * 运行数据移植(Django中的`manage.py syncdb`, Rails中的`rake db:migrate`)。 * 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个REPL工具(`python` 或 `erl`) ,或是其他命令(Ruby使用 `irb`, Rails使用 `rails console` )。 From ad524df061ed97af4276bcb490bc09cc439c4692 Mon Sep 17 00:00:00 2001 From: erning Date: Tue, 8 May 2012 22:14:03 +0800 Subject: [PATCH 045/472] filename should not be translated --- content/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/codebase.md b/content/codebase.md index e7f4b3a42..b1ba6d11c 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -5,7 +5,7 @@ 在类似SVN这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 -![一份代码库对应多份部署](/images/代码库-deploys.png) +![一份代码库对应多份部署](/images/codebase-deploys.png) 基准代码和应用之间总是保持一一对应的关系: From 1a62d839faef37c0fdcc00d5ffdaaf2e8206c86f Mon Sep 17 00:00:00 2001 From: erning Date: Tue, 8 May 2012 22:15:21 +0800 Subject: [PATCH 046/472] add .rvmrc --- .rvmrc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .rvmrc diff --git a/.rvmrc b/.rvmrc new file mode 100644 index 000000000..aaf7bc9db --- /dev/null +++ b/.rvmrc @@ -0,0 +1,2 @@ +rvm use ruby-1.8.7@12factor --create + From 9c7e6edeb9ad0e32376037e15355486aa518fa3a Mon Sep 17 00:00:00 2001 From: erning Date: Tue, 8 May 2012 22:19:10 +0800 Subject: [PATCH 047/472] Use redcarpet as markdown render. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在使用maruku时,发现其对包含中文的markdown文件渲染有些问题。 --- Gemfile | 2 +- Gemfile.lock | 6 ++---- web.rb | 16 +++++++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 2d7d5aa87..9f3a32d19 100644 --- a/Gemfile +++ b/Gemfile @@ -2,4 +2,4 @@ source 'http://rubygems.org' gem 'sinatra', '1.2.6' gem 'thin', '1.2.7' -gem 'maruku', '0.6.0' +gem 'redcarpet', '2.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 5a934fa1d..7b2bf9cb1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,13 +3,11 @@ GEM specs: daemons (1.1.3) eventmachine (0.12.10) - maruku (0.6.0) - syntax (>= 1.0.0) rack (1.3.0) + redcarpet (2.1.0) sinatra (1.2.6) rack (~> 1.1) tilt (>= 1.2.2, < 2.0) - syntax (1.0.0) thin (1.2.7) daemons (>= 1.0.9) eventmachine (>= 0.12.6) @@ -20,6 +18,6 @@ PLATFORMS ruby DEPENDENCIES - maruku (= 0.6.0) + redcarpet (= 2.1.0) sinatra (= 1.2.6) thin (= 1.2.7) diff --git a/web.rb b/web.rb index a53c0cc35..f18675611 100644 --- a/web.rb +++ b/web.rb @@ -1,5 +1,5 @@ require 'sinatra' -require 'maruku' +require 'redcarpet' get '/' do erb :home @@ -15,8 +15,18 @@ helpers do def render_markdown(file) - markdown = File.read("content/#{file}.md") - Maruku.new(markdown).to_html + text = File.read("content/#{file}.md") + markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, + :fenced_code_blocks => true, + :no_intra_emphasis => true, + :autolink => true, + :strikethrough => true, + :lax_html_blocks => true, + :superscript => true, + :hard_wrap => true, + :tables => true, + :xhtml => true) + markdown.render(text) rescue Errno::ENOENT puts "No content for #{file}, skipping" end From 54d3abad5fb626aaa2f5c301dccf246a4b24a3ba Mon Sep 17 00:00:00 2001 From: erning Date: Tue, 8 May 2012 22:36:56 +0800 Subject: [PATCH 048/472] Footer for this Chinese version. --- views/home.erb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/views/home.erb b/views/home.erb index 6a81c3d47..b706dd643 100644 --- a/views/home.erb +++ b/views/home.erb @@ -13,4 +13,6 @@ Last updated Jan 30, 2012 Sourcecode Download ePub Book + 中文翻译: 梁山 + Sourcecode - zh_CN From 3a014bc21a018f881287a8a99638577611ddcd26 Mon Sep 17 00:00:00 2001 From: Jonathan Clem Date: Wed, 31 Jul 2013 10:10:17 -0700 Subject: [PATCH 049/472] Add Google Tag Manager code --- views/layout.erb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/views/layout.erb b/views/layout.erb index 387b138b0..744006769 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -31,6 +31,18 @@ <% end %> + <% if ENV['GOOGLE_TAG_MANAGER_ACCOUNT'] %> + + + + + <% end %> +

The Twelve-Factor App

From 1d22bc35d6516b113ab7c69fce3d12c997bc4531 Mon Sep 17 00:00:00 2001 From: Ryan Daigle Date: Wed, 31 Jul 2013 13:25:18 -0400 Subject: [PATCH 050/472] Add gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6471d9f4c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.rvmrc From 55542c4a03bb14d51da660edc9a9a7de8216080d Mon Sep 17 00:00:00 2001 From: Raul Barroso Date: Fri, 9 Aug 2013 17:51:53 -0700 Subject: [PATCH 051/472] Change sourcecode repo --- views/home.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/home.erb b/views/home.erb index 6a81c3d47..054719174 100644 --- a/views/home.erb +++ b/views/home.erb @@ -11,6 +11,6 @@ From 71370e81dd56e6220a6d65dfe50d7040289fb65a Mon Sep 17 00:00:00 2001 From: Raul Barroso Date: Thu, 5 Sep 2013 13:22:32 -0700 Subject: [PATCH 052/472] Remove GA code --- views/layout.erb | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/views/layout.erb b/views/layout.erb index 744006769..2e4156f5e 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -15,20 +15,6 @@ - - <% if ENV['GOOGLE_ANALYTICS_KEY'] %> - - <% end %> <% if ENV['GOOGLE_TAG_MANAGER_ACCOUNT'] %> From 2df691ee496ca78dfce81b1b63dc0e2d70d00458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20Napur=C3=AD?= Date: Fri, 31 Jan 2014 10:45:46 -0500 Subject: [PATCH 053/472] Update disposability.md wrong link Fix link to Couchdb Overview article --- content/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/disposability.md b/content/disposability.md index cacbeb0ec..b66e95e63 100644 --- a/content/disposability.md +++ b/content/disposability.md @@ -9,6 +9,6 @@ Processes **shut down gracefully when they receive a [SIGTERM](http://en.wikiped 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](http://kr.github.com/beanstalkd/), 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://couchdb.apache.org/docs/overview.html). +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). From 2f7585acdda95277d4c16e23b8610224818fa6ac Mon Sep 17 00:00:00 2001 From: Michael Allen Date: Sat, 1 Feb 2014 19:35:36 +0000 Subject: [PATCH 054/472] fixing the mobile.css file to make 12factor have better responsive-ness. Changed the method of positioning the 'next' and 'prev' buttons from margin to padding as it increases the hit rectangle for mobile and tablet devices. --- public/css/mobile.css | 84 +++++++++++++++++++++++++++++++++++++++---- public/css/screen.css | 10 +++--- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/public/css/mobile.css b/public/css/mobile.css index 81b5c89ec..72ad90ace 100644 --- a/public/css/mobile.css +++ b/public/css/mobile.css @@ -1,3 +1,79 @@ +@media screen and (min-width: 1041px) { + + section { + min-width: 65em; + } + + article, nav { + max-width: 55em; + } +} + +@media screen and (min-width: 481px) and (max-width: 800px) { + article img { + float: none; + display: block; + margin: 0 auto; + } +} + +@media screen and (min-width: 481px) and (max-width: 1040px) { + + header { + font-size: 1em; + } + + article, nav { + width:85%; + min-width: none; + max-width: none; + } + + section, footer { + width:100%; + min-width: none; + max-width: none; + } + + article h1, article h2, article h3, article p, article table { + padding-left: 15px; + padding-right: 15px; + } + + article ul, article ol { + padding-left: 35px; + padding-right: 10px; + text-align: left; + } + + article table { + font-size: 0.8em; + } + + article table td { + padding-left: 0.25em; + padding-right: 0.25em; + } + + article img { + max-width: 100%; + margin-bottom: 1em; + } + + nav a { + padding:1em; + } + + nav a { + padding:1em; + } + + footer { + padding-left: 0; + padding-right: 0; + } +} + @media screen and (max-width: 480px) { header { font-size: 0.75em; @@ -34,12 +110,8 @@ margin-bottom: 1em; } - #prev { - margin-left: 1em; - } - - #next { - margin-right: 1em; + nav a { + padding: 1em; } footer { diff --git a/public/css/screen.css b/public/css/screen.css index 74d6eb81b..c058f8589 100644 --- a/public/css/screen.css +++ b/public/css/screen.css @@ -9,7 +9,7 @@ body { h1, h2, h3 { padding: 0; margin: 0; -} +} h1, h2 { line-height: 1.25em; @@ -40,8 +40,8 @@ header h1 a { section { padding-top: 16pt; text-align: center; - min-width: 65em; } + section h1 { font-size: 19pt; } @@ -49,16 +49,18 @@ section h1 { article { padding-top: 8pt; } + article, nav { margin: 0 auto; text-align: justify; - max-width: 55em; } + 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; } @@ -159,4 +161,4 @@ article img { article img.full { float: none; margin-left: 0; -} +} \ No newline at end of file From 7cdef83b1e421358c2d765fd6481a8b7a4949cf4 Mon Sep 17 00:00:00 2001 From: Yannick Schutz Date: Tue, 18 Feb 2014 22:18:59 +0100 Subject: [PATCH 055/472] Add mobi version --- public/12factor.mobi | Bin 0 -> 311884 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/12factor.mobi diff --git a/public/12factor.mobi b/public/12factor.mobi new file mode 100644 index 0000000000000000000000000000000000000000..23a194238a6cf609e16f8aa62ed331abfcaa0948 GIT binary patch literal 311884 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

@V51L`#B7S>EqSO%!BBdiFLy9#yn#@Z2?gMuM^j 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ðE?1%ukUgalRJ_ z^V(*UMlm5|jp zV*Fy}3nsRjMdwnVYx6sg?Uh&X;xM)6^9Hu+jhq23xfGhf`|WyTa<*5q#})<1i=%9n zS!6|U^- zP9<&o*9#qqw08AO?JpFW!mmCmXNx=MFW0J=2CBWzG?A9gGJNh1!Q4+Gqs-x7?^$93 zxX58I=KQ|nN9d498#hJDde{34M2+gs~L#LtY|?}}u4Rbx2JH}U$5;$n>hVG-W1 zFBzEhwr6ixtL~g?!U2_K3M=Ga#!om}@Qh}JCFoF zSu^&jlAD!WJ&K9-j6LDqL_0vFt}LgCIuMsy_zb1K8STG0s8O%cFp>-g#K^#h4z;49 zHQT~RiIZVD1ARuLwVuz}GLJVnCo!v^Jh-hn*zDp-ElcS_pW!wnr($Ua9pWRW8I$b7 zd^HEY71i8okuTYP($Yy-h-G}kJ}w5@P>(t4mB`;YasCRz!c>oy&*DElb~+~1$@rMn zSM>B`%6#tsI6A7b|Cszln){USyS>bb=dICg_=vT&y)1T8@nQ+E%zmdd(p5e9l${re z_Hn?1nne@o8y;x!a7L!>eEBXU@$(1wE!sSGxua%bx-31*8L`TQTJ?8U+oQhkA31NQ z-p0v3c1Q=q2b;DqPClB{I45<3S?<}Ji+!rE+lB_`J2i1CNrm-1C*wwuEeN*00UvC$omdx| zAe?Hj!)o9|yT^^9Zhy~?PM(L%G0@7Q2zlTz@kCi(TePC}C%MX+DC6+)Z{&}<=C{bb zMkqDfm;OiPWg|%DYpMIKdw$R~MrB^~U?h=`ywQ9?duG#(Vm%kxd?ZaHPm>I0eG44} zUk=C|l252%@{8ksn#FCEQ*(ejy6ylG73=v3G5X{|UQt3J?QC8C6BS>lb!JY{%*T%T z7na)H=7zL;JP`?giV6E1eWHS*hrW0ntgd7WqxXS=8m>#F~#ryH3m_dJV0+oyy<`~bvW1>FD^dRh z@$7K)4KL(Y3bJR}!j-pB^U?gP>o=QNZ`VX(vykDwZS!+u)x(i?!e8*^6t%){P8A0o za;r)!zS%$AJt2HjY0E&^ykGCvd*<+ubcjvWY=?`TBx$%=qYzbQOthJkgH=8gN>I*SdI-g!k8(IC z{5EZGhbJ>U?V}tnpXTz1_MS-|XSeL6_6U94%0D%Zq8#nU&Bx;^Gk7gjO`i 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%0D)Y-_sIzL;7|Z@PTk~Zaw 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%0AZysunHj|7WCXu-QDMD;dX592*oSMuR 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 literal 0 HcmV?d00001 From 4a2f64d1b4232e65c18fe08c08df2609572f817e Mon Sep 17 00:00:00 2001 From: Kingdon Barrett Date: Fri, 28 Mar 2014 11:43:07 -0400 Subject: [PATCH 056/472] 404 / typo One liner... did you mean 'codebase'? --- content/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/admin-processes.md b/content/admin-processes.md index 3ae04eeea..9963ca67a 100644 --- a/content/admin-processes.md +++ b/content/admin-processes.md @@ -7,7 +7,7 @@ The [process formation](/concurrency) is the array of processes that are used to * 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 `erl`) 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 [code](/code) and [config](/config) as any process run against that release. Admin code must ship with application code to avoid synchronization issues. +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. From 531c34eb6338f673d6cf63305853d3892b0fdd70 Mon Sep 17 00:00:00 2001 From: yourithielen Date: Tue, 13 May 2014 20:50:17 +0200 Subject: [PATCH 057/472] Typo in background text Not 100% sure if I get the first part of this sentence correct. Triangulation as in finding a sweet spot? --- content/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/background.md b/content/background.md index af26e1431..b9ecf6fbd 100644 --- a/content/background.md +++ b/content/background.md @@ -3,7 +3,7 @@ Background The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. -This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From da274e9940a7de3e0ec6a74f5bda6346b21c7acc Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 13 Jun 2014 11:32:14 +0200 Subject: [PATCH 058/472] Fixing typo: continUously There are no small contributions ;-) --- content/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/logs.md b/content/logs.md index 231a28c27..ab2f4f829 100644 --- a/content/logs.md +++ b/content/logs.md @@ -3,7 +3,7 @@ *Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continously as long as the app is operating. +Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. **A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. From c28d4b9a0b015a9d94d7af94af6eaeca8fd213fe Mon Sep 17 00:00:00 2001 From: Adam K Dean Date: Tue, 17 Jun 2014 13:47:21 +0100 Subject: [PATCH 059/472] Grammatical updates --- content/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/dependencies.md b/content/dependencies.md index b5bcb0343..bf5a2dd91 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -5,7 +5,7 @@ Most programming languages offer a packaging system for distributing support lib **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, [Gem Bundler](http://gembundler.com/) 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. +For example, [Gem Bundler](http://gembundler.com/) 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`. From a136e6bf1e1fef6d33550c369023fb9f8ee70c63 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Tue, 29 Jul 2014 09:17:59 +0100 Subject: [PATCH 060/472] add privacy policy --- views/home.erb | 7 +------ views/layout.erb | 10 +++++++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/views/home.erb b/views/home.erb index 054719174..8312b582f 100644 --- a/views/home.erb +++ b/views/home.erb @@ -8,9 +8,4 @@

<%= render_markdown('toc') %>
- + diff --git a/views/layout.erb b/views/layout.erb index 2e4156f5e..582bb5d95 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -12,7 +12,7 @@ - + @@ -34,5 +34,13 @@ <%= yield %> + + From e76eb5d4a46a5d52fc9ea4b9282ce211a9dac46d Mon Sep 17 00:00:00 2001 From: JanAhrens Date: Tue, 30 Sep 2014 06:59:15 +0200 Subject: [PATCH 061/472] Fix broken markup on main page --- views/home.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/home.erb b/views/home.erb index 8312b582f..77193f260 100644 --- a/views/home.erb +++ b/views/home.erb @@ -5,7 +5,7 @@
-
<%= render_markdown('toc') %>
+
<%= render_markdown('toc') %>
From 365f2e80201d046ab517199829b641096826be48 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Fri, 17 Oct 2014 09:05:38 -0300 Subject: [PATCH 062/472] First translate version of intro --- content/intro-pt.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/intro-pt.md diff --git a/content/intro-pt.md b/content/intro-pt.md new file mode 100644 index 000000000..4bba7c229 --- /dev/null +++ b/content/intro-pt.md @@ -0,0 +1,12 @@ +Introdução +============ + +Na era moderna, software é comumente entregue como um serviço: denominados *web apps*, ou *software-como-serviço*. A aplicação doze-fatores é uma metodologia para construir softwares-como-serviço que: + +* Usam formatos **declarativos** para automatizar a configuração inicial, minimizar tempo e custo para novos desenvolvedores participarem do projeto; +* Tem um **contrato claro** com o sistema operacional que o suporta, oferecendo **portabilidade máxima** entre ambientes que o executem; +* São adequados para **implantação** em modernas **plataformas em nuvem**, evitando a necessidade por servidores e administração do sistema; +* **Minimizam a divergência** entre desenvolvimento e produção, permitindo a **implantação contínua** para máxima agilidade; +* E podem **escalar** sem significativas mudanças em ferramentas, arquiteturas, ou práticas de desenvolvimento. + +A metodologia doze-fatores pode ser aplicada a aplicações escritas em qualquer linguagem de programação, e que utilizem qualquer combinação de serviços de suportes (banco de dados, filas, cache de memória, etc). \ No newline at end of file From 7c547dbbb95d857104cfc4fcc02d6d3e9dce03c0 Mon Sep 17 00:00:00 2001 From: Tibor Benke Date: Sun, 2 Nov 2014 18:22:39 +0100 Subject: [PATCH 063/472] fix typo in admin-processes.md --- content/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/admin-processes.md b/content/admin-processes.md index 9963ca67a..92344bfa0 100644 --- a/content/admin-processes.md +++ b/content/admin-processes.md @@ -4,7 +4,7 @@ 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 syncdb` 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 `erl`) or in some cases have a separate command (e.g. `irb` for Ruby, `rails console` for 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. From 90b0751e2fe21a788477b1bd9358b8a2a23db6eb Mon Sep 17 00:00:00 2001 From: Liang Shan Date: Tue, 4 Nov 2014 09:31:08 +0800 Subject: [PATCH 064/472] Update Readme.md --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index 124a7ca56..df6bd8c76 100644 --- a/Readme.md +++ b/Readme.md @@ -3,6 +3,8 @@ The Twelve-Factor App Source for the content app running at: http://www.12factor.net/ +中文翻译:http://liangshan.me/blog/2014/05/22/the-twelve-factor-app/ + Development ----------- From c52ad93cbaf2c8434645f6f2eb41112c1fd50b12 Mon Sep 17 00:00:00 2001 From: liangshan Date: Wed, 5 Nov 2014 14:51:50 +0800 Subject: [PATCH 065/472] Update to the latest version --- .rvmrc | 2 -- Gemfile | 2 +- Gemfile.lock | 6 ++++-- views/home.erb | 1 + web.rb | 16 +++------------- 5 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 .rvmrc diff --git a/.rvmrc b/.rvmrc deleted file mode 100644 index aaf7bc9db..000000000 --- a/.rvmrc +++ /dev/null @@ -1,2 +0,0 @@ -rvm use ruby-1.8.7@12factor --create - diff --git a/Gemfile b/Gemfile index 9f3a32d19..2d7d5aa87 100644 --- a/Gemfile +++ b/Gemfile @@ -2,4 +2,4 @@ source 'http://rubygems.org' gem 'sinatra', '1.2.6' gem 'thin', '1.2.7' -gem 'redcarpet', '2.1.0' +gem 'maruku', '0.6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 7b2bf9cb1..5a934fa1d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,11 +3,13 @@ GEM specs: daemons (1.1.3) eventmachine (0.12.10) + maruku (0.6.0) + syntax (>= 1.0.0) rack (1.3.0) - redcarpet (2.1.0) sinatra (1.2.6) rack (~> 1.1) tilt (>= 1.2.2, < 2.0) + syntax (1.0.0) thin (1.2.7) daemons (>= 1.0.9) eventmachine (>= 0.12.6) @@ -18,6 +20,6 @@ PLATFORMS ruby DEPENDENCIES - redcarpet (= 2.1.0) + maruku (= 0.6.0) sinatra (= 1.2.6) thin (= 1.2.7) diff --git a/views/home.erb b/views/home.erb index d05fcff34..fc714b7d8 100644 --- a/views/home.erb +++ b/views/home.erb @@ -7,3 +7,4 @@
<%= render_markdown('toc') %>
+ diff --git a/web.rb b/web.rb index f18675611..a53c0cc35 100644 --- a/web.rb +++ b/web.rb @@ -1,5 +1,5 @@ require 'sinatra' -require 'redcarpet' +require 'maruku' get '/' do erb :home @@ -15,18 +15,8 @@ helpers do def render_markdown(file) - text = File.read("content/#{file}.md") - markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, - :fenced_code_blocks => true, - :no_intra_emphasis => true, - :autolink => true, - :strikethrough => true, - :lax_html_blocks => true, - :superscript => true, - :hard_wrap => true, - :tables => true, - :xhtml => true) - markdown.render(text) + markdown = File.read("content/#{file}.md") + Maruku.new(markdown).to_html rescue Errno::ENOENT puts "No content for #{file}, skipping" end From 3a33a71bf23cb6a22e7d49edcad01dbe6d02470a Mon Sep 17 00:00:00 2001 From: liangshan Date: Wed, 5 Nov 2014 15:48:20 +0800 Subject: [PATCH 066/472] Add spaces between Chinese and English --- content/admin-processes.md | 8 ++++---- content/background.md | 2 +- content/backing-services.md | 8 ++++---- content/build-release-run.md | 6 +++--- content/codebase.md | 8 ++++---- content/concurrency.md | 8 ++++---- content/config.md | 12 ++++++------ content/dependencies.md | 10 +++++----- content/dev-prod-parity.md | 20 ++++++++++---------- content/disposability.md | 8 ++++---- content/intro.md | 12 ++++++------ content/logs.md | 8 ++++---- content/port-binding.md | 8 ++++---- content/processes.md | 8 ++++---- content/who.md | 2 +- 15 files changed, 64 insertions(+), 64 deletions(-) diff --git a/content/admin-processes.md b/content/admin-processes.md index 8928892d7..95772c61f 100644 --- a/content/admin-processes.md +++ b/content/admin-processes.md @@ -3,12 +3,12 @@ [进程构成](/concurrency) 是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: -* 运行数据移植(Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate`)。 -* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具(`python` 或 `erl`) ,或是其他命令(Ruby 使用 `irb`, Rails 使用 `rails console` )。 -* 运行一些提交到代码仓库的一次性脚本。 +* 运行数据移植( Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate` )。 +* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell ),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具( `python` 或 `erl` ) ,或是其他命令( Ruby 使用 `irb`, Rails 使用 `rails console` )。 +* 运行一些提交到代码仓库的一次性脚本。\n 一次性管理进程应该和正常的 [常驻进程](/processes) 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 [代码](/codebase) 和 [配置](/config) ,基于某个 [发布版本](/build-release-run) 运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。 -所有进程类型应该使用同样的 [依赖隔离](/dependencies) 技术。例如,如果Ruby的web进程使用了命令 `bundle exec thin start` ,那么数据库移植应使用 `bundle exec rake db:migrate` 。同样的,如果一个 Python 程序使用了 Virtualenv,则需要在运行 Tornado Web 服务器和任何 `manage.py` 管理进程时引入 ‵bin/python‵ 。 +所有进程类型应该使用同样的 [依赖隔离](/dependencies) 技术。例如,如果Ruby的web进程使用了命令 `bundle exec thin start` ,那么数据库移植应使用 `bundle exec rake db:migrate` 。同样的,如果一个 Python 程序使用了 Virtualenv,则需要在运行 Tornado Web 服务器和任何 `manage.py` 管理进程时引入 `bin/python` 。 12-factor 尤其青睐那些提供了 REPL shell 的语言,因为那会让运行一次性脚本变得简单。在本地部署中,开发人员直接在命令行使用 shell 命令调用一次性管理进程。在线上部署中,开发人员依旧可以使用ssh或是运行环境提供的其他机制来运行这样的进程。 diff --git a/content/background.md b/content/background.md index b22893e07..abcdedddb 100644 --- a/content/background.md +++ b/content/background.md @@ -3,7 +3,7 @@ 本文的贡献者者参与过数以百计的应用程序的开发和部署,并通过 [Heroku](http://www.heroku.com/) 平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 -本文综合了我们关于 SaaS 应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何[避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 +本文综合了我们关于 SaaS 应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何 [避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 我们的初衷是分享在现代软件开发过程中发现的一些系统性问题,并加深对这些问题的认识。我们提供了讨论这些问题时所需的共享词汇,同时使用相关术语给出一套针对这些问题的广义解决方案。本文格式的灵感来自于 Martin Fowler 的书籍: *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* , *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* 。 diff --git a/content/backing-services.md b/content/backing-services.md index 3a7a8ff6c..33becb65a 100644 --- a/content/backing-services.md +++ b/content/backing-services.md @@ -1,13 +1,13 @@ ## IV. 后端服务 ### 把后端服务(*backing services*)当作附加资源 -*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP邮件发送服务([Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 +*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库( [MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/) ),消息/队列系统( [RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/) ),SMTP 邮件发送服务( [ Postfix](http://www.postfix.org/) ),以及缓存系统( [Memcached](http://memcached.org/) )。 -类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如[Amazon S3](http://http://aws.amazon.com/s3/)),以及使用API访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 +类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/) ),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/) ),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/) ),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 -**12-Factor应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个url或是其他存储在 [配置](/config) 中的服务定位/服务证书来获取数据。12-Factor应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,将本地MySQL数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地SMTP服务应该也可以和第三方SMTP服务(例如Postmark)互换。上述2个例子中,仅需修改配置中的资源地址。 +**12-Factor 应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 [配置](/config) 中的服务定位/服务证书来获取数据。12-Factor 应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换。上述 2 个例子中,仅需修改配置中的资源地址。 -每个不同的后端服务是一份 *资源* 。例如,一个MySQL数据库是一个资源,两个MySQL数据库(用来数据分区)就被当作是2个不同的资源。Twelve-factor应用将这些数据库都视作 *附加资源* ,这些资源和它们附属的部署保持松耦合。 +每个不同的后端服务是一份 *资源* 。例如,一个 MySQL 数据库是一个资源,两个 MySQL 数据库(用来数据分区)就被当作是 2 个不同的资源。12-Factor 应用将这些数据库都视作 *附加资源* ,这些资源和它们附属的部署保持松耦合。 一种部署附加4个后端服务 diff --git a/content/build-release-run.md b/content/build-release-run.md index 9af378350..d7b3633db 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -3,9 +3,9 @@ [基准代码](/codebase) 转化为一份部署(非开发环境)需要以下三个阶段: -* *构建阶段* 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包[依赖项](/dependencies),编译成二进制文件和资源文件。 +* *构建阶段* 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包 [依赖项](/dependencies),编译成二进制文件和资源文件。 * *发布阶段* 会将构建的结果和当前部署所需 [配置](/config) 相结合,并能够立刻在运行环境中投入使用。 -* *运行阶段* (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序[进程](/processes)。 +* *运行阶段* (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 [进程](/processes)。 ![代码被构建,然后和配置结合成为发布版本](/images/release.png) @@ -13,6 +13,6 @@ 部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 -每一个发布版本必须对应一个唯一的发布ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 +每一个发布版本必须对应一个唯一的发布 ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,从而得到妥善处理。 \ No newline at end of file diff --git a/content/codebase.md b/content/codebase.md index b1ba6d11c..c0bc1bc9d 100644 --- a/content/codebase.md +++ b/content/codebase.md @@ -1,7 +1,7 @@ ## I. 基准代码 -### 一份基准代码(*Codebase*),多份部署(*deploy*) +### 一份基准代码(*Codebase*),多份部署(*deploy*) -12-Factor App(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 +12-Factor 应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 在类似SVN这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 @@ -9,8 +9,8 @@ 基准代码和应用之间总是保持一一对应的关系: -* 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用12-Factor进行开发。 -* 多个应用共享一份基准代码是有悖于12-Factor原则的。解决方案是将共享的代码拆分为独立的类库,然后使用[依赖管理](/dependencies)策略去加载它们。 +* 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用 12-Factor 进行开发。 +* 多个应用共享一份基准代码是有悖于 12-Factor 原则的。解决方案是将共享的代码拆分为独立的类库,然后使用 [依赖管理](/dependencies) 策略去加载它们。 尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 diff --git a/content/concurrency.md b/content/concurrency.md index 85d9ec8ff..45d7c487d 100644 --- a/content/concurrency.md +++ b/content/concurrency.md @@ -1,14 +1,14 @@ ## VIII. 并发 ### 通过进程模型进行扩展 -任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP进程作为Apache的子进程存在,随请求按需启动。Java进程则采取了相反的方式,在程序启动之初JVM就提供了一个超级进程储备了大量的系统资源(CPU和内存),并通过多线程实现内部的并发管理。上述2个例子中,进程是开发人员可以操作的最小单位。 +任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP 进程作为 Apache 的子进程存在,随请求按需启动。Java 进程则采取了相反的方式,在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源( CPU 和内存),并通过多线程实现内部的并发管理。上述 2 个例子中,进程是开发人员可以操作的最小单位。 ![扩展表现为运行中的进程,工作多样性表现为进程类型。](/images/process-types.png) -**在12-factor应用中,进程是一等公民。** 12-factor应用的进程主要借鉴于 [unix守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP请求可以交给web进程来处理,而常驻的后台工作则交由worker进程负责。 +**在 12-actor 应用中,进程是一等公民。** 12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 -上述进程模型会在系统急需扩展时大放异彩。 [12-factor应用的进程所具备的无共享,水平分区的特性](/processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 +上述进程模型会在系统急需扩展时大放异彩。 [12-Factor 应用的进程所具备的无共享,水平分区的特性](/processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 -12-factor应用的进程 [不需要守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入PID文件。相反的,应该借助操作系统的进程管理器(例如 [Upstart](http://upstart.ubuntu.com/) ,分布式的进程管理云平台,或是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),来管理 [输出流](/logs) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 +12-Factor 应用的进程 [不需要守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入 PID 文件。相反的,应该借助操作系统的进程管理器(例如 [Upstart](http://upstart.ubuntu.com/) ,分布式的进程管理云平台,或是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),来管理 [输出流](/logs) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 diff --git a/content/config.md b/content/config.md index a3e7209a3..60fda4cf3 100644 --- a/content/config.md +++ b/content/config.md @@ -4,19 +4,19 @@ 通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: * 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 -* 第三方服务的证书,如Amazon S3、Twitter等 +* 第三方服务的证书,如 Amazon S3、Twitter 等 * 每份部署特有的配置,如域名等 -有些应用在代码中使用常量保存配置,这与12-factor所要求的 **代码和配置严格分离** 显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 +有些应用在代码中使用常量保存配置,这与 12-Factor 所要求的**代码和配置严格分离**显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。 -需要指出的是,这里定义的"配置"并 **不** 包括应用的内部配置,比如Rails的 `config/routes.rb`,或是使用[Spring](http://www.springsource.org/)时[代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 +需要指出的是,这里定义的"配置"并**不**包括应用的内部配置,比如 Rails 的 `config/routes.rb`,或是使用 [Spring](http://www.springsource.org/) 时 [代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像Rails的 `config/database.yml` 。这相对于在代码中使用常量已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的可能会分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 -**12-Factor推荐将应用的配置存储于 *环境变量* 中** (*env vars*, *env*) 。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如Java的属性配置文件)相比,环境变量与语言和系统无关。 +**12-Factor推荐将应用的配置存储于 *环境变量* 中**( *env vars*, *env* )。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如 Java 的属性配置文件)相比,环境变量与语言和系统无关。 -配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 +配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如 Rails 中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 -12-Factor应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 +12-Factor 应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 diff --git a/content/dependencies.md b/content/dependencies.md index d08d643bd..3a1660b31 100644 --- a/content/dependencies.md +++ b/content/dependencies.md @@ -1,12 +1,12 @@ ## II. 依赖 -### 显式声明依赖关系(*dependency*) +### 显式声明依赖关系( *dependency* ) -大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的 [CPAN](http://www.cpan.org/) 或是Ruby的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为"site packages"),或仅供某个应用程序使用,部署在相应的目录中(称之为"vendoring"或"bunding")。 +大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像 Perl 的 [CPAN](http://www.cpan.org/) 或是 Ruby 的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为 "site packages" ),或仅供某个应用程序使用,部署在相应的目录中(称之为 "vendoring" 或 "bunding" )。 **12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它一定通过 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 -例如, Ruby的[Gem Bundler](http://gembundler.com/) 使用`Gemfile`作为依赖项声明清单,使用`bundle exec`来进行依赖隔离。Python中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至C语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 +例如, Ruby 的 [Gem Bundler](http://gembundler.com/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 -显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler下使用`bundle install`,而Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是`lein deps`。 +显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler 下使用 `bundle install`,而 Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是 `lein deps`。 -12-Factor应用同样不会隐式依赖某些系统工具,如ImageMagick或是`curl`。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file +12-Factor 应用同样不会隐式依赖某些系统工具,如 ImageMagick 或是`curl`。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file diff --git a/content/dev-prod-parity.md b/content/dev-prod-parity.md index 5d3b15109..b99d6c297 100644 --- a/content/dev-prod-parity.md +++ b/content/dev-prod-parity.md @@ -3,15 +3,15 @@ 从以往经验来看,开发环境(即开发人员的本地 [部署](/codebase))和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面: -* **时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 -* **人员差异:** 开发人员编写代码,运维人员部署代码。 -* **工具差异:** 开发人员或许使用Nginx,SQLite,OS X,而线上环境使用Apache,MySQL以及Linux。 +* **\[The time gap\] 时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 +* **\[The personnel gap\]人员差异:** 开发人员编写代码,运维人员部署代码。 +* **\[The tools gap\]工具差异:** 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。 -**12-factor应用想要做到 [持续部署](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: +**12-Factor 应用想要做到 [持续部署](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: -* 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 -* 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 -* 缩小工具差异:尽量保证开发环境以及线上环境的一致性。 +* \[1\]缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 +* \[2\]缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 +* \[3\]缩小工具差异:尽量保证开发环境以及线上环境的一致性。 将上述总结变为一个表格如下: @@ -19,7 +19,7 @@ 传统应用 - 12-factor应用 + 12-Factor 应用 每次部署间隔 @@ -67,9 +67,9 @@ -开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力,而那些更重量级的健壮的后端服务应该使用在生产环境。例如,本地使用SQLite线上使用PostgreSQL;又如本地缓存在进程内存中而线上存入Memcached。 +开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力,而那些更重量级的健壮的后端服务应该使用在生产环境。例如,本地使用 SQLite 线上使用 PostgreSQL;又如本地缓存在进程内存中而线上存入 Memcached。 -**12-factor应用的开发人员应该反对在不同环境间使用不同的后端服务** ,即使适配器已经可以几乎消除使用上的差异。这是因为,不同的后端服务意味着会突然出现的不兼容,从而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看,消除这种阻力需要花费很大的代价。 +**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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 diff --git a/content/disposability.md b/content/disposability.md index 89056e016..66b57c0ba 100644 --- a/content/disposability.md +++ b/content/disposability.md @@ -1,13 +1,13 @@ ## IX. 易处理 ### 快速启动和优雅终止可最大化健壮性 -**12-factor应用的 [进程](/processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](/codebase) 或 [配置](/config) ,稳健的部署应用。 +**12-Factor 应用的 [进程](/processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](/codebase) 或 [配置](/config) ,稳健的部署应用。 进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](/build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 -进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 +进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是 HTTP 请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 -对于worker进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker可以发送一个 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) 信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 +对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) 信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 -进程还应当 **在面对突然死亡时保持健壮** ,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-factor应用都应该可以设计能够应对意外的、不优雅的终结。 [Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 +进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。 [Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 diff --git a/content/intro.md b/content/intro.md index ed81a1876..c5f8309f1 100644 --- a/content/intro.md +++ b/content/intro.md @@ -1,11 +1,11 @@ 简介 ============ -如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”(SaaS)。“十二要素应用程序”(12-Factor App)为构建如下的SaaS应用提供了方法论: +如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”( SaaS )。12-Factor 为构建如下的 SaaS 应用提供了方法论: -* 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目; -* 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**; -* 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源; -* 将开发环境和生产环境的**差异降至最低**,并使用**持续交付**实施敏捷开发; -* 可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**; +* 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目;\n +* 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**;\n +* 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源;\n +* 将开发环境和生产环境的**差异降至最低**,并使用**持续交付**实施敏捷开发;\n +* 可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**;\n 这套理论适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序。 diff --git a/content/logs.md b/content/logs.md index c5add1912..edb24acad 100644 --- a/content/logs.md +++ b/content/logs.md @@ -5,12 +5,12 @@ 日志应该是 [事件流](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) 的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行,日志最原始的格式确实是一个事件一行。日志没有确定开始和结束,但随着应用在运行会持续的增加。 -**12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(`stdout`)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 +**12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出( `stdout` )事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 [Logplex](https://github.com/heroku/logplex) 和 [Fluent](https://github.com/fluent/fluentd) 的开源工具可以达到这个目的。 这些事件流可以输出至文件,或者在终端实时观察。最重要的,输出流可以发送到 [Splunk](http://www.splunk.com/) 这样的日志索引及分析系统,或 [Hadoop/Hive](http://hive.apache.org/) 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括: -* 找出过去一段时间特殊的事件。 -* 图形化一个大规模的趋势,比如每分钟的请求量。 -* 根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。 +* \[1\]找出过去一段时间特殊的事件。 +* \[2\]图形化一个大规模的趋势,比如每分钟的请求量。 +* \[3\]根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。 diff --git a/content/port-binding.md b/content/port-binding.md index b97157e44..9d1061982 100644 --- a/content/port-binding.md +++ b/content/port-binding.md @@ -1,14 +1,14 @@ ## VII. 端口绑定 ### 通过端口绑定(*Port binding*)来提供服务 -互联网应用有时会运行于服务器的容器之中。例如PHP经常作为 [Apache HTTPD](http://httpd.apache.org/) 的一个模块来运行,正如Java运行于 [Tomcat](http://tomcat.apache.org/) 。 +互联网应用有时会运行于服务器的容器之中。例如PHP经常作为 [Apache HTTPD](http://httpd.apache.org/) 的一个模块来运行,正如 Java 运行于 [Tomcat](http://tomcat.apache.org/) 。 -**12-factor应用完全自我加载** 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 **通过端口绑定来提供服务** ,并监听发送至该端口的请求。 +**12-Factor 应用完全自我加载** 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 **通过端口绑定来提供服务** ,并监听发送至该端口的请求。 本地环境中,开发人员通过类似 `http://localhost:5000/` 的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 -通常的实现思路是,将网络服务器类库通过 [依赖声明](/dependencies) 载入应用。例如,Python的[Tornado](http://www.tornadoweb.org/), Ruby的[Thin](http://code.macournoyer.com/thin/) , Java以及其他基于JVM语言的 [Jetty](http://jetty.codehaus.org/jetty/) 。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 +通常的实现思路是,将网络服务器类库通过 [依赖声明](/dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://jetty.codehaus.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 -HTTP并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 +HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](/backing-services) ,调用方将服务方提供的相应URL当作资源存入 [配置](/config) 以备将来调用。 \ No newline at end of file diff --git a/content/processes.md b/content/processes.md index aaf13b956..e55790c54 100644 --- a/content/processes.md +++ b/content/processes.md @@ -3,12 +3,12 @@ 运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py`)。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是零个或多个进程实例。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py` )。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是零个或多个进程实例。 -**Twelve-factor应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 +**12-Factor 应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-factor应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 +源文件打包工具( [Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/) ) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 -一些互联网系统依赖于 [“粘性session”] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) , 这是指将用户session中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性Session是twelve-factor极力反对的。Session中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 +一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 diff --git a/content/who.md b/content/who.md index 8946e6ad5..c54277fae 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ 读者应该是哪些人? ============================== -任何SaaS应用的开发人员。部署和管理此类应用的运维工程师。 +任何 SaaS 应用的开发人员。部署和管理此类应用的运维工程师。 From ad8540f632b0303d95326c7b85c3c0b32ef07bdb Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Wed, 28 Jan 2015 13:27:39 -0200 Subject: [PATCH 067/472] [pt-br] Translate Background --- content/background-pt.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 content/background-pt.md diff --git a/content/background-pt.md b/content/background-pt.md new file mode 100644 index 000000000..5c2f1d392 --- /dev/null +++ b/content/background-pt.md @@ -0,0 +1,8 @@ +Experiência +=========== + +Os contribuidores deste documento estão diretamente envolvidos no desenvolvimento e implantação de centenas de aplicativos, e indiretamente testemunhando o desenvolvimento, operação e escalada de centenas de milhares de aplicações através de seu trabalho na plataforma [Heroku](http://www.heroku.com/). + +Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangularização de práticas ideias ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) + +Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatornado](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file From 79af0be7b87c96cd3d3800491dc37d360eb9df25 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 13:57:09 -0300 Subject: [PATCH 068/472] Tranlated who.md --- content/who.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/who.md b/content/who.md index 49eb40fd5..4cbf0fe68 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ -Who should read this document? -============================== +Quem deve ler este documento? +============================= -Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. +Qualquer desenvolvedor que esta construindo aplicações que rodam como serviço. Engenheiros de Operações que implantam ou administram tais aplicações. From f01a98da8e02a7b67bf66aaeb43e3a20ab220a6b Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 14:55:42 -0300 Subject: [PATCH 069/472] Add toc-pt.md --- content/toc-pt.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 content/toc-pt.md diff --git a/content/toc-pt.md b/content/toc-pt.md new file mode 100644 index 000000000..e5c902266 --- /dev/null +++ b/content/toc-pt.md @@ -0,0 +1,39 @@ +The Twelve Factors +================== + +## [I. Base de Código](/codebase) +### Uma base de código monitorada em controle de revisão, muitos deploys + +## [II. Dependências](/dependencies) +### Declare e isole as dependências + +## [III. Configurações](/config) +### Armazene as configurações no ambiente + +## [IV. Serviços de Apoio](/backing-services) +### Trate os serviços de apoio, como recursos ligados + +## [V. Build, release, run](/build-release-run) +### Separe estritamente os builds e execute em estágios + +## [VI. Processos](/processes) +### Execute a aplicação como um ou mais processos stateless + +## [VII. Ligação de porta](/port-binding) +### Exporte serviços por ligação de porta + +## [VIII. Concorrência](/concurrency) +### Dimensione por um modelo de processo + +## [IX. Disponibilidade](/disposability) +### Maximizar a robustez com inicialização e desligamento rápido +Maximize robustness with fast startup and graceful shutdown + +## [X. Dev/prod semelhantes](/dev-prod-parity) +### Mantenha o desenvolvimento, teste, produção e mais semelhante possível + +## [XI. Logs](/logs) +### Trate logs como fluxo de eventos + +## [XII. Procesos de Admin](/admin-processes) +### Executar tarefas de administração/gerenciamento como processos pontuais From 262d4e1e677e9f6228b3035ca96c2c7ef576c192 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 14:56:08 -0300 Subject: [PATCH 070/472] Recover toc.md --- content/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/toc.md b/content/toc.md index fc2ede4bb..a1c8e4ad5 100644 --- a/content/toc.md +++ b/content/toc.md @@ -35,4 +35,4 @@ The Twelve Factors ### Treat logs as event streams ## [XII. Admin processes](/admin-processes) -### Run admin/management tasks as one-off processes +### Run admin/management tasks as one-off processes \ No newline at end of file From 95cba4fd46779651bcc8fd19f3669b24a9589abc Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 14:56:43 -0300 Subject: [PATCH 071/472] Recover who.md --- content/who.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/who.md b/content/who.md index 4cbf0fe68..49eb40fd5 100644 --- a/content/who.md +++ b/content/who.md @@ -1,4 +1,4 @@ -Quem deve ler este documento? -============================= +Who should read this document? +============================== -Qualquer desenvolvedor que esta construindo aplicações que rodam como serviço. Engenheiros de Operações que implantam ou administram tais aplicações. +Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. From 2bae870efd86343dcfaf638a75ef961ef7830058 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 14:56:56 -0300 Subject: [PATCH 072/472] Add who-pt.md --- content/who-pt.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 content/who-pt.md diff --git a/content/who-pt.md b/content/who-pt.md new file mode 100644 index 000000000..4cbf0fe68 --- /dev/null +++ b/content/who-pt.md @@ -0,0 +1,4 @@ +Quem deve ler este documento? +============================= + +Qualquer desenvolvedor que esta construindo aplicações que rodam como serviço. Engenheiros de Operações que implantam ou administram tais aplicações. From 4f529a1026654142ff804ce54233d388d0221b4d Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 15:16:13 -0300 Subject: [PATCH 073/472] Add sugestion of @fernandes --- content/toc-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/toc-pt.md b/content/toc-pt.md index e5c902266..19796a9d9 100644 --- a/content/toc-pt.md +++ b/content/toc-pt.md @@ -2,7 +2,7 @@ The Twelve Factors ================== ## [I. Base de Código](/codebase) -### Uma base de código monitorada em controle de revisão, muitos deploys +### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys ## [II. Dependências](/dependencies) ### Declare e isole as dependências From aef183f3e8c322b7d594da81df5b9b31e1ddf586 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 15:22:28 -0300 Subject: [PATCH 074/472] Remove english line --- content/toc-pt.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/toc-pt.md b/content/toc-pt.md index 19796a9d9..55f8d8f52 100644 --- a/content/toc-pt.md +++ b/content/toc-pt.md @@ -27,7 +27,6 @@ The Twelve Factors ## [IX. Disponibilidade](/disposability) ### Maximizar a robustez com inicialização e desligamento rápido -Maximize robustness with fast startup and graceful shutdown ## [X. Dev/prod semelhantes](/dev-prod-parity) ### Mantenha o desenvolvimento, teste, produção e mais semelhante possível From ebbe1cc5d5b50707092f6e399f5ed61c184518d2 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 15:23:48 -0300 Subject: [PATCH 075/472] =?UTF-8?q?Change=20"e=20mais=20semelhante=20poss?= =?UTF-8?q?=C3=ADvel"=20to=20"o=20mais=20semelhante=20poss=C3=ADvel"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/toc-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/toc-pt.md b/content/toc-pt.md index 55f8d8f52..bd2630f50 100644 --- a/content/toc-pt.md +++ b/content/toc-pt.md @@ -29,7 +29,7 @@ The Twelve Factors ### Maximizar a robustez com inicialização e desligamento rápido ## [X. Dev/prod semelhantes](/dev-prod-parity) -### Mantenha o desenvolvimento, teste, produção e mais semelhante possível +### Mantenha o desenvolvimento, teste, produção o mais semelhante possível ## [XI. Logs](/logs) ### Trate logs como fluxo de eventos From 6a24f7cf6a576d0464a35029caff8df0496b9646 Mon Sep 17 00:00:00 2001 From: George Moura Date: Wed, 28 Jan 2015 15:30:10 -0300 Subject: [PATCH 076/472] Add sugestion --- content/toc-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/toc-pt.md b/content/toc-pt.md index bd2630f50..0b8c0a450 100644 --- a/content/toc-pt.md +++ b/content/toc-pt.md @@ -17,7 +17,7 @@ The Twelve Factors ### Separe estritamente os builds e execute em estágios ## [VI. Processos](/processes) -### Execute a aplicação como um ou mais processos stateless +### Execute a aplicação como um ou mais processos que não armazenam estado ## [VII. Ligação de porta](/port-binding) ### Exporte serviços por ligação de porta From b8f8cf5ab911e4d1ac2ef545dd741b2095576796 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Fri, 30 Jan 2015 10:32:39 -0200 Subject: [PATCH 077/472] Fix some typo, thanks @gwmoura --- content/background-pt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/background-pt.md b/content/background-pt.md index 5c2f1d392..5135af5bf 100644 --- a/content/background-pt.md +++ b/content/background-pt.md @@ -1,8 +1,8 @@ Experiência =========== -Os contribuidores deste documento estão diretamente envolvidos no desenvolvimento e implantação de centenas de aplicativos, e indiretamente testemunhando o desenvolvimento, operação e escalada de centenas de milhares de aplicações através de seu trabalho na plataforma [Heroku](http://www.heroku.com/). +Os contribuidores deste documento estão diretamente envolvidos no desenvolvimento e implantação de centenas de aplicações, e indiretamente testemunhando o desenvolvimento, operação e escalada de centenas de milhares de aplicações através de seu trabalho na plataforma [Heroku](http://www.heroku.com/). Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangularização de práticas ideias ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) -Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatornado](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file +Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatorando](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file From a50d01f8fc5f2b6aeab862c7eed1877a451e8a5e Mon Sep 17 00:00:00 2001 From: George Moura Date: Fri, 30 Jan 2015 12:54:15 -0300 Subject: [PATCH 078/472] Rename toc-pt.md to toc-br.md --- content/toc-br.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 content/toc-br.md diff --git a/content/toc-br.md b/content/toc-br.md new file mode 100644 index 000000000..0b8c0a450 --- /dev/null +++ b/content/toc-br.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Base de Código](/codebase) +### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys + +## [II. Dependências](/dependencies) +### Declare e isole as dependências + +## [III. Configurações](/config) +### Armazene as configurações no ambiente + +## [IV. Serviços de Apoio](/backing-services) +### Trate os serviços de apoio, como recursos ligados + +## [V. Build, release, run](/build-release-run) +### Separe estritamente os builds e execute em estágios + +## [VI. Processos](/processes) +### Execute a aplicação como um ou mais processos que não armazenam estado + +## [VII. Ligação de porta](/port-binding) +### Exporte serviços por ligação de porta + +## [VIII. Concorrência](/concurrency) +### Dimensione por um modelo de processo + +## [IX. Disponibilidade](/disposability) +### Maximizar a robustez com inicialização e desligamento rápido + +## [X. Dev/prod semelhantes](/dev-prod-parity) +### Mantenha o desenvolvimento, teste, produção o mais semelhante possível + +## [XI. Logs](/logs) +### Trate logs como fluxo de eventos + +## [XII. Procesos de Admin](/admin-processes) +### Executar tarefas de administração/gerenciamento como processos pontuais From c26b9cb889bf5f7cabdf5fa03315b4b598b3425f Mon Sep 17 00:00:00 2001 From: George Moura Date: Fri, 30 Jan 2015 12:55:20 -0300 Subject: [PATCH 079/472] toc-pt.md renamed to toc-br.md --- content/toc-pt.md | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 content/toc-pt.md diff --git a/content/toc-pt.md b/content/toc-pt.md deleted file mode 100644 index 0b8c0a450..000000000 --- a/content/toc-pt.md +++ /dev/null @@ -1,38 +0,0 @@ -The Twelve Factors -================== - -## [I. Base de Código](/codebase) -### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys - -## [II. Dependências](/dependencies) -### Declare e isole as dependências - -## [III. Configurações](/config) -### Armazene as configurações no ambiente - -## [IV. Serviços de Apoio](/backing-services) -### Trate os serviços de apoio, como recursos ligados - -## [V. Build, release, run](/build-release-run) -### Separe estritamente os builds e execute em estágios - -## [VI. Processos](/processes) -### Execute a aplicação como um ou mais processos que não armazenam estado - -## [VII. Ligação de porta](/port-binding) -### Exporte serviços por ligação de porta - -## [VIII. Concorrência](/concurrency) -### Dimensione por um modelo de processo - -## [IX. Disponibilidade](/disposability) -### Maximizar a robustez com inicialização e desligamento rápido - -## [X. Dev/prod semelhantes](/dev-prod-parity) -### Mantenha o desenvolvimento, teste, produção o mais semelhante possível - -## [XI. Logs](/logs) -### Trate logs como fluxo de eventos - -## [XII. Procesos de Admin](/admin-processes) -### Executar tarefas de administração/gerenciamento como processos pontuais From f8ad94f3226927c19c8e4b566fa119309e3f36be Mon Sep 17 00:00:00 2001 From: George Moura Date: Fri, 30 Jan 2015 13:24:03 -0300 Subject: [PATCH 080/472] Translated paragraph 1 --- content/dependencies-br.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/dependencies-br.md diff --git a/content/dependencies-br.md b/content/dependencies-br.md new file mode 100644 index 000000000..fd7bc13b0 --- /dev/null +++ b/content/dependencies-br.md @@ -0,0 +1,14 @@ +## II. Dependências +### Declare e isole explicitamente as dependências + +A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistemas de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou no escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). + +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, [Gem Bundler](http://gembundler.com/) 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. From 7f8387412c557371ac63dac77bb4a1b158ed311a Mon Sep 17 00:00:00 2001 From: George Moura Date: Fri, 30 Jan 2015 14:45:19 -0300 Subject: [PATCH 081/472] Translated paragraph 2 --- content/dependencies-br.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/content/dependencies-br.md b/content/dependencies-br.md index fd7bc13b0..adc28e198 100644 --- a/content/dependencies-br.md +++ b/content/dependencies-br.md @@ -1,11 +1,9 @@ ## II. Dependências ### Declare e isole explicitamente as dependências -A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistemas de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou no escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). +A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistemas de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou com escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). -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. +**Uma aplicação twelve-factor nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. For example, [Gem Bundler](http://gembundler.com/) 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. From 6158b3aa65708eab87c0b9a6cb8cb2f42cf9873d Mon Sep 17 00:00:00 2001 From: George Moura Date: Fri, 30 Jan 2015 15:12:30 -0300 Subject: [PATCH 082/472] Translated paragraph 3 --- content/dependencies-br.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/dependencies-br.md b/content/dependencies-br.md index adc28e198..aec5d618a 100644 --- a/content/dependencies-br.md +++ b/content/dependencies-br.md @@ -5,7 +5,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação twelve-factor nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. -For example, [Gem Bundler](http://gembundler.com/) 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. +Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer 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`. From 5f233db17ab50d99c5a884270b3a4e0265613aae Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Fri, 30 Jan 2015 16:44:40 -0200 Subject: [PATCH 083/472] =?UTF-8?q?triangulariza=C3=A7=C3=A3o=20->=20trian?= =?UTF-8?q?gula=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/background-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/background-pt.md b/content/background-pt.md index 5135af5bf..7591723a2 100644 --- a/content/background-pt.md +++ b/content/background-pt.md @@ -3,6 +3,6 @@ Experiência Os contribuidores deste documento estão diretamente envolvidos no desenvolvimento e implantação de centenas de aplicações, e indiretamente testemunhando o desenvolvimento, operação e escalada de centenas de milhares de aplicações através de seu trabalho na plataforma [Heroku](http://www.heroku.com/). -Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangularização de práticas ideias ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) +Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangulação de práticas ideias ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatorando](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file From 0d390769e6749757db245cf8f29be315a45351aa Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 31 Jan 2015 01:33:57 -0300 Subject: [PATCH 084/472] Translated paragraph 4 --- content/dependencies-br.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/dependencies-br.md b/content/dependencies-br.md index aec5d618a..fdfe2d4af 100644 --- a/content/dependencies-br.md +++ b/content/dependencies-br.md @@ -7,6 +7,6 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer 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`. +Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, equanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `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. From c46bd9ec284de5d1c00e7632f2fb96185d638274 Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 31 Jan 2015 12:58:38 -0300 Subject: [PATCH 085/472] Translate paragraph 4 --- content/dependencies-br.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/dependencies-br.md b/content/dependencies-br.md index fdfe2d4af..0a494d05c 100644 --- a/content/dependencies-br.md +++ b/content/dependencies-br.md @@ -9,4 +9,4 @@ Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato d Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, equanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `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. +Aplicações Twelve-factor também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem pagar por ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo a maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa pagar por uma ferramenta de sistema, essa ferramenta deve ser vendorizada na aplicação. From 4b1aa582c32d35cd73d9fa6e5936199ae7ccaa25 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Sat, 31 Jan 2015 21:53:51 -0200 Subject: [PATCH 086/472] [pt-br] Translate Codebase --- content/codebase-pt.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 content/codebase-pt.md diff --git a/content/codebase-pt.md b/content/codebase-pt.md new file mode 100644 index 000000000..785b564ce --- /dev/null +++ b/content/codebase-pt.md @@ -0,0 +1,18 @@ +## I. Base de Código +### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys + +Uma aplicação 12 fatores é sempre rastreada em um sistema de controle de versão, como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Uma cópia da base de dados do rastreamento de revisões é conhecido como *repositório de código*, normalmente abreviado como *repositório* ou *repo*. + +Uma *base de código* é um único repo (em um sistema de controle de versão centralizado como Subversion), ou uma série de repositórios que compartilham um registro raiz. + +![Uma base de código para vários deploys](/images/codebase-deploys.png) + +Existe sempre uma correlação um-para-um entre a base de código e a aplicação: + +* Se existem várias bases de código, isto não é uma app -- é um sistema distribuído. Cada componente do sistema é uma app, e cada uma pode individualmente ser compatível com os 12 fatores. +* Multiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas artavés do [gerenciador de dependências](/dependencies). + +Existe apenas uma base de código por aplicação, mas existirão várias deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. + +A base de código é a mesma através de todos deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não deployados no ambiente de teste, o ambiente de teste ainda tem registros não deployados em prodição. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. + From 57e8f029ef6e984077fcc3a66f37e64a2eef5fd4 Mon Sep 17 00:00:00 2001 From: George Moura Date: Tue, 3 Feb 2015 13:08:26 -0300 Subject: [PATCH 087/472] add adjustes from @fernandes --- content/dependencies-br.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/dependencies-br.md b/content/dependencies-br.md index 0a494d05c..9fd02afd2 100644 --- a/content/dependencies-br.md +++ b/content/dependencies-br.md @@ -7,6 +7,6 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer twelve-factor. -Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, equanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. +Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. -Aplicações Twelve-factor também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem pagar por ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo a maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa pagar por uma ferramenta de sistema, essa ferramenta deve ser vendorizada na aplicação. +Aplicações Twelve-factor também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. From 03c17fd9322d04669a51bb62cfd8b35759d9086a Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 5 Feb 2015 08:58:49 +0000 Subject: [PATCH 088/472] manual merging changes from @orangain --- Gemfile | 3 +- Gemfile.lock | 8 +-- content/{ => en}/admin-processes.md | 6 +-- content/{ => en}/background.md | 0 content/{ => en}/backing-services.md | 2 +- content/{ => en}/build-release-run.md | 8 +-- content/{ => en}/codebase.md | 2 +- content/{ => en}/concurrency.md | 4 +- content/{ => en}/config.md | 4 +- content/{ => en}/dependencies.md | 0 content/{ => en}/dev-prod-parity.md | 4 +- content/{ => en}/disposability.md | 4 +- content/{ => en}/intro.md | 0 content/{ => en}/logs.md | 0 content/{ => en}/port-binding.md | 4 +- content/{ => en}/processes.md | 6 +-- content/{ => en}/toc.md | 24 ++++----- content/{ => en}/who.md | 0 content/ja/admin-processes.md | 14 +++++ content/ja/background.md | 8 +++ content/ja/backing-services.md | 15 ++++++ content/ja/build-release-run.md | 18 +++++++ content/ja/codebase.md | 17 ++++++ content/ja/concurrency.md | 14 +++++ content/ja/config.md | 22 ++++++++ content/ja/dependencies.md | 12 +++++ content/ja/dev-prod-parity.md | 78 +++++++++++++++++++++++++++ content/ja/disposability.md | 12 +++++ content/ja/intro.md | 12 +++++ content/ja/logs.md | 16 ++++++ content/ja/port-binding.md | 14 +++++ content/ja/processes.md | 14 +++++ content/ja/toc.md | 38 +++++++++++++ content/ja/who.md | 4 ++ locales/en.yml | 7 +++ locales/ja.yml | 7 +++ public/css/screen.css | 15 ++++-- views/factor.erb | 1 + views/home.erb | 8 ++- views/layout.erb | 4 +- web.rb | 39 ++++++++++++-- 41 files changed, 417 insertions(+), 51 deletions(-) rename content/{ => en}/admin-processes.md (53%) rename content/{ => en}/background.md (100%) rename content/{ => en}/backing-services.md (83%) rename content/{ => en}/build-release-run.md (82%) rename content/{ => en}/codebase.md (95%) rename content/{ => en}/concurrency.md (86%) rename content/{ => en}/config.md (96%) rename content/{ => en}/dependencies.md (100%) rename content/{ => en}/dev-prod-parity.md (88%) rename content/{ => en}/disposability.md (83%) rename content/{ => en}/intro.md (100%) rename content/{ => en}/logs.md (100%) rename content/{ => en}/port-binding.md (69%) rename content/{ => en}/processes.md (90%) rename content/{ => en}/toc.md (58%) rename content/{ => en}/who.md (100%) create mode 100644 content/ja/admin-processes.md create mode 100644 content/ja/background.md create mode 100644 content/ja/backing-services.md create mode 100644 content/ja/build-release-run.md create mode 100644 content/ja/codebase.md create mode 100644 content/ja/concurrency.md create mode 100644 content/ja/config.md create mode 100644 content/ja/dependencies.md create mode 100644 content/ja/dev-prod-parity.md create mode 100644 content/ja/disposability.md create mode 100644 content/ja/intro.md create mode 100644 content/ja/logs.md create mode 100644 content/ja/port-binding.md create mode 100644 content/ja/processes.md create mode 100644 content/ja/toc.md create mode 100644 content/ja/who.md create mode 100644 locales/en.yml create mode 100644 locales/ja.yml diff --git a/Gemfile b/Gemfile index 2d7d5aa87..3e1c8d5a0 100644 --- a/Gemfile +++ b/Gemfile @@ -2,4 +2,5 @@ source 'http://rubygems.org' gem 'sinatra', '1.2.6' gem 'thin', '1.2.7' -gem 'maruku', '0.6.0' +gem 'maruku', '0.7.1' +gem 'i18n', '0.6.9' diff --git a/Gemfile.lock b/Gemfile.lock index 5a934fa1d..9a19d6b8b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,13 +3,12 @@ GEM specs: daemons (1.1.3) eventmachine (0.12.10) - maruku (0.6.0) - syntax (>= 1.0.0) + i18n (0.6.9) + maruku (0.7.1) rack (1.3.0) sinatra (1.2.6) rack (~> 1.1) tilt (>= 1.2.2, < 2.0) - syntax (1.0.0) thin (1.2.7) daemons (>= 1.0.9) eventmachine (>= 0.12.6) @@ -20,6 +19,7 @@ PLATFORMS ruby DEPENDENCIES - maruku (= 0.6.0) + i18n (= 0.6.9) + maruku (= 0.7.1) sinatra (= 1.2.6) thin (= 1.2.7) diff --git a/content/admin-processes.md b/content/en/admin-processes.md similarity index 53% rename from content/admin-processes.md rename to content/en/admin-processes.md index 92344bfa0..7015e7a1c 100644 --- a/content/admin-processes.md +++ b/content/en/admin-processes.md @@ -1,14 +1,14 @@ ## 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: +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 syncdb` 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. +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. +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. diff --git a/content/background.md b/content/en/background.md similarity index 100% rename from content/background.md rename to content/en/background.md diff --git a/content/backing-services.md b/content/en/backing-services.md similarity index 83% rename from content/backing-services.md rename to content/en/backing-services.md index 1b6f77c1d..60e43fced 100644 --- a/content/backing-services.md +++ b/content/en/backing-services.md @@ -5,7 +5,7 @@ A *backing service* is any service the app consumes over the network as part of Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](/config). A [deploy](/codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. +**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. diff --git a/content/build-release-run.md b/content/en/build-release-run.md similarity index 82% rename from content/build-release-run.md rename to content/en/build-release-run.md index b0ed3ed90..a7215b0a1 100644 --- a/content/build-release-run.md +++ b/content/en/build-release-run.md @@ -1,11 +1,11 @@ ## V. Build, release, run ### Strictly separate build and run stages -A [codebase](/codebase) is transformed into a (non-development) deploy through three stages: +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](/dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](/config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](/processes) against a selected release. +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. ![Code becomes a build, which is combined with config to create a release.](/images/release.png) diff --git a/content/codebase.md b/content/en/codebase.md similarity index 95% rename from content/codebase.md rename to content/en/codebase.md index a194c98b9..94a62f41e 100644 --- a/content/codebase.md +++ b/content/en/codebase.md @@ -10,7 +10,7 @@ A *codebase* is any single repo (in a centralized revision control system like S There is always a one-to-one correlation between the codebase and the app: * If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. -* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](/dependencies). +* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. diff --git a/content/concurrency.md b/content/en/concurrency.md similarity index 86% rename from content/concurrency.md rename to content/en/concurrency.md index 8d84064ec..5ae4706b9 100644 --- a/content/concurrency.md +++ b/content/en/concurrency.md @@ -9,6 +9,6 @@ Any computer program, once run, is represented by one or more processes. Web ap This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](/processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](/logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/config.md b/content/en/config.md similarity index 96% rename from content/config.md rename to content/en/config.md index c32d6a22c..2d2ff384b 100644 --- a/content/config.md +++ b/content/en/config.md @@ -1,9 +1,9 @@ ## III. Config ### Store config in the environment -An app's *config* is everything that is likely to vary between [deploys](/codebase) (staging, production, developer environments, etc). This includes: +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: -* Resource handles to the database, Memcached, and other [backing services](/backing-services) +* Resource handles to the database, Memcached, and other [backing services](./backing-services) * Credentials to external services such as Amazon S3 or Twitter * Per-deploy values such as the canonical hostname for the deploy diff --git a/content/dependencies.md b/content/en/dependencies.md similarity index 100% rename from content/dependencies.md rename to content/en/dependencies.md diff --git a/content/dev-prod-parity.md b/content/en/dev-prod-parity.md similarity index 88% rename from content/dev-prod-parity.md rename to content/en/dev-prod-parity.md index bfea489f7..f6e573342 100644 --- a/content/dev-prod-parity.md +++ b/content/en/dev-prod-parity.md @@ -1,7 +1,7 @@ ## X. Dev/prod parity ### Keep development, staging, and production as similar as possible -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](/codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: * **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. * **The personnel gap**: Developers write code, ops engineers deploy it. @@ -38,7 +38,7 @@ Summarizing the above into a table: -[Backing services](/backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. diff --git a/content/disposability.md b/content/en/disposability.md similarity index 83% rename from content/disposability.md rename to content/en/disposability.md index b66e95e63..085f2d721 100644 --- a/content/disposability.md +++ b/content/en/disposability.md @@ -1,9 +1,9 @@ ## 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. +**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 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. diff --git a/content/intro.md b/content/en/intro.md similarity index 100% rename from content/intro.md rename to content/en/intro.md diff --git a/content/logs.md b/content/en/logs.md similarity index 100% rename from content/logs.md rename to content/en/logs.md diff --git a/content/port-binding.md b/content/en/port-binding.md similarity index 69% rename from content/port-binding.md rename to content/en/port-binding.md index ed1a4b1b2..8b3a0407e 100644 --- a/content/port-binding.md +++ b/content/en/port-binding.md @@ -7,8 +7,8 @@ Web apps are sometimes executed inside a webserver container. For example, PHP In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. -This is typically implemented by using [dependency declaration](/dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). -Note also that the port-binding approach means that one app can become the [backing service](/backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](/config) for the consuming app. +Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/processes.md b/content/en/processes.md similarity index 90% rename from content/processes.md rename to content/en/processes.md index 2477d6080..dd13c37f2 100644 --- a/content/processes.md +++ b/content/en/processes.md @@ -3,13 +3,13 @@ The app is executed in the execution environment as one or more *processes*. -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](/concurrency). +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](/backing-services), typically a database. +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). diff --git a/content/toc.md b/content/en/toc.md similarity index 58% rename from content/toc.md rename to content/en/toc.md index fc2ede4bb..742cb8a5a 100644 --- a/content/toc.md +++ b/content/en/toc.md @@ -1,38 +1,38 @@ The Twelve Factors ================== -## [I. Codebase](/codebase) +## [I. Codebase](./codebase) ### One codebase tracked in revision control, many deploys -## [II. Dependencies](/dependencies) +## [II. Dependencies](./dependencies) ### Explicitly declare and isolate dependencies -## [III. Config](/config) +## [III. Config](./config) ### Store config in the environment -## [IV. Backing Services](/backing-services) +## [IV. Backing Services](./backing-services) ### Treat backing services as attached resources -## [V. Build, release, run](/build-release-run) +## [V. Build, release, run](./build-release-run) ### Strictly separate build and run stages -## [VI. Processes](/processes) +## [VI. Processes](./processes) ### Execute the app as one or more stateless processes -## [VII. Port binding](/port-binding) +## [VII. Port binding](./port-binding) ### Export services via port binding -## [VIII. Concurrency](/concurrency) +## [VIII. Concurrency](./concurrency) ### Scale out via the process model -## [IX. Disposability](/disposability) +## [IX. Disposability](./disposability) ### Maximize robustness with fast startup and graceful shutdown -## [X. Dev/prod parity](/dev-prod-parity) +## [X. Dev/prod parity](./dev-prod-parity) ### Keep development, staging, and production as similar as possible -## [XI. Logs](/logs) +## [XI. Logs](./logs) ### Treat logs as event streams -## [XII. Admin processes](/admin-processes) +## [XII. Admin processes](./admin-processes) ### Run admin/management tasks as one-off processes diff --git a/content/who.md b/content/en/who.md similarity index 100% rename from content/who.md rename to content/en/who.md diff --git a/content/ja/admin-processes.md b/content/ja/admin-processes.md new file mode 100644 index 000000000..c216b9689 --- /dev/null +++ b/content/ja/admin-processes.md @@ -0,0 +1,14 @@ +## XII. 管理プロセス +### 管理タスクを1回限りのプロセスとして実行する + +[プロセスフォーメーション](./concurrency)は、アプリケーションが実行されたときにアプリケーションの通常の役割(Webリクエストの処理など)に使われるプロセス群である。それとは別に、開発者はしばしばアプリケーションのために1回限りの管理・メンテナンス用のタスクを実行したくなる。例えば: + +* データベースのマイグレーションを実行する。(例:Djangoにおける `manage.py syncdb` やRailsにおける `rake db:migrate`) +* 任意のコードを実行したり、生のデータベースに対してアプリケーションのモデルを調査したりするために、コンソール([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)シェルとも言われる)を実行する。多くの言語ではインタプリタを引数なしで実行する(例:`python` や `erl`)ことでREPLを利用できるが、別のコマンドを用意している場合もある(例:Rubyでの `irb` や Railsでの `rails console`)。 +* アプリケーションのリポジトリにコミットされた1回限りのスクリプトを実行する(例:`php scripts/fix_bad_records.php`)。 + +1回限りの管理プロセスは、アプリケーションの通常の[長時間実行されるプロセス](./processes)と全く同じ環境で実行されるべきである。これらのプロセスは、ある[リリース](./build-release-run)に対して実行され、そのリリースに対して実行されるすべてのプロセスと同じ[コード](./code)と[設定](./config)を使う。管理用のコードは、同期の問題を避けるためにアプリケーションコードと一緒にデプロイされるべきである。 + +同じ[依存関係分離](./dependencies)技術をすべてのプロセスタイプに利用するべきである。例えば、もしRubyのWebプロセスがコマンド `bundle exec thin start` を使うのであれば、データベースのマイグレーションには `bundle exec rake db:migrate` を使うべきである。同様に、Virtualenvを使っているPythonプログラムは、仮想環境内の `bin/python` をTornado Webサーバーとすべての `manage.py` 管理プロセスの両方で利用するべきである。 + +Twelve-Factorは細かい設定なしですぐに使えるREPLシェルを提供する言語を強く好む。1回限りのスクリプトを実行するのが簡単になるからである。ローカルデプロイでは、開発者は1回限りの管理プロセスを、アプリケーションをチェックアウトしたディレクトリの中でシェルコマンドで直接起動する。本番デプロイでは、開発者はSSHやデプロイの実行環境が提供する他のリモートコマンド実行方法を使ってそのようなプロセスを実行する。 diff --git a/content/ja/background.md b/content/ja/background.md new file mode 100644 index 000000000..9ac0b07c4 --- /dev/null +++ b/content/ja/background.md @@ -0,0 +1,8 @@ +背景 +========== + +このドキュメントへの寄稿者は、何百ものアプリケーションの開発とデプロイに直接関わり、[Heroku](http://www.heroku.com/)プラットフォーム上での仕事を通して、何百何千ものアプリケーションの開発・運用・スケールに間接的に立ち会った。 + +このドキュメントは、多種多様な野生のSaaSアプリケーションにおける私たちの経験と観察をすべてまとめたものである。これは、アプリケーション開発における理想的なプラクティスを見出すための三角測量である。特に、アプリケーションが時間と共に有機的に成長する力学、アプリケーションのコードベースに取り組む開発者間のコラボレーションの力学、そして[ソフトウェア腐敗によるコストの回避](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)に注目している。 + +私たちの動機は、私たちがモダンなアプリケーション開発で見てきたある種のシステム的な問題への関心を高めること、この問題を議論するための共通の語彙を提供すること、そしてこの問題に対する広い概念的な解決策と専門用語を提供することである。フォーマットはMartin Fowlerの書籍、*[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* および *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* に着想を得ている。 diff --git a/content/ja/backing-services.md b/content/ja/backing-services.md new file mode 100644 index 000000000..ee195336d --- /dev/null +++ b/content/ja/backing-services.md @@ -0,0 +1,15 @@ +## IV. バックエンドサービス +### バックエンドサービスをアタッチされたリソースとして扱う + +*バックエンドサービス* はアプリケーションが通常の動作の中でネットワーク越しに利用するすべてのサービスを言う。例としては、データストア(例:[MySQL](http://dev.mysql.com/) や [CouchDB](http://couchdb.apache.org/))、メッセージキューイングシステム(例:[RabbitMQ](http://www.rabbitmq.com/) や [Beanstalkd](http://kr.github.com/beanstalkd/))、電子メールを送信するためのSMTPサービス(例:[Postfix](http://www.postfix.org/))、キャッシュシステム(例:[Memcached](http://memcached.org/))などがある。 + +従来、データストアなどのバックエンドサービスは、デプロイされたアプリケーションと同じシステム管理者によって管理されていた。このようなローカルで管理されるサービスに加えて、サードパーティによって提供、管理されるサービスを利用することもある。例としては、SMTP サービス(例:[Postmark](http://postmarkapp.com/))、メトリクス収集システム(例:[New Relic](http://newrelic.com/) や [Loggly](http://www.loggly.com/))、ストレージサービス(例:[Amazon S3](http://aws.amazon.com/s3/))、APIアクセス可能な消費者向けサービス(例:[Twitter](http://dev.twitter.com/)や[Google Maps](http://code.google.com/apis/maps/index.html)、[Last.fm](http://www.last.fm/api))などがある。 + +**Twelve-Factor Appのコードは、ローカルサービスとサードパーティサービスを区別しない。** アプリケーションにとっては、どちらもアタッチされたリソースであり、[設定](./config)に格納されたURLやその他のロケーター、認証情報でアクセスする。Twelve-Factor Appの[デプロイ](./codebase)は、アプリケーションのコードに変更を加えることなく、ローカルで管理されるMySQLデータベースをサードパーティに管理されるサービス([Amazon RDS](http://aws.amazon.com/rds/)など)に切り替えることができるべきである。同様に、ローカルのSMTPサーバーも、コードを変更することなくサードパーティのSMTPサービス(Postmarkなど)に切り替えることができるべきである。どちらの場合も、変更が必要なのは設定の中のリソースハンドルのみである。 + +それぞれのバックエンドサービスは *リソース* である。例えば、1つのMySQLデータベースはリソースである。2つのMySQLデータベース(アプリケーション層でのシャーディングに使う)は2つの異なるリソースと見なせる。Twelve-Factor Appはこれらのデータベースを *アタッチされたリソース* として扱う。これは、アタッチされたリソースとアタッチする対象のデプロイが疎結合であることを意味する。 + +4つのバックエンドサービスがアタッチされた本番デプロイ + +リソースは自由にデプロイにアタッチしたり、デプロイからデタッチしたりできる。例えば、ハードウェアの問題によってアプリケーションのデータベースの動作がおかしい場合、アプリケーションの管理者は最新のバックアップから新しいデータベースサーバーを立ち上げる。そして現在の本番データベースをデタッチし、新しいデータベースをアタッチする -- コードを一切変更せずに。 + diff --git a/content/ja/build-release-run.md b/content/ja/build-release-run.md new file mode 100644 index 000000000..19cdd5406 --- /dev/null +++ b/content/ja/build-release-run.md @@ -0,0 +1,18 @@ +## V. ビルド、リリース、実行 +### ビルド、リリース、実行の3つのステージを厳密に分離する + +[コードベース](./codebase)は3つのステージを経て、(開発環境ではない)デプロイへと変換される。 + +* *ビルドステージ* は、コードリポジトリを *ビルド* と呼ばれる実行可能な塊へと変える変換である。デプロイプロセスで指定したコミットのコードで指定されたバージョンを使って、ビルドステージは[依存関係](./dependencies)を取得してローカル環境に配置し、バイナリやアセットファイルをコンパイルする。 +* *リリースステージ* は、ビルドステージで生成されたビルドを受け取り、それをデプロイの現在の[設定](./config)と結合する。出来上がる *リリース* にはビルドと設定の両方が含まれ、実行環境の中ですぐにでも実行できるよう準備が整う。 +* *実行ステージ* (ランタイムとも呼ばれる)は、選択されたリリースに対して、アプリケーションのいくつかの[プロセス](./processes)を起動することで、アプリケーションを実行環境の中で実行する。 + +![コードがビルドになり、ビルドと設定が結合されてリリースが作られる。](/images/release.png) + +**Twelve-Factor Appは、ビルド、リリース、実行の3つのステージを厳密に分離する。** 例えば、実行ステージにあるコードを変更してもその変更をビルドステージに伝える方法がないため、コードを実行中に変更することはあり得ない。 + +デプロイツールは通常、リリース管理ツールを提供する。中でも注目すべきは、以前のリリースにロールバックする機能である。例えばデプロイツールの[Capistrano](https://github.com/capistrano/capistrano/wiki)は、リリースを`releases`という名前のサブディレクトリに格納し、現在のリリースは現在のリリースのディレクトリへのシンボリックリンクとなる。Capistranoの`rollback`コマンドを使うと、簡単かつ即座に以前のリリースにロールバックできる。 + +すべてのリリースは常に一意のリリースIDを持つべきである。リリースIDの例としては、リリースのタイムスタンプ(例:`2011-04-06-20:32:17`)や連番(例:`v100`)がある。リリースは追記専用の台帳であり、一度作られたリリースは変更することができない。変更する場合は新しいリリースを作らなければならない。 + +ビルドステージは、新しいコードがデプロイされるときに必ずアプリケーションの開発者によって開始される。一方実行ステージは、サーバーの再起動時や、クラッシュしたプロセスがプロセスマネージャーによって再起動された時に自動で開始される。このため、実行ステージはできるだけ可変部分を持たないようにするべきである。なぜなら、アプリケーションの実行を妨げるような問題が起きると、開発者が待機していない真夜中にアプリケーションが壊れる結果になるためである。ビルドステージはもっと複雑でも構わない。なぜなら、ビルドステージのエラーは常にデプロイを実行している開発者の目の前で発生するためである。 diff --git a/content/ja/codebase.md b/content/ja/codebase.md new file mode 100644 index 000000000..5bc86cb93 --- /dev/null +++ b/content/ja/codebase.md @@ -0,0 +1,17 @@ +## I. コードベース +### バージョン管理されている1つのコードベースと複数のデプロイ + +Twelve-Factor Appは[Git](http://git-scm.com/)や[Mercurial](http://mercurial.selenic.com/)、[Subversion](http://subversion.apache.org/)などのバージョン管理システムで常に変更を追跡している。リビジョン追跡データベースのコピーは *コードリポジトリ* と言われ、単に *リポジトリ* とも言われる。 + +*コードベース* は、単一のリポジトリ(Subversionのような集中バージョン管理システムの場合)またはルートコミットを共有する複数のリポジトリ(Gitのような分散バージョン管理システムの場合)である。 + +![1つのコードベースは複数のデプロイにマッピングされる](/images/codebase-deploys.png) + +コードベースとアプリケーションの間には、常に1対1の関係がある。 + +* もし複数のコードベースがある場合、それはアプリケーションではない -- それは分散システムである。分散システムのそれぞれのコンポーネントがアプリケーションであり、個別にTwelve-Factorに適合することができる。 +* 同じコードを共有する複数のアプリケーションは、Twelve-Factorに違反している。その場合の解決策は、共通のコードをライブラリに分解し、そのライブラリを[依存関係管理ツール](./dependencies)で組み込むようにすることである。 + +アプリケーションごとにただ1つのコードベースが存在するが、アプリケーションのデプロイは複数存在する。 *デプロイ* はアプリケーションの実行中のインスタンスである。これは通常1つの本番サイトと、1つ以上のステージングサイトである。さらにすべての開発者はローカル開発環境で動作するアプリケーションのコピーを持っており、それらもデプロイと見なせる。 + +デプロイごとに異なるバージョンがアクティブであるかもしれないが、コードベースはすべてのデプロイを通して同一である。例えば、開発者はステージング環境にまだデプロイされていないコミットを抱えているし、ステージング環境には本番環境にデプロイされていないコミットが含まれている。しかし、これらのデプロイはすべて同一のコードベースを共有しているため、同一のアプリケーションの異なるデプロイであると認識できる。 diff --git a/content/ja/concurrency.md b/content/ja/concurrency.md new file mode 100644 index 000000000..1795c25e6 --- /dev/null +++ b/content/ja/concurrency.md @@ -0,0 +1,14 @@ +## VIII. 並行性 +### プロセスモデルによってスケールアウトする + +すべてのコンピュータープログラムは、一度実行されると、1つ以上のプロセスとして表される。Webアプリケーションでは様々なプロセス実行形態がとられてきた。例えば、PHPのプロセスはApacheの子プロセスとして実行され、リクエスト量に応じて起動される。Javaプロセスは反対の方法をとる。JVMが1つの巨大な親プロセスを提供し、起動時にシステムリソース(CPUやメモリ)の大きなブロックを確保し、スレッドを使って内部的に並行性を管理する。どちらの場合でも、実行されるプロセスはアプリケーションの開発者にはほとんど見えない。 + +![スケールは実行されるプロセスの数として表現され、ワークロードの種類はプロセスタイプとして表現される。](/images/process-types.png) + +**Twelve-Factor Appではプロセスは第一級市民である。** Twelve-Factor Appにおけるプロセスの考え方は、[サービスのデーモンを実行するためのUnixプロセスモデル](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)から大きなヒントを得ている。このモデルを使い、個々のワークロードの種類を *プロセスタイプ* に割り当てることで、開発者はアプリケーションが多様なワークロードを扱えるように設計することができる。例えば、HTTPリクエストはWebプロセスによって処理し、時間のかかるバックグラウンドタスクはワーカープロセスによって処理することができる。 + +このモデルは、ランタイムVM内のスレッドや、[EventMachine](http://rubyeventmachine.com/)、[Twisted](http://twistedmatrix.com/trac/)、[Node.js](http://nodejs.org/)などの非同期イベントモデルによって、個々のプロセスがプロセス内部で多重化することを禁止するわけではない。しかし個々のVMはそれほど大きくなる(垂直にスケールする)ことができないため、アプリケーションは複数の物理マシンで動作する複数のプロセスへと拡大できなければならない。 + +このプロセスモデルが真価を発揮するのは、スケールアウトが必要になったときである。[シェアードナッシングで水平分割可能なTwelve-Factor Appプロセスの性質](./processes)は、並行性を高める操作が単純かつ確実なものであることを意味する。プロセスタイプとそれぞれのタイプのプロセス数の配列は、 *プロセスフォーメーション* と言われる。 + +Twelve-Factor Appのプロセスは[決してデーモン化するべきではないし](http://dustin.github.com/2010/02/28/running-processes.html)、PIDファイルを書き出すべきではない。その代わりに、OSのプロセスマネージャー(例:[Upstart](http://upstart.ubuntu.com/)、クラウドプラットフォームの分散プロセスマネージャー、あるいは開発環境における[Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)のようなツール)を頼ることで、[出力ストリーム](./logs)を管理し、プロセスのクラッシュに対応し、ユーザーによる再起動やシャットダウンを処理すべきである。 diff --git a/content/ja/config.md b/content/ja/config.md new file mode 100644 index 000000000..510b3f60c --- /dev/null +++ b/content/ja/config.md @@ -0,0 +1,22 @@ +## III. 設定 +### 設定を環境変数に格納する + +アプリケーションの *設定* は、[デプロイ](./codebase)(ステージング、本番、開発環境など)の間で異なり得る唯一のものである。設定には以下のものが含まれる。 + +* データベース、Memcached、他の[バックエンドサービス](./backing-services)などのリソースへのハンドル +* Amazon S3やTwitterなどの外部サービスの認証情報 +* デプロイされたホストの正規化されたホスト名など、デプロイごとの値 + +アプリケーションは時に設定を定数としてコード内に格納する。これはTwelve-Factorに違反している。Twelve-Factorは **設定をコードから厳密に分離すること** を要求する。設定はデプロイごとに大きく異なるが、コードはそうではない。 + +アプリケーションがすべての設定をコードの外部に正しく分離できているかどうかの簡単なテストは、認証情報を漏洩させることなく、コードベースを今すぐにでもオープンソースにすることができるかどうかである。 + +なお、この“設定”の定義には、アプリケーション内部の設定は **含まない** ことに注意する。内部の設定とは、Railsにおける`config/routes.rb`や、[Spring](http://www.springsource.org/)において[コードモジュールがどう接続されるか](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html)などの設定を指す。この種の設定はデプロイの間で変わらないため、コードの内部で行うべきである。 + +設定に対するもう1つのアプローチは、バージョン管理システムにチェックインされない設定ファイルを使う方法である。例として、Railsにおける`config/database.yml`がある。この方法は、リポジトリにチェックインされる定数を使うことに比べると非常に大きな進歩であるが、まだ弱点がある。設定ファイルが誤ってリポジトリにチェックインされやすいことと、設定ファイルが異なる場所に異なるフォーマットで散乱し、すべての設定を一つの場所で見たり管理したりすることが難しくなりがちであることである。その上、これらのフォーマットは言語やフレームワークに固有のものになりがちである。 + +**Twelve-Factor Appは設定を *環境変数* に格納する。** 環境変数は、コードを変更することなくデプロイごとに簡単に変更できる。設定ファイルとは異なり、誤ってリポジトリにチェックインされる可能性はほとんどない。また、独自形式の設定ファイルやJava System Propertiesなど他の設定の仕組みとは異なり、環境変数は言語やOSに依存しない標準である。 + +設定管理のもう1つの側面はグルーピングである。アプリケーションは設定を名前付きのグループ(しばしば“環境”と呼ばれる)にまとめることがある。グループは、Railsにおける`development`、`test`、`production`環境のように、デプロイの名前を取って名付けられる。この方法はうまくスケールしない。アプリケーションのデプロイが増えるにつれて、新しい環境名(`staging`や`qa`)が必要になる。さらにプロジェクトが拡大すると、開発者は`joes-staging`のような自分用の環境を追加する。結果として設定が組み合わせ的に爆発し、アプリケーションのデプロイの管理が非常に不安定になる。 + +Twelve-Factor Appの場合、環境変数は粒度の細かい管理であり、それぞれの環境変数は互いに直交している。環境変数は“環境”としてまとめられることはないが、代わりにデプロイごとに独立して管理される。これは、アプリケーションのライフサイクルに渡って、アプリケーションが多くのデプロイへと自然に拡大していくにつれて、スムーズにスケールアップするモデルである。 diff --git a/content/ja/dependencies.md b/content/ja/dependencies.md new file mode 100644 index 000000000..2bc89dc1b --- /dev/null +++ b/content/ja/dependencies.md @@ -0,0 +1,12 @@ +## II. 依存関係 +### 依存関係を明示的に宣言し分離する + +ほとんどのプログラミング言語は、サポートライブラリを配布するためのパッケージ管理システムを提供している。例えば、Perlにおける[CPAN](http://www.cpan.org/)やRubyにおける[Rubygems](http://rubygems.org/)などである。パッケージ管理システムでインストールされるライブラリは、システム全体(“site packages”と言われる)にインストールされる場合と、アプリケーションを含むディレクトリのスコープ(“vendoring”または“bundling”と言われる)にインストールされる場合がある。 + +**Twelve-Factor Appは、システム全体にインストールされるパッケージが暗黙的に存在することに決して依存しない。** すべての依存関係を *依存関係宣言* マニフェストで完全かつ厳密に宣言する。さらに、実行時には *依存関係分離* ツールを使って、取り囲んでいるシステムから暗黙の依存関係が“漏れ出ない”ことを保証する。完全かつ明示的な依存関係の指定は、本番環境と開発環境の両方に対して同様に適用される。 + +例えば、Rubyで使われる[Gem Bundler](http://gembundler.com/) は、依存関係宣言のためのマニフェストのフォーマットである`Gemfile`と依存関係分離のための`bundle exec`を提供している。Pythonではこれらのステップで2つの別々のツールが使われる -- [Pip](http://www.pip-installer.org/en/latest/)が宣言のために使われ、[Virtualenv](http://www.virtualenv.org/en/latest/)が分離のために使われる。C言語でも[Autoconf](http://www.gnu.org/s/autoconf/)で依存関係を宣言し、静的リンクで依存関係を分離することができる。ツールが何であれ、依存関係の宣言と分離は常に一緒に使わなければならない -- どちらか片方だけではTwelve-Factorを満足するのに不十分である。 + +明示的に依存関係を宣言する利点の1つは、アプリケーションに新しい開発者が加わった際のセットアップを単純化できることである。新しい開発者は、言語のランタイムと依存関係管理ツールさえインストールされていれば、アプリケーションのコードベースを自分の開発マシンにチェックアウトすることができる。開発者は決められた *ビルドコマンド* で、アプリケーションのコードを実行するために必要なすべてのものをセットアップできる。例えば、Ruby/Bundlerのビルドコマンドは`bundle install`であり、Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)では`lein deps`である。 + +また、Twelve-Factor Appは、いかなるシステムツールの暗黙的な存在にも依存しない。例として、アプリケーションからImageMagickや`curl`を使う場合がある。これらのツールはほとんどのシステムに存在するだろうが、アプリケーションが将来に渡って実行され得るすべてのシステムに存在するかどうか、あるいは将来のシステムでこのアプリケーションと互換性のあるバージョンが見つかるかどうかについては何の保証もない。アプリケーションがシステムツールを必要とするならば、そのツールをアプリケーションに組み込むべきである。 diff --git a/content/ja/dev-prod-parity.md b/content/ja/dev-prod-parity.md new file mode 100644 index 000000000..eda082101 --- /dev/null +++ b/content/ja/dev-prod-parity.md @@ -0,0 +1,78 @@ +## X. 開発/本番一致 +### 開発、ステージング、本番環境をできるだけ一致させた状態を保つ + +歴史的に、開発環境(開発者が直接変更するアプリケーションのローカル[デプロイ](./codebase))と本番環境(エンドユーザーからアクセスされるアプリケーションの実行中デプロイ)の間には大きなギャップがあった。これらのギャップは3つの領域で現れる。 + +* **時間のギャップ**: 開発者が編集したコードが本番に反映されるまで数日、数週間、時には数ヶ月かかることがある。 +* **人材のギャップ**: 開発者が書いたコードを、インフラエンジニアがデプロイする。 +* **ツールのギャップ**: 本番デプロイではApache、MySQL、Linuxを使うのに、開発者がNginx、SQLite、OS Xのようなスタックを使うことがある。 + +**Twelve-Factor Appでは、[継続的デプロイ](http://www.avc.com/a_vc/2011/02/continuous-deployment.html)しやすいよう開発環境と本番環境のギャップを小さく保つ。** 上で述べた3つのギャップを見る。 + +* 時間のギャップを小さくする: 開発者が書いたコードは数時間後、さらには数分後にはデプロイされる。 +* 人材のギャップを小さくする: コードを書いた開発者はそのコードのデプロイに深く関わり、そのコードの本番環境での挙動をモニタリングする。 +* ツールのギャップを小さくする: 開発環境と本番環境をできるだけ一致させた状態を保つ。 + +上で述べたことを表にまとめる。 + +
+ + + + + + + + + + + + + + + + + + + + +
伝統的なアプリケーションTwelve-Factor App
デプロイの間隔数週間数時間
コードを書く人とデプロイする人異なる人同じ人
開発環境と本番環境異なるできるだけ一致
+ + +[バックエンドサービス](./backing-services)(アプリケーションのデータベース、キューイングシステム、キャッシュなど)は、開発/本番一致が重要になる領域の一つである。多くの言語は、異なる種類のサービスへの *アダプター* を含め、バックエンド・サービスへのアクセスを単純化するライブラリを提供している。以下の表にいくつかの例を示す。 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
種類言語ライブラリアダプター
データベースRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
キューPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
キャッシュRuby/RailsActiveSupport::Cacheメモリ, ファイルシステム, Memcached
+ +本番環境ではより本格的で堅牢なバックエンドサービスが使われるにもかかわらず、開発者は自身のローカル開発環境で軽量なバックエンドサービスを使いたくなることがある。例えば、開発環境ではSQLiteを使い、本番ではPostgreSQLを使ったり、開発環境ではローカルプロセスのメモリをキャッシュに使い、本番ではMemcachedを使ったりするなどである。 + +たとえ理論的にはアダプターがバックエンドサービスの違いをすべて抽象化してくれるとしても、 **Twelve-Factorの開発者は、開発と本番の間で異なるバックエンドサービスを使いたくなる衝動に抵抗する。** バックエンドサービスの違いは、わずかな非互換性が顕在化し、開発環境やステージング環境では正常に動作してテストも通過するコードが本番環境でエラーを起こす事態を招くことを意味する。この種のエラーは継続的デプロイを妨げる摩擦を生む。この摩擦とそれに伴って継続的デプロイが妨げられることのコストは、アプリケーションのライフサイクルに渡ってトータルで考えると非常に高くつく。 + +軽量なローカルサービスは、以前ほど魅力的なものではなくなっている。Memcached、PostgreSQLやRabbitMQなどのモダンなバックエンドサービスは、[Homebrew](http://mxcl.github.com/homebrew/) や [apt-get](https://help.ubuntu.com/community/AptGet/Howto) などのモダンなパッケージングシステムのおかげで、簡単にインストールして実行できる。あるいは [Chef](http://www.opscode.com/chef/) や [Puppet](http://docs.puppetlabs.com/) などの宣言的なプロビジョニングツールと、[Vagrant](http://vagrantup.com/) などの軽量な仮想環境を組み合わせることで、開発者は本番環境に限りなく近いローカル環境を作ることができる。開発/本番一致と継続的デプロイの利益に比べると、これらのシステムをインストールして利用するコストは低い。 + +異なるバックエンドサービスへのアダプターは依然有用である。これらのアダプターは、新しいバックエンドサービスに移植するときの苦痛を比較的和らげてくれるためである。しかし、アプリケーションのすべてのデプロイ(開発、ステージング、本番環境)は同じ種類かつ同じバージョンのバックエンドサービスを利用するべきである。 diff --git a/content/ja/disposability.md b/content/ja/disposability.md new file mode 100644 index 000000000..d07e9f633 --- /dev/null +++ b/content/ja/disposability.md @@ -0,0 +1,12 @@ +## IX. 廃棄容易性 +### 高速な起動とグレースフルシャットダウンで堅牢性を最大化する + +**Twelve-Factor Appの [プロセス](./processes) は *廃棄容易* である、すなわち即座に起動・終了することができる。** この性質が、素早く柔軟なスケールと、[コード](./codebase) や [設定](./config) に対する変更の素早いデプロイを容易にし、本番デプロイの堅牢性を高める。 + +プロセスは、 **起動時間を最小化する** よう努力するべきである。理想的には、1つのプロセスは、起動コマンドが実行されてから数秒間でリクエストやジョブを受け取れるようになるべきである。起動時間が短いと、[リリース](./build-release-run)作業やスケールアップのアジリティが高くなる。さら、プロセスマネージャーが必要に応じてプロセスを新しい物理マシンに簡単に移動できるようになるため、堅牢性も高くなる。 + +プロセスは、プロセスマネージャーから **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)シグナルを受け取ったときに、グレースフルにシャットダウンする。** Webプロセスの場合、グレースフルシャットダウンは、サービスポートのリッスンを中止し(従って新しいリクエストを拒み)、処理中のリクエストが終了するまで待ち、シャットダウンすることで実現される。このモデルでは暗黙的にHTTPリクエストが短い(せいぜい数秒)ことを仮定している。ロングポーリングの場合、クライアントはコネクションが失われたときに途切れなく再接続を試みるべきである。 + +ワーカープロセスの場合、グレースフルシャットダウンは、処理中のジョブをワーカーキューに戻すことで実現される。例えば、[RabbitMQ](http://www.rabbitmq.com/)ではワーカーは[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)を送ることができる。[Beanstalkd](http://kr.github.com/beanstalkd/)では、ワーカーの接続が失われるとジョブは自動的にキューに戻る。[Delayed Job](https://github.com/collectiveidea/delayed_job#readme)などのロックをベースにしたシステムでは、ジョブレコードのロックを確実に解放する必要がある。このモデルでは、暗黙的にすべてのジョブが[再入可能](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)であることを仮定している。再入可能性は一般的に、結果をトランザクションで包んだり、処理を[べき等](http://en.wikipedia.org/wiki/Idempotence)にすることで実現される。 + +また、下層のハードウェアの障害に関して言えば、プロセスは **突然の死に対して堅牢** であるべきである。このような事態が起こることは、`SIGTERM`によるグレースフルシャットダウンに比べればずっと少ないが、それでも起こりうる。この対策として推奨される方法は、Beanstalkdなどの堅牢なキューイングバックエンドを使い、クライアントの接続が切断されたり、タイムアウトしたときにジョブをキューに戻せるようにすることである。どちらにしても、Twelve-Factor Appは予期しないグレースフルでない停止をうまく処理できるよう設計される。[「クラッシュオンリー」設計](http://lwn.net/Articles/191059/)はこのコンセプトをその[論理的帰結](http://docs.couchdb.org/en/latest/intro/overview.html)に導く。 diff --git a/content/ja/intro.md b/content/ja/intro.md new file mode 100644 index 000000000..dd62a6656 --- /dev/null +++ b/content/ja/intro.md @@ -0,0 +1,12 @@ +はじめに +============ + +現代では、ソフトウェアは一般にサービスとして提供され、*Webアプリケーション* や *Software as a Service* と呼ばれる。Twelve-Factor Appは、次のようなSoftware as a Serviceを作り上げるための方法論である。 + +* セットアップ自動化のために **宣言的な** フォーマットを使い、プロジェクトに新しく加わった開発者が要する時間とコストを最小化する。 +* 下層のOSへの **依存関係を明確化** し、実行環境間での **移植性を最大化** する。 +* モダンな **クラウドプラットフォーム** 上への **デプロイ** に適しており、サーバー管理やシステム管理を不要なものにする。 +* 開発環境と本番環境の **差異を最小限** にし、アジリティを最大化する **継続的デプロイ** を可能にする。 +* ツール、アーキテクチャ、開発プラクティスを大幅に変更することなく **スケールアップ** できる。 + +Twelve-Factorの方法論は、どのようなプログラミング言語で書かれたアプリケーションにでも適用できる。また、どのようなバックエンドサービス(データベース、メッセージキュー、メモリキャッシュなど)の組み合わせを使っていても適用できる。 diff --git a/content/ja/logs.md b/content/ja/logs.md new file mode 100644 index 000000000..0998a4d41 --- /dev/null +++ b/content/ja/logs.md @@ -0,0 +1,16 @@ +## XI. ログ +### ログをイベントストリームとして扱う + +*ログ* は実行中のアプリケーションの挙動を可視化する。サーバーベースの環境では、ログは一般的にディスク上のファイル(“ログファイル”)に書き込まれる。しかしこれは出力フォーマットの一つに過ぎない。 + +ログは、すべての実行中のプロセスとバックエンドサービスの出力ストリームから収集されたイベントが、集約されて時刻順に並べられた[ストリーム](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/)である。生の状態のログは、通常1行が1つのイベントを表すテキストフォーマットである(例外のバックトレースは複数行に渡る場合もあるが)。ログには固定の始まりと終わりはなく、アプリケーションが稼動している限り流れ続ける。 + +**Twelve-Factor Appはアプリケーションの出力ストリームの送り先やストレージについて一切関知しない。** アプリケーションはログファイルに書き込んだり管理しようとするべきではない。代わりに、それぞれの実行中のプロセスはイベントストリームを`stdout`(標準出力)にバッファリングせずに書きだす。ローカルでの開発中、開発者はこのストリームをターミナルのフォアグラウンドで見ることで、アプリケーションの挙動を観察する。 + +ステージングや本番のデプロイでは、それぞれのプロセスのストリームは実行環境に捕らえられ、アプリケーションからの他のすべてのストリームと一緒に並べられ、表示や長期アーカイブのために1つもしくは複数の最終目的地に送られる。これらの保存のための目的地は、アプリケーションからは見ることも設定することもできず、代わりに実行環境によって完全に管理される。[Logplex](https://github.com/heroku/logplex) や [Fluent](https://github.com/fluent/fluentd) などのオープンソースのログルーターがこの目的に利用できる。 + +アプリケーションのイベントストリームは、ファイルに送られたり、ターミナルでtailを使ってリアルタイムに見られたりする。最も重要な用途として、ストリームは、[Splunk](http://www.splunk.com/)などのログインデックス・解析システムや、[Hadoop/Hive](http://hive.apache.org/)などの汎用データウェアハウスシステムに送られることもある。これらのシステムは、長期に渡ってアプリケーションの挙動を確認するための大きな力と柔軟性をもたらし、次のようなことができるようになる。 + +* 過去の特定のイベントを見つける。 +* 大きなスケールの傾向をグラフ化する。(1分あたりのリクエスト数など) +* ユーザー定義のヒューリスティクスに基づいて素早くアラートを出す。(1分あたりのエラー数がある閾値を超えた場合にアラートを出すなど) diff --git a/content/ja/port-binding.md b/content/ja/port-binding.md new file mode 100644 index 000000000..7e2116376 --- /dev/null +++ b/content/ja/port-binding.md @@ -0,0 +1,14 @@ +## 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://jetty.codehaus.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)にリソースハンドルとして格納すればよい。 diff --git a/content/ja/processes.md b/content/ja/processes.md new file mode 100644 index 000000000..6592c8a8d --- /dev/null +++ b/content/ja/processes.md @@ -0,0 +1,14 @@ +## VI. プロセス +### アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する + +アプリケーションは、実行環境の中で1つもしくは複数の *プロセス* として実行される。 + +最も単純な場合では、コードは単体のスクリプトであり、実行環境は言語ランタイムがインストールされた開発者のローカルノートPCであり、プロセスはコマンドラインから実行される(例:`python my_script.py`)。対極にあるのは、[複数の実行プロセスとしてインスタンス化される多くのプロセスタイプ](./concurrency)を使う洗練されたアプリケーションの本番デプロイである。 + +**Twelve-Factorのプロセスはステートレスかつ[シェアードナッシング](http://en.wikipedia.org/wiki/Shared_nothing_architecture)** である。永続化する必要のあるすべてのデータは、ステートフルな[バックエンドサービス](./backing-services)(典型的にはデータベース)に格納しなければならない。 + +プロセスのメモリ空間やファイルシステムは、短い単一のトランザクション内でのキャッシュとして利用してもよい。例えば、大きなファイルをダウンロードし、そのファイルを処理し、結果をデータベースに格納するという一連の処理において、ファイルシステムをキャッシュとして利用できる。Twelve-Factor Appは、メモリやディスクにキャッシュされたものが将来のリクエストやジョブにおいて利用できることを決して仮定しない -- それぞれのプロセスタイプのプロセスが多く実行されている場合、将来のリクエストやジョブが別のプロセスで処理される可能性が高い。1つのプロセスしか実行されていない場合であっても、プロセスが再起動すると、すべての局所的な状態(メモリやファイルシステムなど)が消えてしまうことがある。プロセスの再起動の要因としては、コードのデプロイ、設定の変更、プロセスを別の物理位置に再配置する実行環境などがある。 + +アセットパッケージャー(例:[Jammit](http://documentcloud.github.com/jammit/) や [django-assetpackager](http://code.google.com/p/django-assetpackager/))は、コンパイルされたアセットをキャッシュするためにファイルシステムを利用する。Twelve-Factor Appは、このコンパイル処理を実行時に行うよりも、[Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html)のように[ビルドステージ](./build-release-run)で行うほうが、望ましいと考えている。 + +Webシステムの中には、[“スティッキーセッション”](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)に頼るものがある -- これはユーザーのセッションデータをアプリケーションプロセスのメモリにキャッシュし、同じ訪問者からの将来のリクエストが同じプロセスに送られることを期待するものである。スティッキーセッションはTwelve-Factorに違反しており、決して使ったり頼ったりしてはならない。セッション状態のデータは、有効期限を持つデータストア(例:[Memcached](http://memcached.org/) や [Redis](http://redis.io/))に格納すべきである。 diff --git a/content/ja/toc.md b/content/ja/toc.md new file mode 100644 index 000000000..2de323df1 --- /dev/null +++ b/content/ja/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. コードベース](./codebase) +### バージョン管理されている1つのコードベースと複数のデプロイ + +## [II. 依存関係](./dependencies) +### 依存関係を明示的に宣言し分離する + +## [III. 設定](./config) +### 設定を環境変数に格納する + +## [IV. バックエンドサービス](./backing-services) +### バックエンドサービスをアタッチされたリソースとして扱う + +## [V. ビルド、リリース、実行](./build-release-run) +### ビルド、リリース、実行の3つのステージを厳密に分離する + +## [VI. プロセス](./processes) +### アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する + +## [VII. ポートバインディング](./port-binding) +### ポートバインディングを通してサービスを公開する + +## [VIII. 並行性](./concurrency) +### プロセスモデルによってスケールアウトする + +## [IX. 廃棄容易性](./disposability) +### 高速な起動とグレースフルシャットダウンで堅牢性を最大化する + +## [X. 開発/本番一致](./dev-prod-parity) +### 開発、ステージング、本番環境をできるだけ一致させた状態を保つ + +## [XI. ログ](./logs) +### ログをイベントストリームとして扱う + +## [XII. 管理プロセス](./admin-processes) +### 管理タスクを1回限りのプロセスとして実行する diff --git a/content/ja/who.md b/content/ja/who.md new file mode 100644 index 000000000..7633f0e65 --- /dev/null +++ b/content/ja/who.md @@ -0,0 +1,4 @@ +このドキュメントの対象者 +============================== + +サービスとして動くアプリケーションを開発しているすべての開発者。およびそのようなアプリケーションをデプロイまたは管理しているインフラエンジニア。 diff --git a/locales/en.yml b/locales/en.yml new file mode 100644 index 000000000..7188c643a --- /dev/null +++ b/locales/en.yml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: English (en) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "" diff --git a/locales/ja.yml b/locales/ja.yml new file mode 100644 index 000000000..bd5305ca0 --- /dev/null +++ b/locales/ja.yml @@ -0,0 +1,7 @@ +ja: + # Name of language listed in locales menu + language: 日本語 (ja) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: (日本語訳) diff --git a/public/css/screen.css b/public/css/screen.css index c058f8589..a86d871c0 100644 --- a/public/css/screen.css +++ b/public/css/screen.css @@ -108,6 +108,15 @@ 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; } @@ -145,10 +154,6 @@ footer { min-height: 56pt; } -footer span { - display: block; -} - footer a { color: #444; } @@ -161,4 +166,4 @@ article img { article img.full { float: none; margin-left: 0; -} \ No newline at end of file +} diff --git a/views/factor.erb b/views/factor.erb index 40eee4d0e..404a0bd01 100644 --- a/views/factor.erb +++ b/views/factor.erb @@ -6,6 +6,7 @@
diff --git a/views/home.erb b/views/home.erb index 8312b582f..2d76c6d89 100644 --- a/views/home.erb +++ b/views/home.erb @@ -8,4 +8,10 @@
<%= render_markdown('toc') %>
- + diff --git a/views/layout.erb b/views/layout.erb index 582bb5d95..30d5fe491 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -3,7 +3,7 @@ - The Twelve-Factor App + The Twelve-Factor App<%= I18n.t(:translation) %> @@ -30,7 +30,7 @@ <% end %>
-

The Twelve-Factor App

+

The Twelve-Factor App

<%= yield %> diff --git a/web.rb b/web.rb index a53c0cc35..242c0a7d6 100644 --- a/web.rb +++ b/web.rb @@ -1,5 +1,25 @@ require 'sinatra' require 'maruku' +require 'i18n' + +configure do + I18n.enforce_available_locales = true + I18n.load_path = Dir[File.join(settings.root, 'locales', '*.yml')] + 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 @@ -15,22 +35,33 @@ helpers do def render_markdown(file) - markdown = File.read("content/#{file}.md") + markdown = File.read("content/#{I18n.locale}/#{file}.md") Maruku.new(markdown).to_html rescue Errno::ENOENT - puts "No content for #{file}, skipping" + puts "No content for #{I18n.locale}/#{file}, skipping" end def render_prev(factor) idx = TOC.index(factor) return if idx == 0 - "« Previous" + "« Previous" end def render_next(factor) idx = TOC.index(factor) return if idx == TOC.size-1 - "Next »" + "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 From 0c10f4f5eec0561455ddd1519767988cd0b9868b Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 5 Feb 2015 09:09:18 +0000 Subject: [PATCH 089/472] fixes to footer --- views/home.erb | 8 -------- views/layout.erb | 11 ++++++----- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/views/home.erb b/views/home.erb index 2d76c6d89..d05fcff34 100644 --- a/views/home.erb +++ b/views/home.erb @@ -7,11 +7,3 @@
<%= render_markdown('toc') %>
- - diff --git a/views/layout.erb b/views/layout.erb index 30d5fe491..b32ce02f6 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -36,11 +36,12 @@ <%= yield %> From f9a7a4ae2de9579ce61c5b50acad4b4560ef50ec Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 5 Feb 2015 09:22:36 +0000 Subject: [PATCH 090/472] small fix to English applied to Japanese --- content/ja/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/admin-processes.md b/content/ja/admin-processes.md index c216b9689..b31ed5ca6 100644 --- a/content/ja/admin-processes.md +++ b/content/ja/admin-processes.md @@ -4,7 +4,7 @@ [プロセスフォーメーション](./concurrency)は、アプリケーションが実行されたときにアプリケーションの通常の役割(Webリクエストの処理など)に使われるプロセス群である。それとは別に、開発者はしばしばアプリケーションのために1回限りの管理・メンテナンス用のタスクを実行したくなる。例えば: * データベースのマイグレーションを実行する。(例:Djangoにおける `manage.py syncdb` やRailsにおける `rake db:migrate`) -* 任意のコードを実行したり、生のデータベースに対してアプリケーションのモデルを調査したりするために、コンソール([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)シェルとも言われる)を実行する。多くの言語ではインタプリタを引数なしで実行する(例:`python` や `erl`)ことでREPLを利用できるが、別のコマンドを用意している場合もある(例:Rubyでの `irb` や Railsでの `rails console`)。 +* 任意のコードを実行したり、生のデータベースに対してアプリケーションのモデルを調査したりするために、コンソール([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)シェルとも言われる)を実行する。多くの言語ではインタプリタを引数なしで実行する(例:`python` や `perl`)ことでREPLを利用できるが、別のコマンドを用意している場合もある(例:Rubyでの `irb` や Railsでの `rails console`)。 * アプリケーションのリポジトリにコミットされた1回限りのスクリプトを実行する(例:`php scripts/fix_bad_records.php`)。 1回限りの管理プロセスは、アプリケーションの通常の[長時間実行されるプロセス](./processes)と全く同じ環境で実行されるべきである。これらのプロセスは、ある[リリース](./build-release-run)に対して実行され、そのリリースに対して実行されるすべてのプロセスと同じ[コード](./code)と[設定](./config)を使う。管理用のコードは、同期の問題を避けるためにアプリケーションコードと一緒にデプロイされるべきである。 From 34ed60c49d6a682b829c9a4f94e2b77907e3aaf5 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 5 Feb 2015 09:42:54 +0000 Subject: [PATCH 091/472] Upgrading to Cedar-14 From 5f53453f85b93a17637b7f596c9fbb421cb8935c Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 5 Feb 2015 17:45:10 +0800 Subject: [PATCH 092/472] Move all into the folder --- content/{ => zh_cn}/admin-processes.md | 0 content/{ => zh_cn}/background.md | 0 content/{ => zh_cn}/backing-services.md | 0 content/{ => zh_cn}/build-release-run.md | 0 content/{ => zh_cn}/codebase.md | 0 content/{ => zh_cn}/concurrency.md | 0 content/{ => zh_cn}/config.md | 0 content/{ => zh_cn}/dependencies.md | 0 content/{ => zh_cn}/dev-prod-parity.md | 0 content/{ => zh_cn}/disposability.md | 0 content/{ => zh_cn}/intro.md | 0 content/{ => zh_cn}/logs.md | 0 content/{ => zh_cn}/port-binding.md | 0 content/{ => zh_cn}/processes.md | 0 content/{ => zh_cn}/toc.md | 0 content/{ => zh_cn}/who.md | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename content/{ => zh_cn}/admin-processes.md (100%) rename content/{ => zh_cn}/background.md (100%) rename content/{ => zh_cn}/backing-services.md (100%) rename content/{ => zh_cn}/build-release-run.md (100%) rename content/{ => zh_cn}/codebase.md (100%) rename content/{ => zh_cn}/concurrency.md (100%) rename content/{ => zh_cn}/config.md (100%) rename content/{ => zh_cn}/dependencies.md (100%) rename content/{ => zh_cn}/dev-prod-parity.md (100%) rename content/{ => zh_cn}/disposability.md (100%) rename content/{ => zh_cn}/intro.md (100%) rename content/{ => zh_cn}/logs.md (100%) rename content/{ => zh_cn}/port-binding.md (100%) rename content/{ => zh_cn}/processes.md (100%) rename content/{ => zh_cn}/toc.md (100%) rename content/{ => zh_cn}/who.md (100%) diff --git a/content/admin-processes.md b/content/zh_cn/admin-processes.md similarity index 100% rename from content/admin-processes.md rename to content/zh_cn/admin-processes.md diff --git a/content/background.md b/content/zh_cn/background.md similarity index 100% rename from content/background.md rename to content/zh_cn/background.md diff --git a/content/backing-services.md b/content/zh_cn/backing-services.md similarity index 100% rename from content/backing-services.md rename to content/zh_cn/backing-services.md diff --git a/content/build-release-run.md b/content/zh_cn/build-release-run.md similarity index 100% rename from content/build-release-run.md rename to content/zh_cn/build-release-run.md diff --git a/content/codebase.md b/content/zh_cn/codebase.md similarity index 100% rename from content/codebase.md rename to content/zh_cn/codebase.md diff --git a/content/concurrency.md b/content/zh_cn/concurrency.md similarity index 100% rename from content/concurrency.md rename to content/zh_cn/concurrency.md diff --git a/content/config.md b/content/zh_cn/config.md similarity index 100% rename from content/config.md rename to content/zh_cn/config.md diff --git a/content/dependencies.md b/content/zh_cn/dependencies.md similarity index 100% rename from content/dependencies.md rename to content/zh_cn/dependencies.md diff --git a/content/dev-prod-parity.md b/content/zh_cn/dev-prod-parity.md similarity index 100% rename from content/dev-prod-parity.md rename to content/zh_cn/dev-prod-parity.md diff --git a/content/disposability.md b/content/zh_cn/disposability.md similarity index 100% rename from content/disposability.md rename to content/zh_cn/disposability.md diff --git a/content/intro.md b/content/zh_cn/intro.md similarity index 100% rename from content/intro.md rename to content/zh_cn/intro.md diff --git a/content/logs.md b/content/zh_cn/logs.md similarity index 100% rename from content/logs.md rename to content/zh_cn/logs.md diff --git a/content/port-binding.md b/content/zh_cn/port-binding.md similarity index 100% rename from content/port-binding.md rename to content/zh_cn/port-binding.md diff --git a/content/processes.md b/content/zh_cn/processes.md similarity index 100% rename from content/processes.md rename to content/zh_cn/processes.md diff --git a/content/toc.md b/content/zh_cn/toc.md similarity index 100% rename from content/toc.md rename to content/zh_cn/toc.md diff --git a/content/who.md b/content/zh_cn/who.md similarity index 100% rename from content/who.md rename to content/zh_cn/who.md From cbf2ccee520949b629d6390f68e8acc03c86a913 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 5 Feb 2015 17:56:04 +0800 Subject: [PATCH 093/472] Add zh_cn locale file --- locales/zh_cn.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/zh_cn.yml diff --git a/locales/zh_cn.yml b/locales/zh_cn.yml new file mode 100644 index 000000000..7010edd45 --- /dev/null +++ b/locales/zh_cn.yml @@ -0,0 +1,7 @@ +zh_cn: + # Name of language listed in locales menu + language: 简体中文 (zh_cn) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: (简体中文) From fbfb62d4958f168ba80a49751f690e21853e1b53 Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Thu, 5 Feb 2015 18:01:55 +0800 Subject: [PATCH 094/472] Remove chinese version intro in the README --- Readme.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Readme.md b/Readme.md index df6bd8c76..124a7ca56 100644 --- a/Readme.md +++ b/Readme.md @@ -3,8 +3,6 @@ The Twelve-Factor App Source for the content app running at: http://www.12factor.net/ -中文翻译:http://liangshan.me/blog/2014/05/22/the-twelve-factor-app/ - Development ----------- From 5c0ec610f5d40e31043f13713ab8d47e3bdbb8d6 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 5 Feb 2015 20:20:02 +0000 Subject: [PATCH 095/472] changed to relative language links --- content/zh_cn/admin-processes.md | 8 ++++---- content/zh_cn/backing-services.md | 2 +- content/zh_cn/build-release-run.md | 8 ++++---- content/zh_cn/codebase.md | 2 +- content/zh_cn/concurrency.md | 2 +- content/zh_cn/config.md | 4 ++-- content/zh_cn/dev-prod-parity.md | 4 ++-- content/zh_cn/disposability.md | 4 ++-- content/zh_cn/port-binding.md | 2 +- content/zh_cn/processes.md | 6 +++--- content/zh_cn/toc.md | 24 ++++++++++++------------ 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/content/zh_cn/admin-processes.md b/content/zh_cn/admin-processes.md index 95772c61f..790d5c5ab 100644 --- a/content/zh_cn/admin-processes.md +++ b/content/zh_cn/admin-processes.md @@ -1,14 +1,14 @@ ## XII. 管理进程 ### 后台管理任务当作一次性进程运行 -[进程构成](/concurrency) 是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: +[进程构成](./concurrency) 是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: * 运行数据移植( Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate` )。 -* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell ),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具( `python` 或 `erl` ) ,或是其他命令( Ruby 使用 `irb`, Rails 使用 `rails console` )。 +* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell ),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具( `python` 或 `perl` ) ,或是其他命令( Ruby 使用 `irb`, Rails 使用 `rails console` )。 * 运行一些提交到代码仓库的一次性脚本。\n -一次性管理进程应该和正常的 [常驻进程](/processes) 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 [代码](/codebase) 和 [配置](/config) ,基于某个 [发布版本](/build-release-run) 运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。 +一次性管理进程应该和正常的 [常驻进程](./processes) 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 [代码](./codebase) 和 [配置](./config) ,基于某个 [发布版本](./build-release-run) 运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。 -所有进程类型应该使用同样的 [依赖隔离](/dependencies) 技术。例如,如果Ruby的web进程使用了命令 `bundle exec thin start` ,那么数据库移植应使用 `bundle exec rake db:migrate` 。同样的,如果一个 Python 程序使用了 Virtualenv,则需要在运行 Tornado Web 服务器和任何 `manage.py` 管理进程时引入 `bin/python` 。 +所有进程类型应该使用同样的 [依赖隔离](./dependencies) 技术。例如,如果Ruby的web进程使用了命令 `bundle exec thin start` ,那么数据库移植应使用 `bundle exec rake db:migrate` 。同样的,如果一个 Python 程序使用了 Virtualenv,则需要在运行 Tornado Web 服务器和任何 `manage.py` 管理进程时引入 `bin/python` 。 12-factor 尤其青睐那些提供了 REPL shell 的语言,因为那会让运行一次性脚本变得简单。在本地部署中,开发人员直接在命令行使用 shell 命令调用一次性管理进程。在线上部署中,开发人员依旧可以使用ssh或是运行环境提供的其他机制来运行这样的进程。 diff --git a/content/zh_cn/backing-services.md b/content/zh_cn/backing-services.md index 33becb65a..75911825e 100644 --- a/content/zh_cn/backing-services.md +++ b/content/zh_cn/backing-services.md @@ -5,7 +5,7 @@ 类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/) ),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/) ),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/) ),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 -**12-Factor 应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 [配置](/config) 中的服务定位/服务证书来获取数据。12-Factor 应用的任意 [部署](/codebase) ,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换。上述 2 个例子中,仅需修改配置中的资源地址。 +**12-Factor 应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 [配置](./config) 中的服务定位/服务证书来获取数据。12-Factor 应用的任意 [部署](./codebase) ,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换。上述 2 个例子中,仅需修改配置中的资源地址。 每个不同的后端服务是一份 *资源* 。例如,一个 MySQL 数据库是一个资源,两个 MySQL 数据库(用来数据分区)就被当作是 2 个不同的资源。12-Factor 应用将这些数据库都视作 *附加资源* ,这些资源和它们附属的部署保持松耦合。 diff --git a/content/zh_cn/build-release-run.md b/content/zh_cn/build-release-run.md index d7b3633db..bd68d5fd1 100644 --- a/content/zh_cn/build-release-run.md +++ b/content/zh_cn/build-release-run.md @@ -1,11 +1,11 @@ ## V. 构建,发布,运行 ### 严格分离构建和运行 -[基准代码](/codebase) 转化为一份部署(非开发环境)需要以下三个阶段: +[基准代码](./codebase) 转化为一份部署(非开发环境)需要以下三个阶段: -* *构建阶段* 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包 [依赖项](/dependencies),编译成二进制文件和资源文件。 -* *发布阶段* 会将构建的结果和当前部署所需 [配置](/config) 相结合,并能够立刻在运行环境中投入使用。 -* *运行阶段* (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 [进程](/processes)。 +* *构建阶段* 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包 [依赖项](./dependencies),编译成二进制文件和资源文件。 +* *发布阶段* 会将构建的结果和当前部署所需 [配置](./config) 相结合,并能够立刻在运行环境中投入使用。 +* *运行阶段* (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 [进程](./processes)。 ![代码被构建,然后和配置结合成为发布版本](/images/release.png) diff --git a/content/zh_cn/codebase.md b/content/zh_cn/codebase.md index c0bc1bc9d..1814796d5 100644 --- a/content/zh_cn/codebase.md +++ b/content/zh_cn/codebase.md @@ -10,7 +10,7 @@ 基准代码和应用之间总是保持一一对应的关系: * 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用 12-Factor 进行开发。 -* 多个应用共享一份基准代码是有悖于 12-Factor 原则的。解决方案是将共享的代码拆分为独立的类库,然后使用 [依赖管理](/dependencies) 策略去加载它们。 +* 多个应用共享一份基准代码是有悖于 12-Factor 原则的。解决方案是将共享的代码拆分为独立的类库,然后使用 [依赖管理](./dependencies) 策略去加载它们。 尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份 *部署* 相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index 45d7c487d..c0846bdef 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -9,6 +9,6 @@ 这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 -上述进程模型会在系统急需扩展时大放异彩。 [12-Factor 应用的进程所具备的无共享,水平分区的特性](/processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 +上述进程模型会在系统急需扩展时大放异彩。 [12-Factor 应用的进程所具备的无共享,水平分区的特性](./processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 12-Factor 应用的进程 [不需要守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入 PID 文件。相反的,应该借助操作系统的进程管理器(例如 [Upstart](http://upstart.ubuntu.com/) ,分布式的进程管理云平台,或是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),来管理 [输出流](/logs) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 diff --git a/content/zh_cn/config.md b/content/zh_cn/config.md index 60fda4cf3..29524bbd7 100644 --- a/content/zh_cn/config.md +++ b/content/zh_cn/config.md @@ -1,9 +1,9 @@ ## III. 配置 ### 在环境中存储配置 -通常,应用的 *配置* 在不同 [部署](/codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: +通常,应用的 *配置* 在不同 [部署](./codebase) (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: -* 数据库,Memcached,以及其他 [后端服务](/backing-services) 的配置 +* 数据库,Memcached,以及其他 [后端服务](./backing-services) 的配置 * 第三方服务的证书,如 Amazon S3、Twitter 等 * 每份部署特有的配置,如域名等 diff --git a/content/zh_cn/dev-prod-parity.md b/content/zh_cn/dev-prod-parity.md index b99d6c297..e8f1abf6b 100644 --- a/content/zh_cn/dev-prod-parity.md +++ b/content/zh_cn/dev-prod-parity.md @@ -1,7 +1,7 @@ ## X. 开发环境与线上环境等价 ### 尽可能的保持开发,预发布,线上环境相同 -从以往经验来看,开发环境(即开发人员的本地 [部署](/codebase))和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面: +从以往经验来看,开发环境(即开发人员的本地 [部署](./codebase))和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面: * **\[The time gap\] 时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 * **\[The personnel gap\]人员差异:** 开发人员编写代码,运维人员部署代码。 @@ -38,7 +38,7 @@ -[后端服务](/backing-services) 是保持开发与线上等价的重要部分,例如数据库,队列系统,以及缓存。许多语言都提供了简化获取后端服务的类库,例如不同类型服务的 *适配器* 。下列表格提供了一些例子。 +[后端服务](./backing-services) 是保持开发与线上等价的重要部分,例如数据库,队列系统,以及缓存。许多语言都提供了简化获取后端服务的类库,例如不同类型服务的 *适配器* 。下列表格提供了一些例子。 diff --git a/content/zh_cn/disposability.md b/content/zh_cn/disposability.md index 66b57c0ba..a68767eba 100644 --- a/content/zh_cn/disposability.md +++ b/content/zh_cn/disposability.md @@ -1,9 +1,9 @@ ## IX. 易处理 ### 快速启动和优雅终止可最大化健壮性 -**12-Factor 应用的 [进程](/processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](/codebase) 或 [配置](/config) ,稳健的部署应用。 +**12-Factor 应用的 [进程](./processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](./codebase) 或 [配置](./config) ,稳健的部署应用。 -进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](/build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 +进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](./build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是 HTTP 请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 diff --git a/content/zh_cn/port-binding.md b/content/zh_cn/port-binding.md index 9d1061982..87f9bda8d 100644 --- a/content/zh_cn/port-binding.md +++ b/content/zh_cn/port-binding.md @@ -7,7 +7,7 @@ 本地环境中,开发人员通过类似 `http://localhost:5000/` 的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 -通常的实现思路是,将网络服务器类库通过 [依赖声明](/dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://jetty.codehaus.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 +通常的实现思路是,将网络服务器类库通过 [依赖声明](./dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://jetty.codehaus.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 diff --git a/content/zh_cn/processes.md b/content/zh_cn/processes.md index e55790c54..4f1a54e04 100644 --- a/content/zh_cn/processes.md +++ b/content/zh_cn/processes.md @@ -3,12 +3,12 @@ 运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py` )。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](/concurrency) ,也就是零个或多个进程实例。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py` )。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](./concurrency) ,也就是零个或多个进程实例。 -**12-Factor 应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](/backing-services) 内,比如数据库。 +**12-Factor 应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](./backing-services) 内,比如数据库。 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具( [Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/) ) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](/build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 +源文件打包工具( [Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/) ) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 diff --git a/content/zh_cn/toc.md b/content/zh_cn/toc.md index 6ee4854a9..277ef7006 100644 --- a/content/zh_cn/toc.md +++ b/content/zh_cn/toc.md @@ -1,38 +1,38 @@ 12-factors ================== -## [I. 基准代码](/codebase) +## [I. 基准代码](./codebase) ### 一份基准代码,多份部署 -## [II. 依赖](/dependencies) +## [II. 依赖](./dependencies) ### 显式声明依赖关系 -## [III. 配置](/config) +## [III. 配置](./config) ### 在环境中存储配置 -## [IV. 后端服务](/backing-services) +## [IV. 后端服务](./backing-services) ### 把后端服务当作附加资源 -## [V. 构建,发布,运行](/build-release-run) +## [V. 构建,发布,运行](./build-release-run) ### 严格分离构建和运行 -## [VI. 进程](/processes) +## [VI. 进程](./processes) ### 以一个或多个无状态进程运行应用 -## [VII. 端口绑定](/port-binding) +## [VII. 端口绑定](./port-binding) ### 通过端口绑定提供服务 -## [VIII. 并发](/concurrency) +## [VIII. 并发](./concurrency) ### 通过进程模型进行扩展 -## [IX. 易处理](/disposability) +## [IX. 易处理](./disposability) ### 快速启动和优雅终止可最大化健壮性 -## [X. 开发环境与线上环境等价](/dev-prod-parity) +## [X. 开发环境与线上环境等价](./dev-prod-parity) ### 尽可能的保持开发,预发布,线上环境相同 -## [XI. 日志](/logs) +## [XI. 日志](./logs) ### 把日志当作事件流 -## [XII. 管理进程](/admin-processes) +## [XII. 管理进程](./admin-processes) ### 后台管理任务当作一次性进程运行 From d70379c63b8aa789b64be18dd302681ec719927e Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Fri, 6 Feb 2015 09:44:02 +0800 Subject: [PATCH 096/472] Fix error formats --- content/zh_cn/backing-services.md | 4 ++-- content/zh_cn/build-release-run.md | 4 ++-- content/zh_cn/codebase.md | 2 +- content/zh_cn/concurrency.md | 4 ++-- content/zh_cn/config.md | 2 +- content/zh_cn/dependencies.md | 6 +++--- content/zh_cn/dev-prod-parity.md | 14 +++++++------- content/zh_cn/disposability.md | 6 +++--- content/zh_cn/intro.md | 10 +++++----- content/zh_cn/logs.md | 8 ++++---- content/zh_cn/port-binding.md | 8 ++++---- content/zh_cn/processes.md | 6 +++--- 12 files changed, 37 insertions(+), 37 deletions(-) diff --git a/content/zh_cn/backing-services.md b/content/zh_cn/backing-services.md index 75911825e..70a6d998f 100644 --- a/content/zh_cn/backing-services.md +++ b/content/zh_cn/backing-services.md @@ -1,9 +1,9 @@ ## IV. 后端服务 ### 把后端服务(*backing services*)当作附加资源 -*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库( [MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/) ),消息/队列系统( [RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/) ),SMTP 邮件发送服务( [ Postfix](http://www.postfix.org/) ),以及缓存系统( [Memcached](http://memcached.org/) )。 +*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 -类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/) ),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/) ),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/) ),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 +类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/)),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 **12-Factor 应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 [配置](./config) 中的服务定位/服务证书来获取数据。12-Factor 应用的任意 [部署](./codebase) ,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换。上述 2 个例子中,仅需修改配置中的资源地址。 diff --git a/content/zh_cn/build-release-run.md b/content/zh_cn/build-release-run.md index bd68d5fd1..db2d4e9ed 100644 --- a/content/zh_cn/build-release-run.md +++ b/content/zh_cn/build-release-run.md @@ -13,6 +13,6 @@ 部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 -每一个发布版本必须对应一个唯一的发布 ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 +每一个发布版本必须对应一个唯一的发布 ID,例如可以使用发布时的时间戳(`2011-04-06-20:32:17`),亦或是一个增长的数字(`v100`)。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。 -新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,从而得到妥善处理。 \ No newline at end of file +新的代码在部署之前,需要开发人员触发构建操作。但是,运行阶段不一定需要人为触发,而是可以自动进行。如服务器重启,或是进程管理器重启了一个崩溃的进程。因此,运行阶段应该保持尽可能少的模块,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,从而得到妥善处理。 diff --git a/content/zh_cn/codebase.md b/content/zh_cn/codebase.md index 1814796d5..dd48a554f 100644 --- a/content/zh_cn/codebase.md +++ b/content/zh_cn/codebase.md @@ -3,7 +3,7 @@ 12-Factor 应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 -在类似SVN这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 +在类似 SVN 这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在 Git 那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 ![一份代码库对应多份部署](/images/codebase-deploys.png) diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index c0846bdef..2a07019a0 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -1,11 +1,11 @@ ## VIII. 并发 ### 通过进程模型进行扩展 -任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP 进程作为 Apache 的子进程存在,随请求按需启动。Java 进程则采取了相反的方式,在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源( CPU 和内存),并通过多线程实现内部的并发管理。上述 2 个例子中,进程是开发人员可以操作的最小单位。 +任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP 进程作为 Apache 的子进程存在,随请求按需启动。Java 进程则采取了相反的方式,在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源(CPU 和内存),并通过多线程实现内部的并发管理。上述 2 个例子中,进程是开发人员可以操作的最小单位。 ![扩展表现为运行中的进程,工作多样性表现为进程类型。](/images/process-types.png) -**在 12-actor 应用中,进程是一等公民。** 12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 +**在 12-actor 应用中,进程是一等公民。**12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 diff --git a/content/zh_cn/config.md b/content/zh_cn/config.md index 29524bbd7..93013adf4 100644 --- a/content/zh_cn/config.md +++ b/content/zh_cn/config.md @@ -13,7 +13,7 @@ 需要指出的是,这里定义的"配置"并**不**包括应用的内部配置,比如 Rails 的 `config/routes.rb`,或是使用 [Spring](http://www.springsource.org/) 时 [代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 -另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像Rails的 `config/database.yml` 。这相对于在代码中使用常量已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的可能会分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 +另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像 Rails 的 `config/database.yml` 。这相对于在代码中使用常量已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的可能会分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 **12-Factor推荐将应用的配置存储于 *环境变量* 中**( *env vars*, *env* )。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如 Java 的属性配置文件)相比,环境变量与语言和系统无关。 diff --git a/content/zh_cn/dependencies.md b/content/zh_cn/dependencies.md index 3a1660b31..38040ce1b 100644 --- a/content/zh_cn/dependencies.md +++ b/content/zh_cn/dependencies.md @@ -1,12 +1,12 @@ ## II. 依赖 ### 显式声明依赖关系( *dependency* ) -大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像 Perl 的 [CPAN](http://www.cpan.org/) 或是 Ruby 的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为 "site packages" ),或仅供某个应用程序使用,部署在相应的目录中(称之为 "vendoring" 或 "bunding" )。 +大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像 Perl 的 [CPAN](http://www.cpan.org/) 或是 Ruby 的 [Rubygems](http://rubygems.org/) 。通过打包系统安装的类库可以是系统级的(称之为 "site packages"),或仅供某个应用程序使用,部署在相应的目录中(称之为 "vendoring" 或 "bunding")。 **12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它一定通过 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 -例如, Ruby 的 [Gem Bundler](http://gembundler.com/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 +例如, Ruby 的 [Gem Bundler](http://gembundler.com/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。 显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler 下使用 `bundle install`,而 Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是 `lein deps`。 -12-Factor 应用同样不会隐式依赖某些系统工具,如 ImageMagick 或是`curl`。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 \ No newline at end of file +12-Factor 应用同样不会隐式依赖某些系统工具,如 ImageMagick 或是`curl`。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 diff --git a/content/zh_cn/dev-prod-parity.md b/content/zh_cn/dev-prod-parity.md index e8f1abf6b..f45cf3fe5 100644 --- a/content/zh_cn/dev-prod-parity.md +++ b/content/zh_cn/dev-prod-parity.md @@ -3,15 +3,15 @@ 从以往经验来看,开发环境(即开发人员的本地 [部署](./codebase))和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面: -* **\[The time gap\] 时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 -* **\[The personnel gap\]人员差异:** 开发人员编写代码,运维人员部署代码。 -* **\[The tools gap\]工具差异:** 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。 +* **时间差异:** 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。 +* **人员差异:** 开发人员编写代码,运维人员部署代码。 +* **工具差异:** 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。 **12-Factor 应用想要做到 [持续部署](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: -* \[1\]缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 -* \[2\]缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 -* \[3\]缩小工具差异:尽量保证开发环境以及线上环境的一致性。 +* 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 +* 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 +* 缩小工具差异:尽量保证开发环境以及线上环境的一致性。 将上述总结变为一个表格如下: @@ -71,6 +71,6 @@ **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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 +与此同时,轻量的本地服务也不像以前那样引人注目。借助于 [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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的相同版本。 diff --git a/content/zh_cn/disposability.md b/content/zh_cn/disposability.md index a68767eba..1965638b4 100644 --- a/content/zh_cn/disposability.md +++ b/content/zh_cn/disposability.md @@ -5,9 +5,9 @@ 进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](./build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 -进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是 HTTP 请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 +进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是 HTTP 请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 -对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) 信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 +对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 -进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。 [Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 +进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。[Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 diff --git a/content/zh_cn/intro.md b/content/zh_cn/intro.md index c5f8309f1..7fffe4e3f 100644 --- a/content/zh_cn/intro.md +++ b/content/zh_cn/intro.md @@ -2,10 +2,10 @@ ============ 如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”( SaaS )。12-Factor 为构建如下的 SaaS 应用提供了方法论: -* 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目;\n -* 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**;\n -* 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源;\n -* 将开发环境和生产环境的**差异降至最低**,并使用**持续交付**实施敏捷开发;\n -* 可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**;\n +* 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。 +* 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**。 +* 适合**部署**在现代的**云计算平台**,从而在服务器和系统管理方面节省资源。 +* 将开发环境和生产环境的**差异降至最低**,并使用**持续交付**实施敏捷开发。 +* 可以在工具、架构和开发流程不发生明显变化的前提下实现**扩展**。 这套理论适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序。 diff --git a/content/zh_cn/logs.md b/content/zh_cn/logs.md index edb24acad..b751b6e9d 100644 --- a/content/zh_cn/logs.md +++ b/content/zh_cn/logs.md @@ -5,12 +5,12 @@ 日志应该是 [事件流](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) 的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行,日志最原始的格式确实是一个事件一行。日志没有确定开始和结束,但随着应用在运行会持续的增加。 -**12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出( `stdout` )事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 +**12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(`stdout`)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 [Logplex](https://github.com/heroku/logplex) 和 [Fluent](https://github.com/fluent/fluentd) 的开源工具可以达到这个目的。 这些事件流可以输出至文件,或者在终端实时观察。最重要的,输出流可以发送到 [Splunk](http://www.splunk.com/) 这样的日志索引及分析系统,或 [Hadoop/Hive](http://hive.apache.org/) 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括: -* \[1\]找出过去一段时间特殊的事件。 -* \[2\]图形化一个大规模的趋势,比如每分钟的请求量。 -* \[3\]根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。 +* 找出过去一段时间特殊的事件。 +* 图形化一个大规模的趋势,比如每分钟的请求量。 +* 根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。 diff --git a/content/zh_cn/port-binding.md b/content/zh_cn/port-binding.md index 87f9bda8d..045d8a164 100644 --- a/content/zh_cn/port-binding.md +++ b/content/zh_cn/port-binding.md @@ -1,14 +1,14 @@ ## VII. 端口绑定 ### 通过端口绑定(*Port binding*)来提供服务 -互联网应用有时会运行于服务器的容器之中。例如PHP经常作为 [Apache HTTPD](http://httpd.apache.org/) 的一个模块来运行,正如 Java 运行于 [Tomcat](http://tomcat.apache.org/) 。 +互联网应用有时会运行于服务器的容器之中。例如 PHP 经常作为 [Apache HTTPD](http://httpd.apache.org/) 的一个模块来运行,正如 Java 运行于 [Tomcat](http://tomcat.apache.org/) 。 **12-Factor 应用完全自我加载** 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 **通过端口绑定来提供服务** ,并监听发送至该端口的请求。 -本地环境中,开发人员通过类似 `http://localhost:5000/` 的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 +本地环境中,开发人员通过类似`http://localhost:5000/`的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 通常的实现思路是,将网络服务器类库通过 [依赖声明](./dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://jetty.codehaus.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 -HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 +HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis 协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 -还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](/backing-services) ,调用方将服务方提供的相应URL当作资源存入 [配置](/config) 以备将来调用。 \ No newline at end of file +还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](/backing-services) ,调用方将服务方提供的相应 URL 当作资源存入 [配置](/config) 以备将来调用。 diff --git a/content/zh_cn/processes.md b/content/zh_cn/processes.md index 4f1a54e04..adde52e77 100644 --- a/content/zh_cn/processes.md +++ b/content/zh_cn/processes.md @@ -3,12 +3,12 @@ 运行环境中,应用程序通常是以一个和多个 *进程* 运行的。 -最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如 `python my_script.py` )。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](./concurrency) ,也就是零个或多个进程实例。 +最简单的场景中,代码是一个独立的脚本,运行环境是开发人员自己的笔记本电脑,进程由一条命令行(例如`python my_script.py`)。另外一个极端情况是,复杂的应用可能会使用很多 [进程类型](./concurrency) ,也就是零个或多个进程实例。 **12-Factor 应用的进程必须无状态且 [无共享](http://en.wikipedia.org/wiki/Shared_nothing_architecture) 。** 任何需要持久化的数据都要存储在 [后端服务](./backing-services) 内,比如数据库。 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具( [Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/) ) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 -一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如[Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 +一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如 [Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 From 43a16ef59f65a66343e7736e2dfe6b650508782e Mon Sep 17 00:00:00 2001 From: liangshan <2lisum3@gmail.com> Date: Fri, 6 Feb 2015 10:12:21 +0800 Subject: [PATCH 097/472] Update zh_cn translation --- content/zh_cn/admin-processes.md | 8 ++++---- content/zh_cn/backing-services.md | 2 +- content/zh_cn/build-release-run.md | 2 +- content/zh_cn/codebase.md | 4 ++-- content/zh_cn/config.md | 2 +- content/zh_cn/dev-prod-parity.md | 2 +- content/zh_cn/disposability.md | 4 ++-- content/zh_cn/intro.md | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/content/zh_cn/admin-processes.md b/content/zh_cn/admin-processes.md index 790d5c5ab..b2175445e 100644 --- a/content/zh_cn/admin-processes.md +++ b/content/zh_cn/admin-processes.md @@ -1,11 +1,11 @@ ## XII. 管理进程 ### 后台管理任务当作一次性进程运行 -[进程构成](./concurrency) 是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: +[进程构成](./concurrency)(process formation)是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: -* 运行数据移植( Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate` )。 -* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell ),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具( `python` 或 `perl` ) ,或是其他命令( Ruby 使用 `irb`, Rails 使用 `rails console` )。 -* 运行一些提交到代码仓库的一次性脚本。\n +* 运行数据移植(Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate`)。 +* 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具(`python` 或 `perl`) ,或是其他命令(Ruby 使用 `irb`, Rails 使用 `rails console`)。 +* 运行一些提交到代码仓库的一次性脚本。 一次性管理进程应该和正常的 [常驻进程](./processes) 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 [代码](./codebase) 和 [配置](./config) ,基于某个 [发布版本](./build-release-run) 运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。 diff --git a/content/zh_cn/backing-services.md b/content/zh_cn/backing-services.md index 70a6d998f..16d5fc550 100644 --- a/content/zh_cn/backing-services.md +++ b/content/zh_cn/backing-services.md @@ -1,7 +1,7 @@ ## IV. 后端服务 ### 把后端服务(*backing services*)当作附加资源 -*后端服务* 是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 +*后端服务*是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/)),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 diff --git a/content/zh_cn/build-release-run.md b/content/zh_cn/build-release-run.md index db2d4e9ed..838e0418c 100644 --- a/content/zh_cn/build-release-run.md +++ b/content/zh_cn/build-release-run.md @@ -9,7 +9,7 @@ ![代码被构建,然后和配置结合成为发布版本](/images/release.png) -**Twelve-facfor应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 +**12-facfor 应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 diff --git a/content/zh_cn/codebase.md b/content/zh_cn/codebase.md index dd48a554f..40af32cca 100644 --- a/content/zh_cn/codebase.md +++ b/content/zh_cn/codebase.md @@ -1,9 +1,9 @@ ## I. 基准代码 ### 一份基准代码(*Codebase*),多份部署(*deploy*) -12-Factor 应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库* (code repository, code repo, repo)。 +12-Factor应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库*(code repository, code repo, repo)。 -在类似 SVN 这样的集中式版本控制系统中, *基准代码* 就是指控制系统中的这一份代码库;而在 Git 那样的分布式版本控制系统中, *基准代码* 则是指最上游的那份代码库。 +在类似 SVN 这样的集中式版本控制系统中,*基准代码* 就是指控制系统中的这一份代码库;而在 Git 那样的分布式版本控制系统中,*基准代码* 则是指最上游的那份代码库。 ![一份代码库对应多份部署](/images/codebase-deploys.png) diff --git a/content/zh_cn/config.md b/content/zh_cn/config.md index 93013adf4..92cf639d3 100644 --- a/content/zh_cn/config.md +++ b/content/zh_cn/config.md @@ -17,6 +17,6 @@ **12-Factor推荐将应用的配置存储于 *环境变量* 中**( *env vars*, *env* )。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码;与配置文件不同,不小心把它们签入代码库的概率微乎其微;与一些传统的解决配置问题的机制(比如 Java 的属性配置文件)相比,环境变量与语言和系统无关。 -配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如 Rails 中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 +配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组(或叫做“环境”),例如Rails中的 `development`,`test`, 和 `production` 环境。这种方法无法轻易扩展:更多部署意味着更多新的环境,例如 `staging` 或 `qa` 。 随着项目的不断深入,开发人员可能还会添加他们自己的环境,比如 `joes-staging` ,这将导致各种配置组合的激增,从而给管理部署增加了很多不确定因素。 12-Factor 应用中,环境变量的粒度要足够小,且相对独立。它们永远也不会组合成一个所谓的“环境”,而是独立存在于每个部署之中。当应用程序不断扩展,需要更多种类的部署时,这种配置管理方式能够做到平滑过渡。 diff --git a/content/zh_cn/dev-prod-parity.md b/content/zh_cn/dev-prod-parity.md index f45cf3fe5..f7cf98c2a 100644 --- a/content/zh_cn/dev-prod-parity.md +++ b/content/zh_cn/dev-prod-parity.md @@ -71,6 +71,6 @@ **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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 +与此同时,轻量的本地服务也不像以前那样引人注目。借助于[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/) 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比,安装这些系统显然是值得的。 不同后端服务的适配器仍然是有用的,因为它们可以使移植后端服务变得简单。但应用的所有部署,这其中包括开发、预发布以及线上环境,都应该使用同一个后端服务的相同版本。 diff --git a/content/zh_cn/disposability.md b/content/zh_cn/disposability.md index 1965638b4..bae8394b4 100644 --- a/content/zh_cn/disposability.md +++ b/content/zh_cn/disposability.md @@ -1,11 +1,11 @@ ## IX. 易处理 ### 快速启动和优雅终止可最大化健壮性 -**12-Factor 应用的 [进程](./processes) 是 *可支配* 的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](./codebase) 或 [配置](./config) ,稳健的部署应用。 +**12-Factor 应用的 [进程](./processes) 是 *易处理(disposable)*的,意思是说它们可以瞬间开启或停止。** 这有利于快速、弹性的伸缩应用,迅速部署变化的 [代码](./codebase) 或 [配置](./config) ,稳健的部署应用。 进程应当追求 **最小启动时间** 。 理想状态下,进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 [发布](./build-release-run) 以及扩展过程,此外还增加了健壮性,因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 -进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是 HTTP 请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 +进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 diff --git a/content/zh_cn/intro.md b/content/zh_cn/intro.md index 7fffe4e3f..a6fc37eef 100644 --- a/content/zh_cn/intro.md +++ b/content/zh_cn/intro.md @@ -1,6 +1,6 @@ 简介 ============ -如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或“软件即服务”( SaaS )。12-Factor 为构建如下的 SaaS 应用提供了方法论: +如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或软件即服务(SaaS)。12-Factor 为构建如下的 SaaS 应用提供了方法论: * 使用**标准化**流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。 * 和操作系统之间尽可能的**划清界限**,在各个系统中提供**最大的可移植性**。 From 1a8c15713d8400eaab37b555d384b9b50ea99c4c Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Fri, 6 Feb 2015 11:49:58 +0000 Subject: [PATCH 098/472] update to new django --- content/en/admin-processes.md | 2 +- content/ja/admin-processes.md | 2 +- content/zh_cn/admin-processes.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/admin-processes.md b/content/en/admin-processes.md index 7015e7a1c..870a56096 100644 --- a/content/en/admin-processes.md +++ b/content/en/admin-processes.md @@ -3,7 +3,7 @@ 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 syncdb` in Django, `rake db:migrate` in Rails). +* 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`). diff --git a/content/ja/admin-processes.md b/content/ja/admin-processes.md index b31ed5ca6..a3c68481e 100644 --- a/content/ja/admin-processes.md +++ b/content/ja/admin-processes.md @@ -3,7 +3,7 @@ [プロセスフォーメーション](./concurrency)は、アプリケーションが実行されたときにアプリケーションの通常の役割(Webリクエストの処理など)に使われるプロセス群である。それとは別に、開発者はしばしばアプリケーションのために1回限りの管理・メンテナンス用のタスクを実行したくなる。例えば: -* データベースのマイグレーションを実行する。(例:Djangoにおける `manage.py syncdb` やRailsにおける `rake db:migrate`) +* データベースのマイグレーションを実行する。(例:Djangoにおける `manage.py migrate` やRailsにおける `rake db:migrate`) * 任意のコードを実行したり、生のデータベースに対してアプリケーションのモデルを調査したりするために、コンソール([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)シェルとも言われる)を実行する。多くの言語ではインタプリタを引数なしで実行する(例:`python` や `perl`)ことでREPLを利用できるが、別のコマンドを用意している場合もある(例:Rubyでの `irb` や Railsでの `rails console`)。 * アプリケーションのリポジトリにコミットされた1回限りのスクリプトを実行する(例:`php scripts/fix_bad_records.php`)。 diff --git a/content/zh_cn/admin-processes.md b/content/zh_cn/admin-processes.md index b2175445e..715266ee3 100644 --- a/content/zh_cn/admin-processes.md +++ b/content/zh_cn/admin-processes.md @@ -3,7 +3,7 @@ [进程构成](./concurrency)(process formation)是指用来处理应用的常规业务(比如处理 web 请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如: -* 运行数据移植(Django 中的 `manage.py syncdb`, Rails 中的 `rake db:migrate`)。 +* 运行数据移植(Django 中的 `manage.py migrate`, Rails 中的 `rake db:migrate`)。 * 运行一个控制台(也被称为 [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell),来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具(`python` 或 `perl`) ,或是其他命令(Ruby 使用 `irb`, Rails 使用 `rails console`)。 * 运行一些提交到代码仓库的一次性脚本。 From 1bd9ee9859d0006e3f74e2e375a9207fd57d5cc9 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Sun, 8 Feb 2015 21:21:05 -0200 Subject: [PATCH 099/472] Make pt_br translation compatible to translation system --- content/{background-pt.md => pt_br/background.md} | 0 content/{codebase-pt.md => pt_br/codebase.md} | 0 content/{dependencies-br.md => pt_br/dependencies.md} | 0 content/{intro-pt.md => pt_br/intro.md} | 0 content/{toc-br.md => pt_br/toc.md} | 0 content/{who-pt.md => pt_br/who.md} | 0 locales/pt_br.yml | 7 +++++++ 7 files changed, 7 insertions(+) rename content/{background-pt.md => pt_br/background.md} (100%) rename content/{codebase-pt.md => pt_br/codebase.md} (100%) rename content/{dependencies-br.md => pt_br/dependencies.md} (100%) rename content/{intro-pt.md => pt_br/intro.md} (100%) rename content/{toc-br.md => pt_br/toc.md} (100%) rename content/{who-pt.md => pt_br/who.md} (100%) create mode 100644 locales/pt_br.yml diff --git a/content/background-pt.md b/content/pt_br/background.md similarity index 100% rename from content/background-pt.md rename to content/pt_br/background.md diff --git a/content/codebase-pt.md b/content/pt_br/codebase.md similarity index 100% rename from content/codebase-pt.md rename to content/pt_br/codebase.md diff --git a/content/dependencies-br.md b/content/pt_br/dependencies.md similarity index 100% rename from content/dependencies-br.md rename to content/pt_br/dependencies.md diff --git a/content/intro-pt.md b/content/pt_br/intro.md similarity index 100% rename from content/intro-pt.md rename to content/pt_br/intro.md diff --git a/content/toc-br.md b/content/pt_br/toc.md similarity index 100% rename from content/toc-br.md rename to content/pt_br/toc.md diff --git a/content/who-pt.md b/content/pt_br/who.md similarity index 100% rename from content/who-pt.md rename to content/pt_br/who.md diff --git a/locales/pt_br.yml b/locales/pt_br.yml new file mode 100644 index 000000000..1a4eafbf6 --- /dev/null +++ b/locales/pt_br.yml @@ -0,0 +1,7 @@ +pt_br: + # Name of language listed in locales menu + language: Brazilian Portuguese (pt_br) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "(traduzido)" From 3658be030a079fe5ee74d9b789d35b3715481d56 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Sun, 8 Feb 2015 21:21:22 -0200 Subject: [PATCH 100/472] Remove dummy files --- getAllObjects | 1 - getAllObjects.1 | 1 - index.html | 31 ------------------------------- index.html.1 | 31 ------------------------------- index.html.2 | 31 ------------------------------- 5 files changed, 95 deletions(-) delete mode 100644 getAllObjects delete mode 100644 getAllObjects.1 delete mode 100644 index.html delete mode 100644 index.html.1 delete mode 100644 index.html.2 diff --git a/getAllObjects b/getAllObjects deleted file mode 100644 index 9ee25c3dc..000000000 --- a/getAllObjects +++ /dev/null @@ -1 +0,0 @@ -[{"firstOrderStepId":1,"id":0,"isActive":1,"name":"Additional Products","unitSize":null},{"firstOrderStepId":1,"id":10,"isActive":1,"name":"Control Panels for VPS","unitSize":null},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":32,"isActive":1,"name":"Quad Processor, Quad Core Intel","subDescription":"Quad Processor Multi-core Servers","unitSize":2},{"description":"
dual processor multi core<\/div>","firstOrderStepId":1,"id":35,"isActive":1,"name":"Dual Xeon (Dual Core) Woodcrest\/Cloverton - OUTLET","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":41,"isActive":1,"name":"Single Xeon 5500 Series (Nehalem)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Dual Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":42,"isActive":1,"name":"Dual Xeon 5500 Series (Nehalem)","subDescription":"Dual Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: Redundant Power<\/div>","firstOrderStepId":1,"id":43,"isActive":1,"name":"Specialty Server: Redundant Power: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Redundant Power","unitSize":2},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":44,"isActive":1,"name":"Specialty Server: Mass Storage: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"Virtual Server Instance","firstOrderStepId":1,"id":46,"isActive":1,"name":"Cloud Server","subDescription":"Virtual Server Instance","unitSize":1},{"description":"
Specialty Servers: Redundant Power<\/div>","firstOrderStepId":1,"id":49,"isActive":1,"name":"Specialty Server: 4u Redundant power Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Redundant Power","unitSize":4},{"firstOrderStepId":1,"id":50,"isActive":1,"name":"Bare Metal Instance","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":51,"isActive":1,"name":"Single Xeon 3400 Series (Lynnfield)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":52,"isActive":1,"name":"Specialty Server: 4u Mass Storage Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":53,"isActive":1,"name":"Specialty Server: Private Network: Single Xeon 3400 Series (Lynnfield)","subDescription":"Specialty Servers: Private Network","unitSize":1},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":54,"isActive":1,"name":"Specialty Server: Private Network: Dual Xeon 5500 Series (Nehalem)","subDescription":"Specialty Servers: Private Network","unitSize":1},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":55,"isActive":1,"name":"Specialty Server: Private Network & Redundant Power: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Private Network","unitSize":2},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":56,"isActive":1,"name":"Quad Processor Multi Core Nehalem EX","subDescription":"Quad Processor Multi-core Servers","unitSize":2},{"description":"
Colocation Service<\/div>","firstOrderStepId":1,"id":58,"isActive":1,"name":"Colocation Service","unitSize":1},{"description":"ThePlanet Legacy Placeholder Package","firstOrderStepId":1,"id":60,"isActive":1,"name":"ThePlanet Legacy Placeholder Package","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":61,"isActive":1,"name":"Virtual Rack MD3000i SAN - HA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":62,"isActive":1,"name":"PC Dual Xeon 5130 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":63,"isActive":1,"name":"PC Dual Xeon 5130 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":64,"isActive":1,"name":"PR Dual Xeon 5520 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":65,"isActive":1,"name":"Virtual Rack Xeon 3210 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":66,"isActive":1,"name":"Virtual Rack Dual Xeon 5335 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":67,"isActive":1,"name":"PR Dual Xeon 5520 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":68,"isActive":1,"name":"PR Dual Xeon 5620 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":69,"isActive":1,"name":"PR Dual Xeon 5620 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":70,"isActive":1,"name":"Virtual Rack Dual Xeon 5620 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":71,"isActive":1,"name":"Virtual Rack Dual Xeon 5620 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":72,"isActive":1,"name":"PC Dual Xeon 5620 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":73,"isActive":1,"name":"PC Dual Xeon 5620 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":74,"isActive":1,"name":"Virtual Rack Dual Xeon 5660 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":75,"isActive":1,"name":"Virtual Rack Dual Xeon 5660 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":76,"isActive":1,"name":"PC Dual Xeon 5660 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":77,"isActive":1,"name":"PC Dual Xeon 5660 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":78,"isActive":1,"name":"Virtual Rack Quad Xeon 7550 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":79,"isActive":1,"name":"PC Quad Xeon 7550 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":80,"isActive":1,"name":"PR Xeon 3450 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":81,"isActive":1,"name":"PR Xeon 3450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":82,"isActive":1,"name":"Virtual Rack Pentium G6950 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":83,"isActive":1,"name":"PC Pentium G6950 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":84,"isActive":1,"name":"Virtual Rack MD1000 DAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":85,"isActive":1,"name":"Virtual Rack MD3000 DAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":86,"isActive":1,"name":"Virtual Rack MD3000 DAS - HA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":87,"isActive":1,"name":"PR Dual Xeon 5130 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":88,"isActive":1,"name":"PR Dual Xeon 5130 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":89,"isActive":1,"name":"PR Dual Xeon 5335 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":90,"isActive":1,"name":"PR Xeon 3060 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":91,"isActive":1,"name":"PR Xeon 3060 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":92,"isActive":1,"name":"PR Xeon 3210 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":93,"isActive":1,"name":"PR Xeon 3210 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":94,"isActive":1,"name":"PC Dual Xeon 5335 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":95,"isActive":1,"name":"PC Dual Xeon 5335 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":96,"isActive":1,"name":"PC Dual Xeon 5405 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":97,"isActive":1,"name":"PC Dual Xeon 5405 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":98,"isActive":1,"name":"PC Dual Xeon 5405 - Monster","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":99,"isActive":1,"name":"PC Xeon 3360 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":100,"isActive":1,"name":"PC Xeon 3360 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":101,"isActive":1,"name":"PC Dual Xeon 5450 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":102,"isActive":1,"name":"PC Dual Xeon 5450 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":103,"isActive":1,"name":"PR Xeon 3040 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":104,"isActive":1,"name":"PC Xeon 3210 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":105,"isActive":1,"name":"PC Xeon 3210 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":106,"isActive":1,"name":"PR Dual Xeon 5335 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":107,"isActive":1,"name":"Virtual Rack Xeon 3360 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":108,"isActive":1,"name":"Virtual Rack Xeon 3360 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":109,"isActive":1,"name":"Virtual Rack Dual Xeon 5450 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":110,"isActive":1,"name":"Virtual Rack Dual Xeon 5450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":111,"isActive":1,"name":"Virtual Rack Xeon 3210 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":112,"isActive":1,"name":"Virtual Rack Dual Xeon 5130 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":113,"isActive":1,"name":"Virtual Rack Dual Xeon 5335 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":114,"isActive":1,"name":"Virtual Rack Dual Xeon 5130 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":115,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":116,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":117,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - Monster","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":118,"isActive":1,"name":"PC Dual Xeon 5520 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":119,"isActive":1,"name":"PC Dual Xeon 5520 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":120,"isActive":1,"name":"Virtual Rack Dual Xeon 5520 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":121,"isActive":1,"name":"Virtual Rack Dual Xeon 5520 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":122,"isActive":1,"name":"PC Xeon 3450 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":123,"isActive":1,"name":"PC Xeon 3450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":124,"isActive":1,"name":"Virtual Rack Xeon 3450 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":125,"isActive":1,"name":"Virtual Rack Xeon 3450 - SAS","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":126,"isActive":1,"name":"Single Xeon 1200 Series (Sandy Bridge \/ Haswell)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":132,"isActive":1,"name":"Virtual Rack Quad Xeon 7450 - SAS","unitSize":1},{"description":"RightScale XS CCI","firstOrderStepId":1,"id":135,"isActive":1,"name":"RightScale XS CCI","unitSize":1},{"description":"RightScale SM CCI","firstOrderStepId":1,"id":136,"isActive":1,"name":"RightScale SM CCI","unitSize":1},{"description":"RightScale MD CCI","firstOrderStepId":1,"id":137,"isActive":1,"name":"RightScale MD CCI","unitSize":1},{"description":"RightScale LG CCI","firstOrderStepId":1,"id":138,"isActive":1,"name":"RightScale LG CCI","unitSize":1},{"description":"RightScale XL CCI","firstOrderStepId":1,"id":139,"isActive":1,"name":"RightScale XL CCI","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":140,"isActive":1,"name":"Specialty Server: Mass Storage: QuantaStor","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":141,"isActive":1,"name":"Specialty Server: 4u Mass Storage: QuantaStor","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":142,"isActive":1,"name":"Single Xeon 2000 Series (Sandy Bridge)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Dual Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":143,"isActive":1,"name":"Dual Xeon 2000 Series (Sandy Bridge)","subDescription":"Dual Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: GPU<\/div>","firstOrderStepId":1,"id":144,"isActive":1,"name":"Specialty Server: GPU","subDescription":"Specialty Servers: GPU","unitSize":3},{"description":"
Intel Xeon 3460<\/div>","firstOrderStepId":1,"id":145,"isActive":1,"name":"Intel Xeon 3460","subDescription":"Intel Xeon 3460","unitSize":1},{"description":"
Sandy Bridge 1270<\/div>","firstOrderStepId":1,"id":146,"isActive":1,"name":"Sandy Bridge 1270","subDescription":"Sandy Bridge 1270","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":147,"isActive":1,"name":"Specialty Server: 4u Mass Storage Dual Xeon 2000 (Sandy Bridge) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":148,"isActive":1,"name":"Specialty Server: 2u Mass Storage Dual Xeon 2000 (Sandy Bridge) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":158,"isActive":1,"name":"Quad Xeon 4000 Series (Sandy Bridge)","subDescription":"Quad Processor Multi-core Servers","unitSize":4},{"description":"RightScale MD (High Mem) CCI","firstOrderStepId":1,"id":161,"isActive":1,"name":"RightScale MD (High Mem) CCI","unitSize":1},{"description":"ScaleRight LG (High Mem) Private CCI","firstOrderStepId":1,"id":162,"isActive":1,"name":"ScaleRight LG (High Mem) Private CCI","unitSize":1},{"description":"ScaleRight XS Private CCI","firstOrderStepId":1,"id":163,"isActive":1,"name":"ScaleRight XS Private CCI","unitSize":1},{"description":"ScaleRight SM Private CCI","firstOrderStepId":1,"id":164,"isActive":1,"name":"ScaleRight SM Private CCI","unitSize":1},{"description":"ScaleRight MD Private CCI","firstOrderStepId":1,"id":165,"isActive":1,"name":"ScaleRight MD Private CCI","unitSize":1},{"description":"ScaleRight LG Private CCI","firstOrderStepId":1,"id":166,"isActive":1,"name":"ScaleRight LG Private CCI","unitSize":1},{"description":"RightScale LG (High Mem) CCI","firstOrderStepId":1,"id":168,"isActive":1,"name":"RightScale LG (High Mem) CCI","unitSize":1},{"description":"ScaleRight MD (High Mem) Private CCI","firstOrderStepId":1,"id":169,"isActive":1,"name":"ScaleRight MD (High Mem) Private CCI","unitSize":1},{"firstOrderStepId":1,"id":173,"isActive":1,"name":"VHD Import","unitSize":1},{"description":"Network Gateway Appliance","firstOrderStepId":1,"id":174,"isActive":1,"name":"Network Gateway Appliance","subDescription":"Network Gateway Appliance","unitSize":1},{"firstOrderStepId":1,"id":192,"isActive":1,"name":"Application Delivery Appliance","subDescription":"Application Delivery Appliance","unitSize":null},{"firstOrderStepId":1,"id":194,"isActive":1,"name":"Load Balancers","subDescription":"Load Balancers","unitSize":null},{"firstOrderStepId":1,"id":196,"isActive":1,"name":"Network Gateway Appliance Cluster","unitSize":1},{"firstOrderStepId":1,"id":198,"isActive":1,"name":"Portable Storage","subDescription":"Portable Storage","unitSize":1},{"description":"Bare Metal Server","firstOrderStepId":1,"id":200,"isActive":1,"name":"Bare Metal Server","subDescription":"Bare Metal Server","unitSize":1},{"description":"POWER8 TULETA FOR WATSON","firstOrderStepId":1,"id":202,"isActive":1,"name":"POWER8 TULETA","unitSize":4},{"firstOrderStepId":1,"id":206,"isActive":1,"name":"Object Storage","subDescription":"Object Storage","unitSize":null},{"firstOrderStepId":1,"id":208,"isActive":1,"name":"Content Delivery Network","subDescription":"Content Delivery Network","unitSize":null},{"firstOrderStepId":1,"id":210,"isActive":1,"name":"SSL Certificate","subDescription":"SSL Certificate","unitSize":null},{"firstOrderStepId":1,"id":212,"isActive":1,"name":"Message Queue","subDescription":"Message Queue","unitSize":null},{"firstOrderStepId":1,"id":216,"isActive":1,"name":"Network Attached Storage","subDescription":"Network Attached Storage","unitSize":null},{"firstOrderStepId":1,"id":218,"isActive":1,"name":"iSCSI Storage","subDescription":"iSCSI Storage","unitSize":null},{"firstOrderStepId":1,"id":222,"isActive":1,"name":"Consistent Performance Storage","subDescription":"Consistent Performance Storage","unitSize":1},{"firstOrderStepId":1,"id":226,"isActive":1,"name":"Authentication Services","subDescription":"Authentication Services","unitSize":null},{"description":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","firstOrderStepId":1,"id":234,"isActive":1,"name":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","subDescription":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","unitSize":4},{"description":"Network Gateway Appliance (10 Gbps)","firstOrderStepId":1,"id":236,"isActive":1,"name":"Network Gateway Appliance (10 Gbps)","subDescription":"Network Gateway Appliance (10 Gbps)","unitSize":2},{"firstOrderStepId":1,"id":240,"isActive":1,"name":"'Codename: Prime' storage","unitSize":1},{"firstOrderStepId":null,"id":242,"isActive":1,"name":"POWER8 Servers","unitSize":null},{"firstOrderStepId":1,"id":244,"isActive":1,"name":"Monitoring","unitSize":null}] \ No newline at end of file diff --git a/getAllObjects.1 b/getAllObjects.1 deleted file mode 100644 index 9ee25c3dc..000000000 --- a/getAllObjects.1 +++ /dev/null @@ -1 +0,0 @@ -[{"firstOrderStepId":1,"id":0,"isActive":1,"name":"Additional Products","unitSize":null},{"firstOrderStepId":1,"id":10,"isActive":1,"name":"Control Panels for VPS","unitSize":null},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":32,"isActive":1,"name":"Quad Processor, Quad Core Intel","subDescription":"Quad Processor Multi-core Servers","unitSize":2},{"description":"
dual processor multi core<\/div>","firstOrderStepId":1,"id":35,"isActive":1,"name":"Dual Xeon (Dual Core) Woodcrest\/Cloverton - OUTLET","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":41,"isActive":1,"name":"Single Xeon 5500 Series (Nehalem)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Dual Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":42,"isActive":1,"name":"Dual Xeon 5500 Series (Nehalem)","subDescription":"Dual Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: Redundant Power<\/div>","firstOrderStepId":1,"id":43,"isActive":1,"name":"Specialty Server: Redundant Power: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Redundant Power","unitSize":2},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":44,"isActive":1,"name":"Specialty Server: Mass Storage: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"Virtual Server Instance","firstOrderStepId":1,"id":46,"isActive":1,"name":"Cloud Server","subDescription":"Virtual Server Instance","unitSize":1},{"description":"
Specialty Servers: Redundant Power<\/div>","firstOrderStepId":1,"id":49,"isActive":1,"name":"Specialty Server: 4u Redundant power Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Redundant Power","unitSize":4},{"firstOrderStepId":1,"id":50,"isActive":1,"name":"Bare Metal Instance","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":51,"isActive":1,"name":"Single Xeon 3400 Series (Lynnfield)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":52,"isActive":1,"name":"Specialty Server: 4u Mass Storage Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":53,"isActive":1,"name":"Specialty Server: Private Network: Single Xeon 3400 Series (Lynnfield)","subDescription":"Specialty Servers: Private Network","unitSize":1},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":54,"isActive":1,"name":"Specialty Server: Private Network: Dual Xeon 5500 Series (Nehalem)","subDescription":"Specialty Servers: Private Network","unitSize":1},{"description":"
Specialty Servers: Private Network<\/div>","firstOrderStepId":1,"id":55,"isActive":1,"name":"Specialty Server: Private Network & Redundant Power: Xeon 5500 (Nehalem) Series","subDescription":"Specialty Servers: Private Network","unitSize":2},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":56,"isActive":1,"name":"Quad Processor Multi Core Nehalem EX","subDescription":"Quad Processor Multi-core Servers","unitSize":2},{"description":"
Colocation Service<\/div>","firstOrderStepId":1,"id":58,"isActive":1,"name":"Colocation Service","unitSize":1},{"description":"ThePlanet Legacy Placeholder Package","firstOrderStepId":1,"id":60,"isActive":1,"name":"ThePlanet Legacy Placeholder Package","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":61,"isActive":1,"name":"Virtual Rack MD3000i SAN - HA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":62,"isActive":1,"name":"PC Dual Xeon 5130 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":63,"isActive":1,"name":"PC Dual Xeon 5130 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":64,"isActive":1,"name":"PR Dual Xeon 5520 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":65,"isActive":1,"name":"Virtual Rack Xeon 3210 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":66,"isActive":1,"name":"Virtual Rack Dual Xeon 5335 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":67,"isActive":1,"name":"PR Dual Xeon 5520 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":68,"isActive":1,"name":"PR Dual Xeon 5620 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":69,"isActive":1,"name":"PR Dual Xeon 5620 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":70,"isActive":1,"name":"Virtual Rack Dual Xeon 5620 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":71,"isActive":1,"name":"Virtual Rack Dual Xeon 5620 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":72,"isActive":1,"name":"PC Dual Xeon 5620 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":73,"isActive":1,"name":"PC Dual Xeon 5620 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":74,"isActive":1,"name":"Virtual Rack Dual Xeon 5660 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":75,"isActive":1,"name":"Virtual Rack Dual Xeon 5660 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":76,"isActive":1,"name":"PC Dual Xeon 5660 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":77,"isActive":1,"name":"PC Dual Xeon 5660 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":78,"isActive":1,"name":"Virtual Rack Quad Xeon 7550 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":79,"isActive":1,"name":"PC Quad Xeon 7550 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":80,"isActive":1,"name":"PR Xeon 3450 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":81,"isActive":1,"name":"PR Xeon 3450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":82,"isActive":1,"name":"Virtual Rack Pentium G6950 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":83,"isActive":1,"name":"PC Pentium G6950 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":84,"isActive":1,"name":"Virtual Rack MD1000 DAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":85,"isActive":1,"name":"Virtual Rack MD3000 DAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":86,"isActive":1,"name":"Virtual Rack MD3000 DAS - HA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":87,"isActive":1,"name":"PR Dual Xeon 5130 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":88,"isActive":1,"name":"PR Dual Xeon 5130 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":89,"isActive":1,"name":"PR Dual Xeon 5335 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":90,"isActive":1,"name":"PR Xeon 3060 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":91,"isActive":1,"name":"PR Xeon 3060 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":92,"isActive":1,"name":"PR Xeon 3210 - SATA","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":93,"isActive":1,"name":"PR Xeon 3210 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":94,"isActive":1,"name":"PC Dual Xeon 5335 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":95,"isActive":1,"name":"PC Dual Xeon 5335 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":96,"isActive":1,"name":"PC Dual Xeon 5405 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":97,"isActive":1,"name":"PC Dual Xeon 5405 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":98,"isActive":1,"name":"PC Dual Xeon 5405 - Monster","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":99,"isActive":1,"name":"PC Xeon 3360 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":100,"isActive":1,"name":"PC Xeon 3360 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":101,"isActive":1,"name":"PC Dual Xeon 5450 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":102,"isActive":1,"name":"PC Dual Xeon 5450 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":103,"isActive":1,"name":"PR Xeon 3040 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":104,"isActive":1,"name":"PC Xeon 3210 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":105,"isActive":1,"name":"PC Xeon 3210 - SAS","unitSize":1},{"description":"Private Rack","firstOrderStepId":1,"id":106,"isActive":1,"name":"PR Dual Xeon 5335 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":107,"isActive":1,"name":"Virtual Rack Xeon 3360 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":108,"isActive":1,"name":"Virtual Rack Xeon 3360 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":109,"isActive":1,"name":"Virtual Rack Dual Xeon 5450 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":110,"isActive":1,"name":"Virtual Rack Dual Xeon 5450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":111,"isActive":1,"name":"Virtual Rack Xeon 3210 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":112,"isActive":1,"name":"Virtual Rack Dual Xeon 5130 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":113,"isActive":1,"name":"Virtual Rack Dual Xeon 5335 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":114,"isActive":1,"name":"Virtual Rack Dual Xeon 5130 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":115,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":116,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":117,"isActive":1,"name":"Virtual Rack Dual Xeon 5405 - Monster","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":118,"isActive":1,"name":"PC Dual Xeon 5520 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":119,"isActive":1,"name":"PC Dual Xeon 5520 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":120,"isActive":1,"name":"Virtual Rack Dual Xeon 5520 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":121,"isActive":1,"name":"Virtual Rack Dual Xeon 5520 - SAS","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":122,"isActive":1,"name":"PC Xeon 3450 - SATA","unitSize":1},{"description":"Other (PC)","firstOrderStepId":1,"id":123,"isActive":1,"name":"PC Xeon 3450 - SAS","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":124,"isActive":1,"name":"Virtual Rack Xeon 3450 - SATA","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":125,"isActive":1,"name":"Virtual Rack Xeon 3450 - SAS","unitSize":1},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":126,"isActive":1,"name":"Single Xeon 1200 Series (Sandy Bridge \/ Haswell)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"Virtual Rack","firstOrderStepId":1,"id":132,"isActive":1,"name":"Virtual Rack Quad Xeon 7450 - SAS","unitSize":1},{"description":"RightScale XS CCI","firstOrderStepId":1,"id":135,"isActive":1,"name":"RightScale XS CCI","unitSize":1},{"description":"RightScale SM CCI","firstOrderStepId":1,"id":136,"isActive":1,"name":"RightScale SM CCI","unitSize":1},{"description":"RightScale MD CCI","firstOrderStepId":1,"id":137,"isActive":1,"name":"RightScale MD CCI","unitSize":1},{"description":"RightScale LG CCI","firstOrderStepId":1,"id":138,"isActive":1,"name":"RightScale LG CCI","unitSize":1},{"description":"RightScale XL CCI","firstOrderStepId":1,"id":139,"isActive":1,"name":"RightScale XL CCI","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":140,"isActive":1,"name":"Specialty Server: Mass Storage: QuantaStor","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":141,"isActive":1,"name":"Specialty Server: 4u Mass Storage: QuantaStor","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Single Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":142,"isActive":1,"name":"Single Xeon 2000 Series (Sandy Bridge)","subDescription":"Single Processor Multi-core Servers","unitSize":1},{"description":"
Dual Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":143,"isActive":1,"name":"Dual Xeon 2000 Series (Sandy Bridge)","subDescription":"Dual Processor Multi-core Servers","unitSize":1},{"description":"
Specialty Servers: GPU<\/div>","firstOrderStepId":1,"id":144,"isActive":1,"name":"Specialty Server: GPU","subDescription":"Specialty Servers: GPU","unitSize":3},{"description":"
Intel Xeon 3460<\/div>","firstOrderStepId":1,"id":145,"isActive":1,"name":"Intel Xeon 3460","subDescription":"Intel Xeon 3460","unitSize":1},{"description":"
Sandy Bridge 1270<\/div>","firstOrderStepId":1,"id":146,"isActive":1,"name":"Sandy Bridge 1270","subDescription":"Sandy Bridge 1270","unitSize":1},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":147,"isActive":1,"name":"Specialty Server: 4u Mass Storage Dual Xeon 2000 (Sandy Bridge) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":4},{"description":"
Specialty Servers: Mass Storage<\/div>","firstOrderStepId":1,"id":148,"isActive":1,"name":"Specialty Server: 2u Mass Storage Dual Xeon 2000 (Sandy Bridge) Series","subDescription":"Specialty Servers: Mass Storage","unitSize":2},{"description":"
Quad Processor Multi-core Servers<\/div>","firstOrderStepId":1,"id":158,"isActive":1,"name":"Quad Xeon 4000 Series (Sandy Bridge)","subDescription":"Quad Processor Multi-core Servers","unitSize":4},{"description":"RightScale MD (High Mem) CCI","firstOrderStepId":1,"id":161,"isActive":1,"name":"RightScale MD (High Mem) CCI","unitSize":1},{"description":"ScaleRight LG (High Mem) Private CCI","firstOrderStepId":1,"id":162,"isActive":1,"name":"ScaleRight LG (High Mem) Private CCI","unitSize":1},{"description":"ScaleRight XS Private CCI","firstOrderStepId":1,"id":163,"isActive":1,"name":"ScaleRight XS Private CCI","unitSize":1},{"description":"ScaleRight SM Private CCI","firstOrderStepId":1,"id":164,"isActive":1,"name":"ScaleRight SM Private CCI","unitSize":1},{"description":"ScaleRight MD Private CCI","firstOrderStepId":1,"id":165,"isActive":1,"name":"ScaleRight MD Private CCI","unitSize":1},{"description":"ScaleRight LG Private CCI","firstOrderStepId":1,"id":166,"isActive":1,"name":"ScaleRight LG Private CCI","unitSize":1},{"description":"RightScale LG (High Mem) CCI","firstOrderStepId":1,"id":168,"isActive":1,"name":"RightScale LG (High Mem) CCI","unitSize":1},{"description":"ScaleRight MD (High Mem) Private CCI","firstOrderStepId":1,"id":169,"isActive":1,"name":"ScaleRight MD (High Mem) Private CCI","unitSize":1},{"firstOrderStepId":1,"id":173,"isActive":1,"name":"VHD Import","unitSize":1},{"description":"Network Gateway Appliance","firstOrderStepId":1,"id":174,"isActive":1,"name":"Network Gateway Appliance","subDescription":"Network Gateway Appliance","unitSize":1},{"firstOrderStepId":1,"id":192,"isActive":1,"name":"Application Delivery Appliance","subDescription":"Application Delivery Appliance","unitSize":null},{"firstOrderStepId":1,"id":194,"isActive":1,"name":"Load Balancers","subDescription":"Load Balancers","unitSize":null},{"firstOrderStepId":1,"id":196,"isActive":1,"name":"Network Gateway Appliance Cluster","unitSize":1},{"firstOrderStepId":1,"id":198,"isActive":1,"name":"Portable Storage","subDescription":"Portable Storage","unitSize":1},{"description":"Bare Metal Server","firstOrderStepId":1,"id":200,"isActive":1,"name":"Bare Metal Server","subDescription":"Bare Metal Server","unitSize":1},{"description":"POWER8 TULETA FOR WATSON","firstOrderStepId":1,"id":202,"isActive":1,"name":"POWER8 TULETA","unitSize":4},{"firstOrderStepId":1,"id":206,"isActive":1,"name":"Object Storage","subDescription":"Object Storage","unitSize":null},{"firstOrderStepId":1,"id":208,"isActive":1,"name":"Content Delivery Network","subDescription":"Content Delivery Network","unitSize":null},{"firstOrderStepId":1,"id":210,"isActive":1,"name":"SSL Certificate","subDescription":"SSL Certificate","unitSize":null},{"firstOrderStepId":1,"id":212,"isActive":1,"name":"Message Queue","subDescription":"Message Queue","unitSize":null},{"firstOrderStepId":1,"id":216,"isActive":1,"name":"Network Attached Storage","subDescription":"Network Attached Storage","unitSize":null},{"firstOrderStepId":1,"id":218,"isActive":1,"name":"iSCSI Storage","subDescription":"iSCSI Storage","unitSize":null},{"firstOrderStepId":1,"id":222,"isActive":1,"name":"Consistent Performance Storage","subDescription":"Consistent Performance Storage","unitSize":1},{"firstOrderStepId":1,"id":226,"isActive":1,"name":"Authentication Services","subDescription":"Authentication Services","unitSize":null},{"description":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","firstOrderStepId":1,"id":234,"isActive":1,"name":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","subDescription":"Quad Xeon E7-4800 v2 (Ivy Bridge) Series","unitSize":4},{"description":"Network Gateway Appliance (10 Gbps)","firstOrderStepId":1,"id":236,"isActive":1,"name":"Network Gateway Appliance (10 Gbps)","subDescription":"Network Gateway Appliance (10 Gbps)","unitSize":2},{"firstOrderStepId":1,"id":240,"isActive":1,"name":"'Codename: Prime' storage","unitSize":1},{"firstOrderStepId":null,"id":242,"isActive":1,"name":"POWER8 Servers","unitSize":null},{"firstOrderStepId":1,"id":244,"isActive":1,"name":"Monitoring","unitSize":null}] \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 7f8d757bd..000000000 --- a/index.html +++ /dev/null @@ -1,31 +0,0 @@ -{ - "current_user_url": "https://api.github.com/user", - "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", - "authorizations_url": "https://api.github.com/authorizations", - "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", - "emails_url": "https://api.github.com/user/emails", - "emojis_url": "https://api.github.com/emojis", - "events_url": "https://api.github.com/events", - "feeds_url": "https://api.github.com/feeds", - "following_url": "https://api.github.com/user/following{/target}", - "gists_url": "https://api.github.com/gists{/gist_id}", - "hub_url": "https://api.github.com/hub", - "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", - "issues_url": "https://api.github.com/issues", - "keys_url": "https://api.github.com/user/keys", - "notifications_url": "https://api.github.com/notifications", - "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", - "organization_url": "https://api.github.com/orgs/{org}", - "public_gists_url": "https://api.github.com/gists/public", - "rate_limit_url": "https://api.github.com/rate_limit", - "repository_url": "https://api.github.com/repos/{owner}/{repo}", - "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", - "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", - "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", - "starred_gists_url": "https://api.github.com/gists/starred", - "team_url": "https://api.github.com/teams", - "user_url": "https://api.github.com/users/{user}", - "user_organizations_url": "https://api.github.com/user/orgs", - "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", - "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" -} diff --git a/index.html.1 b/index.html.1 deleted file mode 100644 index 7f8d757bd..000000000 --- a/index.html.1 +++ /dev/null @@ -1,31 +0,0 @@ -{ - "current_user_url": "https://api.github.com/user", - "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", - "authorizations_url": "https://api.github.com/authorizations", - "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", - "emails_url": "https://api.github.com/user/emails", - "emojis_url": "https://api.github.com/emojis", - "events_url": "https://api.github.com/events", - "feeds_url": "https://api.github.com/feeds", - "following_url": "https://api.github.com/user/following{/target}", - "gists_url": "https://api.github.com/gists{/gist_id}", - "hub_url": "https://api.github.com/hub", - "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", - "issues_url": "https://api.github.com/issues", - "keys_url": "https://api.github.com/user/keys", - "notifications_url": "https://api.github.com/notifications", - "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", - "organization_url": "https://api.github.com/orgs/{org}", - "public_gists_url": "https://api.github.com/gists/public", - "rate_limit_url": "https://api.github.com/rate_limit", - "repository_url": "https://api.github.com/repos/{owner}/{repo}", - "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", - "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", - "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", - "starred_gists_url": "https://api.github.com/gists/starred", - "team_url": "https://api.github.com/teams", - "user_url": "https://api.github.com/users/{user}", - "user_organizations_url": "https://api.github.com/user/orgs", - "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", - "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" -} diff --git a/index.html.2 b/index.html.2 deleted file mode 100644 index 7f8d757bd..000000000 --- a/index.html.2 +++ /dev/null @@ -1,31 +0,0 @@ -{ - "current_user_url": "https://api.github.com/user", - "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", - "authorizations_url": "https://api.github.com/authorizations", - "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", - "emails_url": "https://api.github.com/user/emails", - "emojis_url": "https://api.github.com/emojis", - "events_url": "https://api.github.com/events", - "feeds_url": "https://api.github.com/feeds", - "following_url": "https://api.github.com/user/following{/target}", - "gists_url": "https://api.github.com/gists{/gist_id}", - "hub_url": "https://api.github.com/hub", - "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", - "issues_url": "https://api.github.com/issues", - "keys_url": "https://api.github.com/user/keys", - "notifications_url": "https://api.github.com/notifications", - "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", - "organization_url": "https://api.github.com/orgs/{org}", - "public_gists_url": "https://api.github.com/gists/public", - "rate_limit_url": "https://api.github.com/rate_limit", - "repository_url": "https://api.github.com/repos/{owner}/{repo}", - "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", - "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", - "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", - "starred_gists_url": "https://api.github.com/gists/starred", - "team_url": "https://api.github.com/teams", - "user_url": "https://api.github.com/users/{user}", - "user_organizations_url": "https://api.github.com/user/orgs", - "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", - "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" -} From 8e39ecb020a413e5446e41d478b93ad94f913f75 Mon Sep 17 00:00:00 2001 From: Celso Fernandes Date: Sun, 8 Feb 2015 21:35:09 -0200 Subject: [PATCH 101/472] [pt_br] Fix links on TOC --- content/pt_br/toc.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index 0b8c0a450..fd0f61234 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -1,38 +1,38 @@ The Twelve Factors ================== -## [I. Base de Código](/codebase) +## [I. Base de Código](./codebase) ### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys -## [II. Dependências](/dependencies) +## [II. Dependências](./dependencies) ### Declare e isole as dependências -## [III. Configurações](/config) +## [III. Configurações](./config) ### Armazene as configurações no ambiente -## [IV. Serviços de Apoio](/backing-services) +## [IV. Serviços de Apoio](./backing-services) ### Trate os serviços de apoio, como recursos ligados -## [V. Build, release, run](/build-release-run) +## [V. Build, release, run](./build-release-run) ### Separe estritamente os builds e execute em estágios -## [VI. Processos](/processes) +## [VI. Processos](./processes) ### Execute a aplicação como um ou mais processos que não armazenam estado -## [VII. Ligação de porta](/port-binding) +## [VII. Ligação de porta](./port-binding) ### Exporte serviços por ligação de porta -## [VIII. Concorrência](/concurrency) +## [VIII. Concorrência](./concurrency) ### Dimensione por um modelo de processo -## [IX. Disponibilidade](/disposability) +## [IX. Disponibilidade](./disposability) ### Maximizar a robustez com inicialização e desligamento rápido -## [X. Dev/prod semelhantes](/dev-prod-parity) +## [X. Dev/prod semelhantes](./dev-prod-parity) ### Mantenha o desenvolvimento, teste, produção o mais semelhante possível -## [XI. Logs](/logs) +## [XI. Logs](./logs) ### Trate logs como fluxo de eventos -## [XII. Procesos de Admin](/admin-processes) +## [XII. Procesos de Admin](./admin-processes) ### Executar tarefas de administração/gerenciamento como processos pontuais From 895cd3165075b6c0b8f1383fa4d6209dcb67c208 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Sun, 8 Feb 2015 23:39:10 -0200 Subject: [PATCH 102/472] Translates backing-services into pt-br. Closes #13 --- content/pt_br/backing-services.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/pt_br/backing-services.md diff --git a/content/pt_br/backing-services.md b/content/pt_br/backing-services.md new file mode 100644 index 000000000..1a6ce82d8 --- /dev/null +++ b/content/pt_br/backing-services.md @@ -0,0 +1,14 @@ +## IV. Serviços de Apoio +### Trate serviços de apoio como recursos anexados + +Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). + +Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). + +**O código para um app doze-fatores não faz distinção entre serviços locais e de terceiros.** Para o app, ambos são recursos anexados, acessíveis via uma URL ou outro localizador/credenciais na [config](./config). Um [deploy](./codebase) do app doze-fatores deve ser ser capaz de trocar um banco de dados MySQL por um gerenciado por terceiros (tais como [Amazon RDS](http://aws.amazon.com/rds/)) sem realizar quaisquer mudanças no código do app. Da mesma forma, um servidor local SMTP poderia ser trocado por um serviço de terceiros (tais como Postmark) sem as mudanças em código. Em ambos os casos, apenas o identificador de recurso precisa mudar. + +Cada serviço de apoio distinto é um *recurso*. Por exemplo, um banco MySQL é um recurso; dois bancos MySQL (usados para sharding na camada da aplicação) qualificam como dois recursos distintos. O app doze-fatores trata tais bancos como *recursos anexados*, o que indica seu baixo acoplamento ao deploy que ele está anexado. + +Um deploy de produção anexado a quatro serviços de apoio. + +Recursos podem ser anexados e desanexados a deploys à vontade. Por exemplo, se o banco de dados do app não está funcionando corretamente devido a um problema de hardware, o administrador do app pode subir um novo servidor de banco de dados restaurado de um backup recente. O atual banco de produção por ser desanexado, e o novo banco anexado -- tudo sem nenhuma mudança no código. From 0787a129b7fc28d5d24128e9ca41679afb3544a8 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Thu, 19 Feb 2015 14:03:54 -0200 Subject: [PATCH 103/472] Translating port-binding to pt-br. Closes #21 --- content/pt_br/port-binding.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/pt_br/port-binding.md diff --git a/content/pt_br/port-binding.md b/content/pt_br/port-binding.md new file mode 100644 index 000000000..ae3e0bf26 --- /dev/null +++ b/content/pt_br/port-binding.md @@ -0,0 +1,14 @@ +## 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://jetty.codehaus.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. From ab05c4b0295d61b3ae55989c57ed751a549e2b30 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Fri, 20 Feb 2015 15:32:02 -0200 Subject: [PATCH 104/472] =?UTF-8?q?Alterando=20TOC=20para=20tradu=C3=A7?= =?UTF-8?q?=C3=A3o=20escolhida=20do=20Port=20Binding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index fd0f61234..0f1026580 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -19,7 +19,7 @@ The Twelve Factors ## [VI. Processos](./processes) ### Execute a aplicação como um ou mais processos que não armazenam estado -## [VII. Ligação de porta](./port-binding) +## [VII. Vínculo de porta](./port-binding) ### Exporte serviços por ligação de porta ## [VIII. Concorrência](./concurrency) From dcc9191e21df63dfb541c4bc3b8db5369d3e03db Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Fri, 20 Feb 2015 15:37:01 -0200 Subject: [PATCH 105/472] Adding original english files for translation --- content/pt_br/admin-processes.md | 14 ++++++ content/pt_br/build-release-run.md | 19 ++++++++ content/pt_br/concurrency.md | 14 ++++++ content/pt_br/config.md | 23 +++++++++ content/pt_br/dev-prod-parity.md | 76 ++++++++++++++++++++++++++++++ content/pt_br/disposability.md | 14 ++++++ content/pt_br/logs.md | 16 +++++++ content/pt_br/processes.md | 15 ++++++ 8 files changed, 191 insertions(+) create mode 100644 content/pt_br/admin-processes.md create mode 100644 content/pt_br/build-release-run.md create mode 100644 content/pt_br/concurrency.md create mode 100644 content/pt_br/config.md create mode 100644 content/pt_br/dev-prod-parity.md create mode 100644 content/pt_br/disposability.md create mode 100644 content/pt_br/logs.md create mode 100644 content/pt_br/processes.md diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/pt_br/admin-processes.md @@ -0,0 +1,14 @@ +## 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. diff --git a/content/pt_br/build-release-run.md b/content/pt_br/build-release-run.md new file mode 100644 index 000000000..a7215b0a1 --- /dev/null +++ b/content/pt_br/build-release-run.md @@ -0,0 +1,19 @@ +## V. Build, release, run +### Strictly separate build and run stages + +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: + +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) + +**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. + +Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. + +Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. + +Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. + diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md new file mode 100644 index 000000000..5ae4706b9 --- /dev/null +++ b/content/pt_br/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrency +### Scale out via the process model + +Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. + +![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) + +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. + +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. + +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. + +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/pt_br/config.md b/content/pt_br/config.md new file mode 100644 index 000000000..2d2ff384b --- /dev/null +++ b/content/pt_br/config.md @@ -0,0 +1,23 @@ +## III. Config +### Store config in the environment + +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: + +* Resource handles to the database, Memcached, and other [backing services](./backing-services) +* Credentials to external services such as Amazon S3 or Twitter +* Per-deploy values such as the canonical hostname for the deploy + +Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. + +A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. + +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). This type of config does not vary between deploys, and so is best done in the code. + +Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. + +**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. + +Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. + +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments," but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. + diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md new file mode 100644 index 000000000..f6e573342 --- /dev/null +++ b/content/pt_br/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod parity +### Keep development, staging, and production as similar as possible + +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: + +* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The personnel gap**: Developers write code, ops engineers deploy it. +* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. + +**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: + +* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. +* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. +* Make the tools gap small: keep development and production as similar as possible. + +Summarizing the above into a table: + +
+ + + + + + + + + + + + + + + + + + + + +
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
+ +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. + +**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. + +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. + +Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/pt_br/disposability.md b/content/pt_br/disposability.md new file mode 100644 index 000000000..085f2d721 --- /dev/null +++ b/content/pt_br/disposability.md @@ -0,0 +1,14 @@ +## 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](http://kr.github.com/beanstalkd/), 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). + + diff --git a/content/pt_br/logs.md b/content/pt_br/logs.md new file mode 100644 index 000000000..ab2f4f829 --- /dev/null +++ b/content/pt_br/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Treat logs as event streams + +*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. + +Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md new file mode 100644 index 000000000..dd13c37f2 --- /dev/null +++ b/content/pt_br/processes.md @@ -0,0 +1,15 @@ +## VI. Processes +### Execute the app as one or more stateless processes + +The app is executed in the execution environment as one or more *processes*. + +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). + +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. + +The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. + +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. + +Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). + From 49ae0286ad72a6d04ec8180a78aa42faa7fb0847 Mon Sep 17 00:00:00 2001 From: Alessandro Minali Date: Wed, 25 Feb 2015 12:50:22 -0500 Subject: [PATCH 106/472] fixed dead link --- content/en/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/processes.md b/content/en/processes.md index dd13c37f2..2a6df3419 100644 --- a/content/en/processes.md +++ b/content/en/processes.md @@ -9,7 +9,7 @@ In the simplest case, the code is a stand-alone script, the execution environmen The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). From f41dc38767b28cfc06ee2a33c8b9d524e3c371d7 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 26 Feb 2015 11:25:02 +0000 Subject: [PATCH 107/472] fix link in translations --- content/ja/processes.md | 2 +- content/zh_cn/processes.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ja/processes.md b/content/ja/processes.md index 6592c8a8d..44e1a7230 100644 --- a/content/ja/processes.md +++ b/content/ja/processes.md @@ -9,6 +9,6 @@ プロセスのメモリ空間やファイルシステムは、短い単一のトランザクション内でのキャッシュとして利用してもよい。例えば、大きなファイルをダウンロードし、そのファイルを処理し、結果をデータベースに格納するという一連の処理において、ファイルシステムをキャッシュとして利用できる。Twelve-Factor Appは、メモリやディスクにキャッシュされたものが将来のリクエストやジョブにおいて利用できることを決して仮定しない -- それぞれのプロセスタイプのプロセスが多く実行されている場合、将来のリクエストやジョブが別のプロセスで処理される可能性が高い。1つのプロセスしか実行されていない場合であっても、プロセスが再起動すると、すべての局所的な状態(メモリやファイルシステムなど)が消えてしまうことがある。プロセスの再起動の要因としては、コードのデプロイ、設定の変更、プロセスを別の物理位置に再配置する実行環境などがある。 -アセットパッケージャー(例:[Jammit](http://documentcloud.github.com/jammit/) や [django-assetpackager](http://code.google.com/p/django-assetpackager/))は、コンパイルされたアセットをキャッシュするためにファイルシステムを利用する。Twelve-Factor Appは、このコンパイル処理を実行時に行うよりも、[Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html)のように[ビルドステージ](./build-release-run)で行うほうが、望ましいと考えている。 +アセットパッケージャー(例:[Jammit](http://documentcloud.github.com/jammit/) や [django-assetpackager](http://code.google.com/p/django-assetpackager/))は、コンパイルされたアセットをキャッシュするためにファイルシステムを利用する。Twelve-Factor Appは、このコンパイル処理を実行時に行うよりも、[Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)のように[ビルドステージ](./build-release-run)で行うほうが、望ましいと考えている。 Webシステムの中には、[“スティッキーセッション”](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)に頼るものがある -- これはユーザーのセッションデータをアプリケーションプロセスのメモリにキャッシュし、同じ訪問者からの将来のリクエストが同じプロセスに送られることを期待するものである。スティッキーセッションはTwelve-Factorに違反しており、決して使ったり頼ったりしてはならない。セッション状態のデータは、有効期限を持つデータストア(例:[Memcached](http://memcached.org/) や [Redis](http://redis.io/))に格納すべきである。 diff --git a/content/zh_cn/processes.md b/content/zh_cn/processes.md index adde52e77..a53facdba 100644 --- a/content/zh_cn/processes.md +++ b/content/zh_cn/processes.md @@ -9,6 +9,6 @@ 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://ryanbigg.com/guides/asset_pipeline.html) ,而不是在运行阶段。 +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://guides.rubyonrails.org/asset_pipeline.html) ,而不是在运行阶段。 一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如 [Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 From fea8a007cac745e38b59ef18fc47606f64f352c9 Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:11:19 +0900 Subject: [PATCH 108/472] translated to korean --- content/ko/admin-processes.md | 15 +++++++ content/ko/background.md | 9 ++++ content/ko/backing-services.md | 15 +++++++ content/ko/build-release-run.md | 19 ++++++++ content/ko/codebase.md | 17 +++++++ content/ko/concurrency.md | 14 ++++++ content/ko/config.md | 22 ++++++++++ content/ko/dependencies.md | 12 +++++ content/ko/dev-prod-parity.md | 78 +++++++++++++++++++++++++++++++++ content/ko/disposability.md | 12 +++++ content/ko/intro.md | 12 +++++ content/ko/logs.md | 16 +++++++ content/ko/port-binding.md | 14 ++++++ content/ko/processes.md | 14 ++++++ content/ko/toc.md | 38 ++++++++++++++++ content/ko/who.md | 4 ++ locales/ko.yaml | 7 +++ 17 files changed, 318 insertions(+) create mode 100644 content/ko/admin-processes.md create mode 100644 content/ko/background.md create mode 100644 content/ko/backing-services.md create mode 100644 content/ko/build-release-run.md create mode 100644 content/ko/codebase.md create mode 100644 content/ko/concurrency.md create mode 100644 content/ko/config.md create mode 100644 content/ko/dependencies.md create mode 100644 content/ko/dev-prod-parity.md create mode 100644 content/ko/disposability.md create mode 100644 content/ko/intro.md create mode 100644 content/ko/logs.md create mode 100644 content/ko/port-binding.md create mode 100644 content/ko/processes.md create mode 100644 content/ko/toc.md create mode 100644 content/ko/who.md create mode 100644 locales/ko.yaml diff --git a/content/ko/admin-processes.md b/content/ko/admin-processes.md new file mode 100644 index 000000000..952f86138 --- /dev/null +++ b/content/ko/admin-processes.md @@ -0,0 +1,15 @@ +## XII. Admin 프로세스 +### admin/maintenance 작업을 일회성 프로세스로 실행 + +[프로세스 포메이션](./concurrency)은 애플리케이션의 일반적인 기능들(예: Web request의 처리)을 처리하기 위한 프로세스들의 집합 입니다. 이와는 별도로, 개발자들은 종종 일회성 관리나 유지 보수 작업을 하고 싶어집니다. 그 예는 아래와 같습니다. + +* 데이터베이스 마이그레이션을 실행합니다. (예: Django에서 `manage.py migrate`, Rail에서 `rake db:migrate`) +* 임의의 코드를 실행하거나 라이브 데이터베이스에서 앱의 모델을 조사하기 위해 콘솔([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) Shell로도 알려져 있는)을 실행한다. 대부분의 언어에서는 인터프리터를 아무런 인자 없이 실행하거나(예: python, perl) 별도의 명령어로 실행(예: ruby의 irb, rails의 rails console)할 수 있는 REPL를 제공합니다. +* 애플리케이션 저장소에 커밋된 일회성 스크립트의 실행 (예: php scripts/fix_bad_records.php) + +일회성 admin 프로세스는 애플리케이션의 일반적인 [오래 실행되는 프로세스](./processes)들과 동일한 환경에서 실행되어야 합니다. 일회성 admin 프로세스들은 릴리즈를 기반으로 실행되며, 해당 릴리즈를 기반으로 돌아가는 모든 프로세스처럼 같은 [코드베이스](./codebase)와 [설정](./config)를 사용해야 합니다. admin 코드는 동기화 문제를 피하기 위해 애플리케이션 코드와 함께 배포되어야 합니다. + +모든 종류 프로세스는 같은 [종속성](./dependencies)을 가져야 합니다. 예를 들어, +루비 웹 프로세스가 `bundle exec thin start` 명령어를 사용한다면, 데이터베이스 마이그레이션은 `bundle exec rake db:migrate`를 사용해야합니다. 마찬가지로, virtualenv를 사용하는 파이썬 프로그램은 tornado 웹 서버와 모든 `manage.py` admin 프로세스가 같은 virtualenv에서의 `bin/python`을 사용해야 합니다. + +Twelve-Factor는 별도의 설치나 구성없이 REPL shell을 제공하는 언어를 강하게 선호합니다. 이러한 점은 일회성 스크립트를 실행하기 쉽게 만들어주기 때문입니다. 로컬 배포에서, 개발자는 앱을 체크아웃한 디렉토리에서 일회성 admin 프로세스를 shell 명령어로 바로 실행시킵니다. production 배포에서, 개발자는 ssh나 배포의 실행 환경에서 제공하는 다른 원격 명령어 실행 메커니즘을 사용하여 admin 프로세스를 실행할 수 있습니다. \ No newline at end of file diff --git a/content/ko/background.md b/content/ko/background.md new file mode 100644 index 000000000..1bb9903f9 --- /dev/null +++ b/content/ko/background.md @@ -0,0 +1,9 @@ +배경 +========== + +이 문서에 대한 기여자들은 수백개의 애플리케이션 개발과 배포에 직접적으로 참여했으며, [Heroku](http://www.heroku.com/) 플랫폼에서의 작업을 통해 방대한 양의 애플리케이션 개발, 운영, 확장을 간접적으로 관찰했습니다. + +이 문서는 생태계의 다양한 SaaS 애플리케이션에 대한 저희의 경험과 관찰을 종합한 결과물입니다. 특히 응용프로그램의 시간이 지남에 따른 유기적인 성장, 애플리케이션의 코드베이스에서 작업하는 개발자들 간의 협업, [소프트웨어가 낡는 것에 의한 비용을 피하는 법](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)에 집중하여 애플리케이션 개발에 대한 이상적인 방법을 찾고자 했습니다. + + +이 문서는 저희가 현대적인 애플리케이션 개발에서 만났던 몇가지 시스템적인 문제에 대한 인지도를 높히고, 이 문제들에 대해 논의를 하기 위한 공통의 어휘를 제공하며, 이 문제들에 대한 넓은 개념의 해결책과 그에 대한 용어를 제공하기 위해 작성 되었습니다. 형식은 Martin Fowler의 책, *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)*과 *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*에서 영감을 받았습니다. \ No newline at end of file diff --git a/content/ko/backing-services.md b/content/ko/backing-services.md new file mode 100644 index 000000000..901265ba9 --- /dev/null +++ b/content/ko/backing-services.md @@ -0,0 +1,15 @@ +## IV. 백엑드 서비스 +### 백엔드 서비스를 연결된 리소스로 취급 + +* 백엔드 서비스*는 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스입니다. 예를 들어, 데이터 저장소(예: [MySQL](http://dev.mysql.com/), [CouchDB](http://couchdb.apache.org/)), 메시지 큐잉 시스템(예: [RabbitMQ](http://www.rabbitmq.com/), [Beanstalkd](http://kr.github.com/beanstalkd/)), 메일을 보내기 위한 SMTP 서비스 (예: [Postfix](http://www.postfix.org/)), 캐시 시스템(예: [Memcached](http://memcached.org/)) 등이 있습니다. + +데이터 저장소와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))등이 있습니다. + +** Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다. ** 애플리케이션에게는 양 쪽 모두 연결된 리소이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. + +각각의 다른 백엔드 서비스는 *리소스*입니다. 예를 들어, 하나의 MySQL DB는 하나의 리소스입니다. 애플리케이션 레이어에서 샤딩을 하는 두 개의 MySQL 데이터베이스는 두 개의 서로 다른 리소스라고 볼 수 있습니다. Twelve-Factor App은 이러한 데이터베이스들을 *첨부된(Attached) 리소스*으로 다룹니다. 이는 서로 느슨하게 결합된다는 점을 암시합니다. + + +4개의 백엔드 서비스가 연결된 production 배포. + +리소스는 자유롭게 배포에 연결되거나 분리될 수 있습니다. 예를 들어, 애플리케이션의 데이터베이스가 하드웨어 이슈로 작용이 이상한 경우, 애플리케이션의 관리자는 최신 백업에서 새로운 데이터베이스 서버를 시작시킬 것입니다. 그리고 코드를 전혀 수정하지 않고 현재 운영에 사용하고 있는 데이터베이스를 분리하고 새로운 데이터베이스를 연결할 수 있습니다. \ No newline at end of file diff --git a/content/ko/build-release-run.md b/content/ko/build-release-run.md new file mode 100644 index 000000000..db21080f9 --- /dev/null +++ b/content/ko/build-release-run.md @@ -0,0 +1,19 @@ +## V. 빌드, 릴리즈, 실행 +### 철저하게 분리된 빌드와 실행 단계 + +[코드베이스](./codebase)는 3 단계를 거쳐 (개발용이 아닌) 배포로 변환됩니다. + +* *빌드 단계*는 코드 저장소를 코드 저장소를 *빌드*라는 실행 가능한 번들로 변환시키는 단계입니다. 빌드 단계에서는 커밋된 코드 중 배포 프로세스에서 지정된 버전을 사용하며, [종속성](./dependencies)를 가져와 바이너리와 에셋들을 컴파일합니다. +* *릴리즈 단계*에서는 빌드 단계에서 만들어진 빌드와 배포의 현재 [설정](./config)을 결합 합니다. 완성된 *릴리즈*는 빌드와 설정을 모두 포함하며 실행 환경에서 바로 실행될 수 있다도록 준비됩니다. +* *실행 단계*(런타임이라고도 하는)에서는 선택된 릴리즈에 대한 애플리케이션 [프로세스](./processes)의 집합을 시작하여, 애플리케이션을 실행 환경에서 돌아가도록 합니다. + + +![코드 베이스는 빌드가 되고, 빌드는 설정과 조합되어 릴리즈가 됩니다.](/images/release.png) + +** Twelve-Factor App은 빌드, 릴리즈, 실행 단계를 엄격하게 서로 분리합니다.** 예를 들어, 실행 단계에서 코드를 변경할 수는 없습니다. 변경을 실행 단계보다 앞에 있는 빌드 단계로 전달할 수 있는 방법이 없기 때문입니다. + +배포 도구는 일반적으로 릴리즈 관리 도구를 제공합니다. 특히 주목할만한 점은 이전 릴리즈로 되돌릴 수 있는 롤백 기능입니다. 예를 들어, [Capistrano](https://github.com/capistrano/capistrano/wiki)는 배포 툴은 릴리즈를 `releases`라는 하위 디렉토리에 저장시키고, 현재 릴리즈는 현재 릴리즈 디렉토리로 심볼릭 링크로 연결합니다. 이 툴의 `rollback` 명령어는 이전 버전으로 쉽고 빠르게 이전 릴리즈로 롤백할 수 있도록 해줍니다. + +모든 릴리즈는 항상 유니크한 릴리즈 아이디를 지녀야 합니다. 예를 들어, 릴리즈의 타임 스템프(예: 2011-04-06-20:32:17)나 증가하는 번호(예: v100, v101)가 있습니다. 릴리즈는 추가만 될 수 있으며, 한번 만들어진 릴리즈는 변경될 수 없습니다. 모든 변경은 새로운 릴리즈를 만들어야 합니다. + +빌드는 새로운 코드가 배포 될 때마다 개발자에 의해 시작됩니다. 반면, 실행 단계는 서버가 재부팅되거나 충돌이 발생한 프로세스가 프로세스 매니저에 의해 재시작 되었을 때 자동으로 실행될 수 있습니다. 따라서 대응할 수 있는 개발자가 없는 한밤중에 문제가 발생하는 것을 방지하기 위해, 실행 단계는 최대한 변화가 적어야합니다. 빌드 단계는 좀 더 복잡해져도 괜찮습니다. 항상 배포를 진행하고 있는 개발자의 눈 앞에서 에러가 발생하기 때문입니다. diff --git a/content/ko/codebase.md b/content/ko/codebase.md new file mode 100644 index 000000000..1db1bb3fd --- /dev/null +++ b/content/ko/codebase.md @@ -0,0 +1,17 @@ +## I. 코드베이스 +### 버전 관리되는 하나의 코드베이스와 다양한 배포 + +Twelve-Factor App은 항상 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/) 등의 버전 컨트롤 시스템을 사용하여 변화를 추적합니다. 수정 추적 데터베이스의 복사본은 *코드 저장소*라고 부르며, 짧게는 *저장소*라고도 합니다. + +*코드베이스*는 하나의 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우), 혹은 하나의 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)입니다. + +![하나의 코드베스는 여러 배포로 매핑됩니다.](/images/codebase-deploys.png) + +코드베이스와 애플리케이션 사이에는 항상 1대1 관계가 성립됩니다. + +* 여러 코드베이스가 있는 경우, 그 것은 애플리케이션이 아닙니다 - 그 것은 분산 시스템입니다. 분산 시스템의 각 구성 요소는 애플리케이션이며, 개별적으로는 Twelve-Factor에 따르고 있을 수 있습니다. +* 하나의 코드를 공유하는 여러개의 앱은 Twelve-Factor를 위반합니다. 해결책은 공유되는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](/dependencies)에 통합시키는 것입니다. + +애플리케이션 하나에는 오직 하나의 코드베이스가 존재하지만, 응용 프로그램의 배포는 여러개 존재합니다. 하나의 *배포*는 애플리케이션의 하나의 실행 중인 인스턴스 입니다. 이것은 일반적으로 하나의 production 공간과 하나 이상의 staging 공간입니다. 또한 모든 개발자는 자신의 로컬 개발 환경에 실행되는 애플리케이션 을 가지고 있으며, 이 것 역시 각각 하나의 배포로 볼 수 있습니다. + +각 배포는 다른 버전이 활성화 되어있을 수도 있지만, 코드베이스는 모든 배포에 대해 동일합니다. 예를 들어, 개발자는 아직 staging 환경에 배포하지 않은 커밋을 가지고 있을 수 있으며, staging 환경에는 아직 production 환경에 배포되지 않은 커밋이 있을 수 있습니다. 하지만, 이런 모든 것들이 같은 코드베이스를 공유하고 있고, 같은 애플리케이션의 다른 배포라고 할 수 있습니다. \ No newline at end of file diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md new file mode 100644 index 000000000..466e092ee --- /dev/null +++ b/content/ko/concurrency.md @@ -0,0 +1,14 @@ +## VIII. 동시성(Concurrency) +### 프로세스 모델을 통한 확장 + +모든 컴퓨터 프로그램은 실행되면 하나 이상의 프로세스로 표현됩니다. 웹 애플리케이션은 다양한 프로세스 실행 형태를 취해왔습니다. 예를 들어, PHP 프로세스는 Apache의 자식 프로세스로 실행되며, request의 양에 따라 필요한 만큼 시작됩니다. 자바 프로세스들은 반대 방향에서의 접근법을 취합니다. JVM은, 시작될 때 큰 시스템 리소스(CPU와 메모리) 블록을 예약하는 하나의 거대한 부모 프로세스를 제공하고, 내부 쓰레드를 통해 동시성(concurrency)을 관리합니다. 두 경우 모두 실행되는 프로세스는 애플리케이션 개발자에게 최소한으로 노출됩니다. + +![Scale는 실행되는 프로세스의 갯수로 표현되고, Workload Diversity는 프로세스의 타입으로 표현됩니다. ](/images/process-types.png) + +**Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션이 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. + +이는 런타임 VM 내부의 쓰레드나 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. + +프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](.processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. + +Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [Upstart](http://upstart.ubuntu.com/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. \ No newline at end of file diff --git a/content/ko/config.md b/content/ko/config.md new file mode 100644 index 000000000..c2c946b68 --- /dev/null +++ b/content/ko/config.md @@ -0,0 +1,22 @@ +## III. 설정 +### 환경(environment)에 저장된 설정 + +애플리케이션의 *설정*은 [배포](./codebase) (staging, production, 개발 환경 등) 마다 달라질 수 있는 모든 것들입니다. 설정에는 다음이 포함됩니다. + +* 데이터베이스, memcached 등 [백엔드 서비스](./backing-services)들의 리소스 핸들 +* Amazon S3 이나 트위터 등의 외부 서비스 인증 정보 +* 배포된 호스트의 정규화된 호스트 이름(canonical hostname)처럼 각 배포마다 달라지는 값 + +애플리케이션은 종종 설정을 상수로 코드에 저장합니다. 이것은 Twelve-Factor를 위한하며, Twelve-Factor는 **설정을 코드에서 엄격하게 분리하는 것**을 요구합니다. 설정은 배치마다 크게 다르지만, 코드는 그렇지 않습니다. + +애플리케이션의 모든 설정이 정상적으로 코드 바깥으로 분리되어 있는지 확인할 수 있는 간단한 테스트는 어떠한 인증정보도 유출시키지 않고 코드베이스가 지금 당장 오픈 소스가 될 수 있는지 확인하는 것입니다. + +이 "설정"의 정의는 애플리케이션 내부 설정을 *포함하지 않는다는 점*에 유의해야 합니다. Rails의 `config/routes.rb`이나 [Spring](http://www.springsource.org/)의 ["어떻게 코드 모듈이 연결되는 가](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html)과 같은 설정들은 배치 사이에서 변하지 않기 때문에 코드의 내부에 있는 것이 가장 좋습니다. + +설정에 대한 또 다른 접근방식은 Rails의 `config/database.yaml`처럼 버전 관리 시스템에 등록되지 않은 설정 파일을 이용하는 것입니다. 이 방법은 코드 저장소에 등록된 상수를 사용하는 것에 비하면 매우 큰 발전이지만, 설정 파일이 여러 위치에 여러 포맷으로 흝어지고 모든 설정을 한 곳에서 확인하고 관리하기 어렵게 만드는 경향이 있습니다. 게다가, 이러한 형식들은 언어와 프레임워크을 따라가는 경향이 있습니다. + +**Twelve-Factor App은 설정을 *환경 변수*** (envvars나 env라고도 불림)에 저장합니다. 환경 변수는 코드 변경 없이 쉽게 배포 떄마다 쉽게 변경할 수 있습니다. 설정 파일과 달리, 잘못해서 코드 저장소에 올라갈 가능성도 낮습니다. 또한, 커스텀 설정 파일이나 Java System Property와 같은 다른 설정 매커니즘과 달리 언어나 OS에 의존하지 않는 표준입니다. + +설정 관리의 다른 측면은 그룹핑입니다. 종종 애플리케이션은 설정을 명명된 그룹("environments"라고도 함)으로 구성하기도 합니다. 해당 그룹은 Rails의 'development', 'test', 'production' environments처럼, 배포의 이름을 따서 명명됩니다. 이 방법은 깔끔하게 확장하기 어렵습니다. 응용 프로그램의 배포가 증가함에 따라, 'staging'이라던가 'qa'같은 새로운 그룹의 이름이 필요하게 됩니다. 프로젝트가 성장함에 따라, 개발자은 자기 자신의 그룹를 추가하게 됩니다. 결과적으로 설정이 각 그룹의 조합으로 폭발하게 되고, 애플리케이션의 배포를 불안정하게 만듭니다. + +Twelve-Factor App에서 환경 변수는 매우 정교한 관리이며, 각각의 환경변수는 서로 직교합니다. 환경 변수는 "environments"로 절대 그룹으로 묶이지 않지만, 대신 각 배포마다 독립적으로 관리됩니다. 이 모델은 애플리케이션의 수명주기를 거치는 동안 더 많은 배포로 원활하게 확장해 나갈 수 있습니다. \ No newline at end of file diff --git a/content/ko/dependencies.md b/content/ko/dependencies.md new file mode 100644 index 000000000..429412e6e --- /dev/null +++ b/content/ko/dependencies.md @@ -0,0 +1,12 @@ +## II. 종속성 +### 명시적으로 선언되고 분리된 종속성 + +대부분의 프로그래밍 언어는 라이브러리 배포를 위한 패키징 시스템을 제공하고 있습니다. Perl의 [CPAN](http://www.cpan.org/) 이나 Ruby의 [Rubygems](http://rubygems.org/)가 그 예입니다. 라이브러리는 패키징 시스템을 통해 시스템 전체(site pakages)나 애플리케이션을 포함한 디렉토리(vendoring 혹은 bundling)에 설치될 수 있습니다. + +** Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. + +예를 들어, 루비에서 사용되는 [Gem Bundler](http://gembundler.com/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. + +명시적인 종속성 선언의 장점 중 하나는 애플리케이션 개발에 새로 참가하게 된 개발자가 설치를 간단하게 할 수 있다는 점입니다. 새로 참가한 개발자는 애플리케이션의 코드베이스를 개발 머신에 체크아웃 하고, 언어의 런타임과 종속성 매니저만 미리 설치하면 됩니다. 개발자는 정해져있는 *빌드 명령어*만 입력하면 응용 프로그램의 코드를 실행하는 데 필요한 모든 것을 설치할 수 있습니다. 예를 들어, Ruby의 빌드 명령어는 `bundle install`이며, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)에서는 `lein deps`입니다. + +Twelve-Factor App은 어떠한 시스템 도구에도 암시적으로 의존하지 않습니다. 예를 들어, ImageMagick이나 `curl`을 사용하는 경우가 있습니다. 이러한 툴들은 대부분의 시스템에 존재하지만, 모든 시스템에 존재하는 것이 보장되는 것은 아닙니다. 미래의 시스템에서는 존재하지 않을 수 있으며, 호환되는 버전이 있으라는 보장도 없습니다. 애플리케이션에게 시스템 도구가 필요하다면, 그 도구를 애플리케이션과 통합해야 합니다. \ No newline at end of file diff --git a/content/ko/dev-prod-parity.md b/content/ko/dev-prod-parity.md new file mode 100644 index 000000000..6e78f1810 --- /dev/null +++ b/content/ko/dev-prod-parity.md @@ -0,0 +1,78 @@ +## X. dev/prod 일치 +### development, staging, production 환경을 최대한 비슷하게 유지 + +역사적으로, 개발 환경(애플리케이션의 개발자가 직접 수정하는 로컬의 [배포](./codebase))과 production 환경(최종 사용자가 접근하게 되는 실행 중인 배포) 사이에는 큰 차이가 있었습니다. 이러한 차이는 3가지 영역에 걸처 나타납니다. + +* **시간의 차이**: 개발자가 작업한 코드는 production에 반영되기까지 며칠, 몇주, 때로는 몇개월이 걸릴 수 있습니다. +* **담당자의 차이**: 개발자는 작성한 코드를 시스템 엔지니어가 배포합니다. +* **툴의 차이**: production 배포는 아파치, MySQL, 리눅스를 사용하는데, 개발자는 Nginx, SQLite, OS X를 사용할 수 있습니다. + +**Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://www.avc.com/a_vc/2011/02/continuous-deployment.html)가 가능하도록 디자인 되었습니다. 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. + +* 시간의 차이을 최소화: 개발자가 작성한 코드는 몇 시간, 심지어 몇 분 후에 배포됩니다. +* 담당자의 차이를 최소화: 코드를 작성한 개발자들이 배포와 production에서의 모니터링에 깊게 관여합니다. +* 툴의 차이를 최소화: 개발과 production 환경을 최대한 비슷하게 유지합니다. + +위의 내용을 표로 요약하면 아래와 같습니다. +Summarizing the above into a table: + + + + + + + + + + + + + + + + + + + + + + +
전통적인 애플리케이션Twelve-Factor App
배포 간의 간격몇 주몇 시간
코드 작성자와 코드 배포자다른 사람같은 사람
개발 환경과 production 환경불일치함최대한 유사함
+ + +데이터베이스, 큐잉 시스템, 캐시와 같은 [백엔드 서비스](./backing-services)는 dev/prod 일치가 중요한 영역 중 하나 입니다. 많은 언어들은 다른 종류의 서비스에 대한 *어댑터*를 포함되어 있는 간단하게 백엔드 서비스에 접근할 수 있는 라이브러리들을 제공합니다. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +production 환경에서는 더 본격적이고 강력한 백엔드 서비스가 사용됨에도 불구하고, 개발자는 자신의 로컬 개발 환경에서는 가벼운 백엔드 서비스를 사용하는 것에 큰 매력을 느낄 수도 있습니다. 예를 들어, 로컬에서는 SQLite를 사용하고 production에서는 PostgreSQL을 사용한다던가, 개발 중에는 로컬 프로세스의 메모리를 캐싱용으로 사용하고 production에서는 Memcached를 사용하는 경우가 있습니다. + +** Twelve-Factor 개발자는 개발 환경과 production 환경에서 다른 백엔드 서비스를 쓰고 싶은 충동에 저항합니다. ** 이론적으로는 어댑터가 백엔드 서비스 간의 차이를 추상화해준다고 해도, 백엔드 서비스 간의 약간의 불일치가 개발 환경과 스테이징 환경에서는 동작하고 테스트에 통과된 코드가 production 환경에서 오류를 일으킬 수 있기 때문입니다. 이런 종류의 오류는 지속적인 배포를 방해합니다. 애플리케이션의 생명 주기 전체를 보았을 때, 이러한 방해와 지속적인 배포의 둔화가 발생시키는 손해는 엄청나게 큽니다. + +가벼운 로컬 서비스는 예전처럼 필수적인 것은 아닙니다. Memcache, PostgreSQL, RabbitMQ와 같은 현대적인 백엔드 서비스들은 [Homebrew](http://mxcl.github.com/homebrew/)나 [apt-get](https://help.ubuntu.com/community/AptGet/Howto)와 같은 현대적인 패키징 시스템 덕분에 설치하고 실행하는데 아무런 어려움도 없습니다. 혹은 [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/)와 같은 선언적 provisioning 툴과 [Vagrant](http://vagrantup.com/)등의 가벼운 가상 환경을 결합하여 로컬 환경을 production 환경과 매우 유사하게 구성할 수 있습니다. dev/prod 일치와 지속적인 배포의 이점에 비하면 이러한 시스템을 설치하고 사용하는 비용은 낮습니다. + +여러 백엔드 서비스에 접근할 수 있는 어댑터는 여전히 유용합니다. 새로운 백엔드 서비스를 사용하도록 포팅하는 작업의 고통을 낮춰주기 때문입니다. 하지만, 모든 애플리케이션의 배포들(개발자 환경, 스테이징, production)은 같은 종류, 같은 버전의 백엔드 서비스를 이용해야합니다. diff --git a/content/ko/disposability.md b/content/ko/disposability.md new file mode 100644 index 000000000..cf64a9b2c --- /dev/null +++ b/content/ko/disposability.md @@ -0,0 +1,12 @@ +## IX. 폐기 가능(Disposability) +### 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화 + +**Twelve-Factor App의 [프로세스](./processes)는 *간단하게 폐기 가능*합니다. 즉, 프로세스는 바로 시작하거나 종료될 수 있습니다. 이러한 속성은 신축성 있는 확장과 [코드](./codebase)나 [설정](./config)의 변화를 빠르게 배포하는 것을 쉽게 하며, production 배포를 안정성 있게 해줍니다. + +프로세스는 **시작 시간을 최소화**하도록 노력해야합니다. 이상적으로, 프로세스는 실행 커맨드가 실행된 뒤 몇 초만에 요청이나 작업을 받을 수 있도록 준비 됩니다. 짧은 실행 시간은 [릴리즈](./build-release-run) 작업과 확장(scale up)이 더 민첩하게 이루어질 수 있게 합니다. 또한 프로세스 매니저가 필요에 따라 쉽게 프로세스를 새로운 머신으로 프로세스를 옮길 수 있기 때문에 안정성도 높아집니다. + +프로세스는 프로세스 매니저로부터 **[SIGTERM]((http://en.wikipedia.org/wiki/SIGTERM)) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다. ** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. + +worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](http://kr.github.com/beanstalkd/)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [idempotent](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. + +프로세스는 하드웨어 에러에 의한 **갑작스러운 죽음에도 견고해야합니다.** 이러한 사태는 `SIGTERM`에 의한 그레이스풀 셧다운에 비하면 드문 일이지만, 그럼에도 발생할 수 있습니다. 이런 일에 대한 대책으로 Beanstalkd와 같은 견고한 큐잉 백엔드를 사용하는 것을 권장합니다. 이러한 백엔드는 클라이언트가 접속이 끊기거나, 타임 아웃이 발생했을 때, 작업을 큐로 되돌립니다. Twelve-Factor App은 예기치 못한, 우아하지 않은 종료도 처리할 수 있도록 설계됩니다. [Crash-only design](http://lwn.net/Articles/191059/)에서는 [논리적인 결론](http://docs.couchdb.org/en/latest/intro/overview.html)으로 이러한 컨셉을 가져왔습니다. \ No newline at end of file diff --git a/content/ko/intro.md b/content/ko/intro.md new file mode 100644 index 000000000..8a1fdb331 --- /dev/null +++ b/content/ko/intro.md @@ -0,0 +1,12 @@ +머리말 +============ + +오늘날 소프트웨어는 보통 서비스로 제공되고, 웹앱 혹은 SaaS(Software As A Service)로 불립니다. Twelve-Factor app은 아래와 같은 SaaS 앱을 만들기 위한 방법론입니다. + +* 설정 자동화를 위해 **선언적(declarative)** 양식을 사용하여 새로운 개발자들이 프로젝트에 참여하는데 드는 시간과 비용을 최소화합니다. +* OS에 대한 **종속성을 명확히**하고, 실행 환경 사이의 **극대화된 이식성**을 제공한다. +* 현대적인 **클라우드 플랫폼** 상에 **배포되기** 적합하며, 서버와 시스템의 관리를 필요하지 않게 합니다. +* 개발 환경과 운영 환경의 **차이를 최소화**하고 민첩성을 극대화하기 위해 **지속적인 배포**가 가능하게 합니다. +* 툴, 아키텍처, 개발 방식을 크게 바꾸지 않고 **확장(scale up)** 할 수 있습니다. + +Twelve-Factor 방법론은 어떤 프로그래밍 언어로 작성된 애플리케이션이든 적용이 가능합니다. 그리고 어떤 백엔드 서비스(데이터베이스, 큐, 메모리 캐시 등)과의 조합에도 사용될 수 있습니다. \ No newline at end of file diff --git a/content/ko/logs.md b/content/ko/logs.md new file mode 100644 index 000000000..553c4a753 --- /dev/null +++ b/content/ko/logs.md @@ -0,0 +1,16 @@ +## XI. 로그 +### 로그를 이벤트 스트림으로 취급 + +*로그*는 실행 중인 app의 동작을 확인할 수 있는 수단입니다. 서버 기반 환경에서 로그는 보통 디스크에 파일(로그 파일)로 저장됩니다. 하지만, 이것은 출력 포맷 중 하나에 불과합니다. + +로그는 모든 실행중인 프로세스와 백그라운드 서비스의 아웃풋 스트림으로부터 수집된 이벤트가 시간 순서로 정렬된 [스트림](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/)입니다. 가공되지 않는 로그는 보통, 하나의 이벤트가 하나의 라인으로 기록된 텍스트 포맷입니다.(예외(exception)에 의한 backtrace는 여러 라인에 걸쳐 있을 수도 있습니다.) 로그는 고정된 시작과 끝이 있는 것이 아니라, app이 실행되는 동안 계속 흐르는 흐름입니다. + +**Twelve-Factor App은 아웃풋 스트림의 전달이나 저장에 절대 관여하지 않습니다.** app은 로그 파일을 작성하거나, 관리하려고 해서는 안됩니다. 대신, 각 프로세스는 이벤트 스트림을 버퍼링 없이 `stdout`에 출력합니다. 로컬 개발환경에서 작업 중인 개발자는 app의 동작을 관찰하기 원하면 각자의 터미널에 출력되는 이 스트림을 볼 수 있습니다. + +스테이징이나 production 배포에서는 각 프로세스의 스트림은 실행 환경에 의해서 수집된 후, 앱의 다른 모든 스트림과 병합되어 열람하거나 보관하기 위한 하나 이상의 최종 목적지로 전달됩니다. 이러한 목적지들은 앱이 열람하거나 설정할 수 없지만, 대신 실행 환경에 의해서 완벽하게 관리됩니다. 이를 위해 오픈 소스 로그 라우터를 사용할 수 있습니다.(예: ([Logplex](https://github.com/heroku/logplex), [Fluent](https://github.com/fluent/fluentd))) + +앱의 이벤트 스트림은 파일로 보내지거나 터미널에서 실시간으로 보여질 수 있습니다. 가장 중요한 점은 스트림은 [Splunk](http://www.splunk.com/)같은 로그 분석 시스템과 [Hadoop/Hive](http://hive.apache.org/)같은 범용 데이터 보관소에 보내질 수 있다는 점입니다. 이러한 시스템은 장기간에 걸쳐 앱의 동작을 조사할 수 있는 강력함과 유연성을 가지게 됩니다. + +* 과거의 특정 이벤트를 찾기 +* 트렌드에 대한 거대한 규모의 그래프 (예: 분당 요청 수) +* 유저가 정의한 휴리스틱에 따른 알림 (예: 분당 오류 수가 임계 값을 넘는 경우 알림을 발생시킴) \ No newline at end of file diff --git a/content/ko/port-binding.md b/content/ko/port-binding.md new file mode 100644 index 000000000..db9c49c6c --- /dev/null +++ b/content/ko/port-binding.md @@ -0,0 +1,14 @@ +## VII. 포트 바인딩 +### 포트 바인딩을 사용해서 서비스를 공개함 + +웹앱은 웹서버 컨테이너 내부에서 실행되기도 합니다. 예를 들어, PHP 앱은 [Apache HTTPD](http://httpd.apache.org/)의 모듈로 실행될 수도 있고, Java 앱은 [Tomcat](http://tomcat.apache.org/) 내부에서 실행될 수도 있습니다. + +**Twelve-Factor 앱은 완전히 독립적**이며 웹서버가 웹 서비스를 만들기 위해 처리하는 실행환경에 대한 런타임 인젝션에 의존하지 않습니다. Twelve-Factor 웹 앱은 **포트를 바인딩하여 HTTP 서비스로 공개되며** 그 포트로 들어오는 요청을 기다립니다. + +로컬 개발 환경에서는 `http://localhost:5000`과 같은 주소를 통해 개발자가 애플리케이션 서비스에 접근할 수 있습니다. 배포에서는 라우팅 레이어가 외부에 공개된 호스트명으로 들어온 요청을 포트에 바인딩된 웹 프로세스에 전달 합니다. + +이는 일반적으로 [종속선 선언](./dependency)에 웹서버 라이브러리를 추가함으로써 구현됩니다. 예를 들어, 파이썬의 [Tornado](http://www.tornadoweb.org/)나 루비의 [Thin](http://code.macournoyer.com/thin/)이나 자바와 JVM 기반 언어들을 위한 [Jetty](http://jetty.codehaus.org/jetty/)가 있습니다. 이것들은 전적으로 *유저 스페이스* 즉, 애플리케이션의 코드 내에서 처리됩니다. 실행 환경과의 규약은 요청을 처리하기 위해 포트를 바인딩하는 것입니다. + +포트 바인딩에 의해 공개되는 서비스는 HTTP 뿐만이 아닙니다. 거의 모든 종류의 서버 소프트웨어는 포트를 바인딩하고 요청이 들어오길 기다리는 프로세스를 통해 실행될 수 있습니다. 예를 들면, [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/)을 따름)나 [Redis](http://redis.io/) ([Redis protocol](http://redis.io/topics/protocol)을 따름) 등이 있습니다. + +포트 바인딩을 사용한다는 것은 하나의 앱이 다른 앱을 위한 백엔드 서비스가 될 수 있다는 것을 의미한다는 점에 주목합시다. 백엔드 앱의 URL을 사용할 앱의 [설정](./config)의 리소스 핸들로 추가하는 방식으로 앱이 다른 앱을 백엔드 서비스로 사용할 수 있습니다. \ No newline at end of file diff --git a/content/ko/processes.md b/content/ko/processes.md new file mode 100644 index 000000000..19a9e63cd --- /dev/null +++ b/content/ko/processes.md @@ -0,0 +1,14 @@ +## VI. 프로세스 +### 애플리케이션을 하나 혹은 여러개의 무상태(stateless) 프로세스로 실행 + +실행 환경에서 앱은 하나 이상의 *프로세스*로 실행됩니다. + +가장 간단한 케이스는 코드가 stand-alone 스크립트인 경우입니다. 이 경우, 실행 환경은 개발자의 언어 런타임이 설치된 로컬 노트북이며, 프로세스는 커맨드 라인 명령어에 의해서 실행됩니다.(예: `python my_script.py`) 복잡한 케이스로는 많은 [프로세스 타입별로 여러개의 프로세스](./concurrency)가 사용되는 복잡한 애플리케이션이 있습니다. + +**Twelve-Factor 프로세스는 무상태(stateless)이며, [아무 것도 공유하지 않습니다](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** 유지될 필요가 있는 모든 데이터는 데이터베이스 같은 안정된 [백엔드 서비스](./backing-services)에 저장되어야 합니다. + +짧은 단일 트랙잭션 내에서 캐시로 프로세스의 메모리 공간이나 파일시스템을 사용해도 됩니다. 예를 들자면 큰 파일을 받고, 해당 파일을 처리하고, 그 결과를 데이터베이스에 저장하는 경우가 있습니다. Twelve-Factor 앱에서 절대로 메모리나 디스크에 캐시된 내용이 미래의 요청이나 작업에서도 유효할 것이라고 가정해서는 안됩니다. 각 프로세스 타입의 프로세스가 여러개 돌아가고 있는 경우, 미래의 요청은 다른 프로세스에 의해서 처리될 가능성이 높습니다. 하나의 프로세스만 돌고 있는 경우에도 여러 요인(코드 배포, 설정 변경, 프로세스를 다른 물리적 장소에 재배치 등)에 의해서 발생하는 재실행은 보통 모든 로컬의 상태(메모리와 파일 시스템 등)를 없애버립니다. + +에셋 패키징 도구 (예: [Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/))는 컴파일된 에셋을 저장할 캐시로 파일 시스템을 사용합니다. Twelve-Factor App은 이러한 컴파일을 런타임에 진행하기보다는, [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html)처럼 [빌드 단계](./build-release-run)에서 수행하는 것을 권장합니다. + +웹 시스템 중에서는 ["Sticky Session"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)에 의존하는 것도 있습니다. 이는 유저의 세션 데이터를 앱의 프로세스 메모리에 캐싱하고, 같은 유저의 이후 요청도 같은 프로세스로 전달될 것을 가정하는 것입니다. Sticky Session은 Twelve-Factor에 위반되며, 절대로 사용하거나 의존해서는 안됩니다. 세션 상태 데이터는 [Memcached](http://memcached.org/)나 [Redis](http://redis.io/)처럼 유효기간을 제공하는 데이터 저장소에 저장하는 것이 적합합니다. \ No newline at end of file diff --git a/content/ko/toc.md b/content/ko/toc.md new file mode 100644 index 000000000..4d9d92862 --- /dev/null +++ b/content/ko/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. 코드베이스](./codebase) +### 버전 관리되는 하나의 코드베이스와 다양한 배포 + +## [II. 종속성](./dependencies) +### 명시적으로 선언되고 분리된 종속성 + +## [III. 설정](./config) +### 환경(environment)에 저장된 설정 + +## [IV. 백엔드 서비스](./backing-services) +### 백엔드 서비스를 연결된 리소스로 취급 + +## [V. 빌드, 릴리즈, 실행](./build-release-run) +### 철저하게 분리된 빌드와 실행 단계 + +## [VI. 프로세스](./processes) +### 애플리케이션을 하나 혹은 여러개의 무상태(stateless) 프로세스로 실행 + +## [VII. 포트 바인딩](./port-binding) +### 포트 바인딩을 사용해서 서비스를 공개함 + +## [VIII. 동시성(Concurrency)](./concurrency) +### 프로세스 모델을 사용한 확장 + +## [IX. 폐기 가능(Disposability)](./disposability) +### 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화 + +## [X. dev/prod 일치](./dev-prod-parity) +### development, staging, production 환경을 최대한 비슷하게 유지 + +## [XI. 로그](./logs) +### 로그를 이벤트 스트림으로 취급 + +## [XII. Admin 프로세스](./admin-processes) +### admin/maintenance 작업을 일회성 프로세스로 실행 diff --git a/content/ko/who.md b/content/ko/who.md new file mode 100644 index 000000000..55674e684 --- /dev/null +++ b/content/ko/who.md @@ -0,0 +1,4 @@ +이 문서의 대상 +============================== + +서비스로 동작하는 애플리케이션을 개발하는 모든 개발자. 그런 애플리케이션을 배포하고 관리하는 인프라 엔지니어. diff --git a/locales/ko.yaml b/locales/ko.yaml new file mode 100644 index 000000000..2312b731c --- /dev/null +++ b/locales/ko.yaml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: Korean (ko) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "(한국어)" From 48d8c19930a4a36e74df192fdbe09dbcbe740ea5 Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:15:25 +0900 Subject: [PATCH 109/472] fixed ko.yaml --- locales/ko.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ko.yaml b/locales/ko.yaml index 2312b731c..62a33eb16 100644 --- a/locales/ko.yaml +++ b/locales/ko.yaml @@ -1,4 +1,4 @@ -en: +ko: # Name of language listed in locales menu language: Korean (ko) From 7a6f6775b57b1a11abe752cfe00301d6151e0079 Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:18:16 +0900 Subject: [PATCH 110/472] renamed ko.yaml to ko.yaml --- locales/{ko.yaml => ko.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename locales/{ko.yaml => ko.yml} (86%) diff --git a/locales/ko.yaml b/locales/ko.yml similarity index 86% rename from locales/ko.yaml rename to locales/ko.yml index 62a33eb16..cdc92d44e 100644 --- a/locales/ko.yaml +++ b/locales/ko.yml @@ -4,4 +4,4 @@ ko: # A text to make known that the article is a translation not an original. # Empty for English, original. - translation: "(한국어)" + translation: (한국어) From bbc3eee4548fbcfcfd5a05c8afd17723faafb892 Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:20:07 +0900 Subject: [PATCH 111/472] =?UTF-8?q?changed=20from=20Korean=20to=20?= =?UTF-8?q?=ED=95=9C=EA=B5=AD=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/ko.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ko.yml b/locales/ko.yml index cdc92d44e..a48103a42 100644 --- a/locales/ko.yml +++ b/locales/ko.yml @@ -1,6 +1,6 @@ ko: # Name of language listed in locales menu - language: Korean (ko) + language: 한국어 (ko) # A text to make known that the article is a translation not an original. # Empty for English, original. From a94f89e5e76c0fa1a234b061d6028cfcf66df33d Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:24:43 +0900 Subject: [PATCH 112/472] fixed markdown syntax errors --- content/ko/backing-services.md | 4 ++-- content/ko/build-release-run.md | 2 +- content/ko/dependencies.md | 2 +- content/ko/dev-prod-parity.md | 2 +- content/ko/intro.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/content/ko/backing-services.md b/content/ko/backing-services.md index 901265ba9..a82ac560b 100644 --- a/content/ko/backing-services.md +++ b/content/ko/backing-services.md @@ -1,11 +1,11 @@ ## IV. 백엑드 서비스 ### 백엔드 서비스를 연결된 리소스로 취급 -* 백엔드 서비스*는 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스입니다. 예를 들어, 데이터 저장소(예: [MySQL](http://dev.mysql.com/), [CouchDB](http://couchdb.apache.org/)), 메시지 큐잉 시스템(예: [RabbitMQ](http://www.rabbitmq.com/), [Beanstalkd](http://kr.github.com/beanstalkd/)), 메일을 보내기 위한 SMTP 서비스 (예: [Postfix](http://www.postfix.org/)), 캐시 시스템(예: [Memcached](http://memcached.org/)) 등이 있습니다. +*백엔드 서비스*는 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스입니다. 예를 들어, 데이터 저장소(예: [MySQL](http://dev.mysql.com/), [CouchDB](http://couchdb.apache.org/)), 메시지 큐잉 시스템(예: [RabbitMQ](http://www.rabbitmq.com/), [Beanstalkd](http://kr.github.com/beanstalkd/)), 메일을 보내기 위한 SMTP 서비스 (예: [Postfix](http://www.postfix.org/)), 캐시 시스템(예: [Memcached](http://memcached.org/)) 등이 있습니다. 데이터 저장소와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))등이 있습니다. -** Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다. ** 애플리케이션에게는 양 쪽 모두 연결된 리소이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. +**Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다.** 애플리케이션에게는 양 쪽 모두 연결된 리소스이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. 각각의 다른 백엔드 서비스는 *리소스*입니다. 예를 들어, 하나의 MySQL DB는 하나의 리소스입니다. 애플리케이션 레이어에서 샤딩을 하는 두 개의 MySQL 데이터베이스는 두 개의 서로 다른 리소스라고 볼 수 있습니다. Twelve-Factor App은 이러한 데이터베이스들을 *첨부된(Attached) 리소스*으로 다룹니다. 이는 서로 느슨하게 결합된다는 점을 암시합니다. diff --git a/content/ko/build-release-run.md b/content/ko/build-release-run.md index db21080f9..60347e180 100644 --- a/content/ko/build-release-run.md +++ b/content/ko/build-release-run.md @@ -10,7 +10,7 @@ ![코드 베이스는 빌드가 되고, 빌드는 설정과 조합되어 릴리즈가 됩니다.](/images/release.png) -** Twelve-Factor App은 빌드, 릴리즈, 실행 단계를 엄격하게 서로 분리합니다.** 예를 들어, 실행 단계에서 코드를 변경할 수는 없습니다. 변경을 실행 단계보다 앞에 있는 빌드 단계로 전달할 수 있는 방법이 없기 때문입니다. +**Twelve-Factor App은 빌드, 릴리즈, 실행 단계를 엄격하게 서로 분리합니다.** 예를 들어, 실행 단계에서 코드를 변경할 수는 없습니다. 변경을 실행 단계보다 앞에 있는 빌드 단계로 전달할 수 있는 방법이 없기 때문입니다. 배포 도구는 일반적으로 릴리즈 관리 도구를 제공합니다. 특히 주목할만한 점은 이전 릴리즈로 되돌릴 수 있는 롤백 기능입니다. 예를 들어, [Capistrano](https://github.com/capistrano/capistrano/wiki)는 배포 툴은 릴리즈를 `releases`라는 하위 디렉토리에 저장시키고, 현재 릴리즈는 현재 릴리즈 디렉토리로 심볼릭 링크로 연결합니다. 이 툴의 `rollback` 명령어는 이전 버전으로 쉽고 빠르게 이전 릴리즈로 롤백할 수 있도록 해줍니다. diff --git a/content/ko/dependencies.md b/content/ko/dependencies.md index 429412e6e..66ffb5e2b 100644 --- a/content/ko/dependencies.md +++ b/content/ko/dependencies.md @@ -3,7 +3,7 @@ 대부분의 프로그래밍 언어는 라이브러리 배포를 위한 패키징 시스템을 제공하고 있습니다. Perl의 [CPAN](http://www.cpan.org/) 이나 Ruby의 [Rubygems](http://rubygems.org/)가 그 예입니다. 라이브러리는 패키징 시스템을 통해 시스템 전체(site pakages)나 애플리케이션을 포함한 디렉토리(vendoring 혹은 bundling)에 설치될 수 있습니다. -** Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. +**Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. 예를 들어, 루비에서 사용되는 [Gem Bundler](http://gembundler.com/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. diff --git a/content/ko/dev-prod-parity.md b/content/ko/dev-prod-parity.md index 6e78f1810..0fb1be33a 100644 --- a/content/ko/dev-prod-parity.md +++ b/content/ko/dev-prod-parity.md @@ -71,7 +71,7 @@ Summarizing the above into a table: production 환경에서는 더 본격적이고 강력한 백엔드 서비스가 사용됨에도 불구하고, 개발자는 자신의 로컬 개발 환경에서는 가벼운 백엔드 서비스를 사용하는 것에 큰 매력을 느낄 수도 있습니다. 예를 들어, 로컬에서는 SQLite를 사용하고 production에서는 PostgreSQL을 사용한다던가, 개발 중에는 로컬 프로세스의 메모리를 캐싱용으로 사용하고 production에서는 Memcached를 사용하는 경우가 있습니다. -** Twelve-Factor 개발자는 개발 환경과 production 환경에서 다른 백엔드 서비스를 쓰고 싶은 충동에 저항합니다. ** 이론적으로는 어댑터가 백엔드 서비스 간의 차이를 추상화해준다고 해도, 백엔드 서비스 간의 약간의 불일치가 개발 환경과 스테이징 환경에서는 동작하고 테스트에 통과된 코드가 production 환경에서 오류를 일으킬 수 있기 때문입니다. 이런 종류의 오류는 지속적인 배포를 방해합니다. 애플리케이션의 생명 주기 전체를 보았을 때, 이러한 방해와 지속적인 배포의 둔화가 발생시키는 손해는 엄청나게 큽니다. +**Twelve-Factor 개발자는 개발 환경과 production 환경에서 다른 백엔드 서비스를 쓰고 싶은 충동에 저항합니다.** 이론적으로는 어댑터가 백엔드 서비스 간의 차이를 추상화해준다고 해도, 백엔드 서비스 간의 약간의 불일치가 개발 환경과 스테이징 환경에서는 동작하고 테스트에 통과된 코드가 production 환경에서 오류를 일으킬 수 있기 때문입니다. 이런 종류의 오류는 지속적인 배포를 방해합니다. 애플리케이션의 생명 주기 전체를 보았을 때, 이러한 방해와 지속적인 배포의 둔화가 발생시키는 손해는 엄청나게 큽니다. 가벼운 로컬 서비스는 예전처럼 필수적인 것은 아닙니다. Memcache, PostgreSQL, RabbitMQ와 같은 현대적인 백엔드 서비스들은 [Homebrew](http://mxcl.github.com/homebrew/)나 [apt-get](https://help.ubuntu.com/community/AptGet/Howto)와 같은 현대적인 패키징 시스템 덕분에 설치하고 실행하는데 아무런 어려움도 없습니다. 혹은 [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/)와 같은 선언적 provisioning 툴과 [Vagrant](http://vagrantup.com/)등의 가벼운 가상 환경을 결합하여 로컬 환경을 production 환경과 매우 유사하게 구성할 수 있습니다. dev/prod 일치와 지속적인 배포의 이점에 비하면 이러한 시스템을 설치하고 사용하는 비용은 낮습니다. diff --git a/content/ko/intro.md b/content/ko/intro.md index 8a1fdb331..3c524fd3b 100644 --- a/content/ko/intro.md +++ b/content/ko/intro.md @@ -5,7 +5,7 @@ * 설정 자동화를 위해 **선언적(declarative)** 양식을 사용하여 새로운 개발자들이 프로젝트에 참여하는데 드는 시간과 비용을 최소화합니다. * OS에 대한 **종속성을 명확히**하고, 실행 환경 사이의 **극대화된 이식성**을 제공한다. -* 현대적인 **클라우드 플랫폼** 상에 **배포되기** 적합하며, 서버와 시스템의 관리를 필요하지 않게 합니다. +* 현대적인 **클라우드 플랫폼** 상에 **배포되기** 적합하고, 서버와 시스템의 관리를 필요하지 않게 합니다. * 개발 환경과 운영 환경의 **차이를 최소화**하고 민첩성을 극대화하기 위해 **지속적인 배포**가 가능하게 합니다. * 툴, 아키텍처, 개발 방식을 크게 바꾸지 않고 **확장(scale up)** 할 수 있습니다. From 3763002c8f07ed5d949c6f68d156cc90f5024cb0 Mon Sep 17 00:00:00 2001 From: Song Jaehak Date: Fri, 27 Feb 2015 01:27:06 +0900 Subject: [PATCH 113/472] Improved korean sentence --- content/ko/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/admin-processes.md b/content/ko/admin-processes.md index 952f86138..206a33e95 100644 --- a/content/ko/admin-processes.md +++ b/content/ko/admin-processes.md @@ -1,7 +1,7 @@ ## XII. Admin 프로세스 ### admin/maintenance 작업을 일회성 프로세스로 실행 -[프로세스 포메이션](./concurrency)은 애플리케이션의 일반적인 기능들(예: Web request의 처리)을 처리하기 위한 프로세스들의 집합 입니다. 이와는 별도로, 개발자들은 종종 일회성 관리나 유지 보수 작업을 하고 싶어집니다. 그 예는 아래와 같습니다. +[프로세스 포메이션](./concurrency)은 애플리케이션의 일반적인 기능들(예: Web request의 처리)을 처리하기 위한 프로세스들의 집합 입니다. 이와는 별도로, 개발자들은 종종 일회성 관리나 유지 보수 작업이 필요합니다. 그 예는 아래와 같습니다. * 데이터베이스 마이그레이션을 실행합니다. (예: Django에서 `manage.py migrate`, Rail에서 `rake db:migrate`) * 임의의 코드를 실행하거나 라이브 데이터베이스에서 앱의 모델을 조사하기 위해 콘솔([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) Shell로도 알려져 있는)을 실행한다. 대부분의 언어에서는 인터프리터를 아무런 인자 없이 실행하거나(예: python, perl) 별도의 명령어로 실행(예: ruby의 irb, rails의 rails console)할 수 있는 REPL를 제공합니다. From d121f0dec609bc21bcdfa606cb0ce9358ffc0b1c Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Mon, 2 Mar 2015 12:00:39 +0100 Subject: [PATCH 114/472] Replace the example Django asset manager django-assetpackager is not maintained nor used, its last update even predates Django 1.0. django-compressor is the most used package when looking at GitHub stars and Django Packages reported users. --- content/en/processes.md | 2 +- content/ja/processes.md | 2 +- content/zh_cn/processes.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/processes.md b/content/en/processes.md index 2a6df3419..dbd86a7c8 100644 --- a/content/en/processes.md +++ b/content/en/processes.md @@ -9,7 +9,7 @@ In the simplest case, the code is a stand-alone script, the execution environmen The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). diff --git a/content/ja/processes.md b/content/ja/processes.md index 44e1a7230..1b2db2e36 100644 --- a/content/ja/processes.md +++ b/content/ja/processes.md @@ -9,6 +9,6 @@ プロセスのメモリ空間やファイルシステムは、短い単一のトランザクション内でのキャッシュとして利用してもよい。例えば、大きなファイルをダウンロードし、そのファイルを処理し、結果をデータベースに格納するという一連の処理において、ファイルシステムをキャッシュとして利用できる。Twelve-Factor Appは、メモリやディスクにキャッシュされたものが将来のリクエストやジョブにおいて利用できることを決して仮定しない -- それぞれのプロセスタイプのプロセスが多く実行されている場合、将来のリクエストやジョブが別のプロセスで処理される可能性が高い。1つのプロセスしか実行されていない場合であっても、プロセスが再起動すると、すべての局所的な状態(メモリやファイルシステムなど)が消えてしまうことがある。プロセスの再起動の要因としては、コードのデプロイ、設定の変更、プロセスを別の物理位置に再配置する実行環境などがある。 -アセットパッケージャー(例:[Jammit](http://documentcloud.github.com/jammit/) や [django-assetpackager](http://code.google.com/p/django-assetpackager/))は、コンパイルされたアセットをキャッシュするためにファイルシステムを利用する。Twelve-Factor Appは、このコンパイル処理を実行時に行うよりも、[Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)のように[ビルドステージ](./build-release-run)で行うほうが、望ましいと考えている。 +アセットパッケージャー(例:[Jammit](http://documentcloud.github.com/jammit/) や [django-compressor](http://django-compressor.readthedocs.org/))は、コンパイルされたアセットをキャッシュするためにファイルシステムを利用する。Twelve-Factor Appは、このコンパイル処理を実行時に行うよりも、[Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)のように[ビルドステージ](./build-release-run)で行うほうが、望ましいと考えている。 Webシステムの中には、[“スティッキーセッション”](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)に頼るものがある -- これはユーザーのセッションデータをアプリケーションプロセスのメモリにキャッシュし、同じ訪問者からの将来のリクエストが同じプロセスに送られることを期待するものである。スティッキーセッションはTwelve-Factorに違反しており、決して使ったり頼ったりしてはならない。セッション状態のデータは、有効期限を持つデータストア(例:[Memcached](http://memcached.org/) や [Redis](http://redis.io/))に格納すべきである。 diff --git a/content/zh_cn/processes.md b/content/zh_cn/processes.md index a53facdba..4491514a4 100644 --- a/content/zh_cn/processes.md +++ b/content/zh_cn/processes.md @@ -9,6 +9,6 @@ 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失。 -源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-assetpackager](http://code.google.com/p/django-assetpackager/)) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://guides.rubyonrails.org/asset_pipeline.html) ,而不是在运行阶段。 +源文件打包工具([Jammit](http://documentcloud.github.com/jammit/), [django-compressor](http://django-compressor.readthedocs.org/)) 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 [构建步骤](./build-release-run) 做此动作——正如 [Rails资源管道](http://guides.rubyonrails.org/asset_pipeline.html) ,而不是在运行阶段。 一些互联网系统依赖于 “[粘性 session ](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence)”, 这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如 [Memcached](http://memcached.org/) 或 [Redis](http://redis.io/) 这样的带有过期时间的缓存中。 From 98166b41e4f7869a3ec9b4e4fb4a0abb2c7a1138 Mon Sep 17 00:00:00 2001 From: Aymeric Beaumet Date: Fri, 27 Feb 2015 11:28:47 +0100 Subject: [PATCH 115/472] fix misplaced comma --- content/en/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/config.md b/content/en/config.md index 2d2ff384b..969296e93 100644 --- a/content/en/config.md +++ b/content/en/config.md @@ -19,5 +19,5 @@ Another approach to config is the use of config files which are not checked into Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments," but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. From 6a686a58cb187b68ea8c53288ab0972e057dd034 Mon Sep 17 00:00:00 2001 From: madhead Date: Sat, 28 Mar 2015 23:04:45 +0300 Subject: [PATCH 116/472] Update Spring links --- content/en/config.md | 3 +-- content/ja/config.md | 2 +- content/zh_cn/config.md | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/content/en/config.md b/content/en/config.md index 969296e93..0bc603b82 100644 --- a/content/en/config.md +++ b/content/en/config.md @@ -11,7 +11,7 @@ Apps sometimes store config as constants in the code. This is a violation of tw A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). This type of config does not vary between deploys, and so is best done in the code. +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. @@ -20,4 +20,3 @@ Another approach to config is the use of config files which are not checked into Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. - diff --git a/content/ja/config.md b/content/ja/config.md index 510b3f60c..6c8e43c32 100644 --- a/content/ja/config.md +++ b/content/ja/config.md @@ -11,7 +11,7 @@ アプリケーションがすべての設定をコードの外部に正しく分離できているかどうかの簡単なテストは、認証情報を漏洩させることなく、コードベースを今すぐにでもオープンソースにすることができるかどうかである。 -なお、この“設定”の定義には、アプリケーション内部の設定は **含まない** ことに注意する。内部の設定とは、Railsにおける`config/routes.rb`や、[Spring](http://www.springsource.org/)において[コードモジュールがどう接続されるか](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html)などの設定を指す。この種の設定はデプロイの間で変わらないため、コードの内部で行うべきである。 +なお、この“設定”の定義には、アプリケーション内部の設定は **含まない** ことに注意する。内部の設定とは、Railsにおける`config/routes.rb`や、[Spring](http://spring.io/)において[コードモジュールがどう接続されるか](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html)などの設定を指す。この種の設定はデプロイの間で変わらないため、コードの内部で行うべきである。 設定に対するもう1つのアプローチは、バージョン管理システムにチェックインされない設定ファイルを使う方法である。例として、Railsにおける`config/database.yml`がある。この方法は、リポジトリにチェックインされる定数を使うことに比べると非常に大きな進歩であるが、まだ弱点がある。設定ファイルが誤ってリポジトリにチェックインされやすいことと、設定ファイルが異なる場所に異なるフォーマットで散乱し、すべての設定を一つの場所で見たり管理したりすることが難しくなりがちであることである。その上、これらのフォーマットは言語やフレームワークに固有のものになりがちである。 diff --git a/content/zh_cn/config.md b/content/zh_cn/config.md index 92cf639d3..bcc671be5 100644 --- a/content/zh_cn/config.md +++ b/content/zh_cn/config.md @@ -11,7 +11,7 @@ 判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。 -需要指出的是,这里定义的"配置"并**不**包括应用的内部配置,比如 Rails 的 `config/routes.rb`,或是使用 [Spring](http://www.springsource.org/) 时 [代码模块间的依赖注入关系](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 +需要指出的是,这里定义的"配置"并**不**包括应用的内部配置,比如 Rails 的 `config/routes.rb`,或是使用 [Spring](http://spring.io/) 时 [代码模块间的依赖注入关系](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) 。这类配置在不同部署间不存在差异,所以应该写入代码。 另外一个解决方法是使用配置文件,但不把它们纳入版本控制系统,就像 Rails 的 `config/database.yml` 。这相对于在代码中使用常量已经是长足进步,但仍然有缺点:总是会不小心将配置文件签入了代码库;配置文件的可能会分散在不同的目录,并有着不同的格式,这让找出一个地方来统一管理所有配置变的不太现实。更糟的是,这些格式通常是语言或框架特定的。 From b34a95e6db8605d847d421dea55f4f2519383250 Mon Sep 17 00:00:00 2001 From: orangain Date: Thu, 5 Feb 2015 20:47:03 +0900 Subject: [PATCH 117/472] Tiny fix in Japanese --- content/ja/admin-processes.md | 2 +- content/ja/background.md | 2 +- content/ja/disposability.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ja/admin-processes.md b/content/ja/admin-processes.md index a3c68481e..46ccb6bc1 100644 --- a/content/ja/admin-processes.md +++ b/content/ja/admin-processes.md @@ -7,7 +7,7 @@ * 任意のコードを実行したり、生のデータベースに対してアプリケーションのモデルを調査したりするために、コンソール([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)シェルとも言われる)を実行する。多くの言語ではインタプリタを引数なしで実行する(例:`python` や `perl`)ことでREPLを利用できるが、別のコマンドを用意している場合もある(例:Rubyでの `irb` や Railsでの `rails console`)。 * アプリケーションのリポジトリにコミットされた1回限りのスクリプトを実行する(例:`php scripts/fix_bad_records.php`)。 -1回限りの管理プロセスは、アプリケーションの通常の[長時間実行されるプロセス](./processes)と全く同じ環境で実行されるべきである。これらのプロセスは、ある[リリース](./build-release-run)に対して実行され、そのリリースに対して実行されるすべてのプロセスと同じ[コード](./code)と[設定](./config)を使う。管理用のコードは、同期の問題を避けるためにアプリケーションコードと一緒にデプロイされるべきである。 +1回限りの管理プロセスは、アプリケーションの通常の[長時間実行されるプロセス](./processes)と全く同じ環境で実行されるべきである。これらのプロセスは、ある[リリース](./build-release-run)に対して実行され、そのリリースに対して実行されるすべてのプロセスと同じ[コードベース](./codebase)と[設定](./config)を使う。管理用のコードは、同期の問題を避けるためにアプリケーションコードと一緒にデプロイされるべきである。 同じ[依存関係分離](./dependencies)技術をすべてのプロセスタイプに利用するべきである。例えば、もしRubyのWebプロセスがコマンド `bundle exec thin start` を使うのであれば、データベースのマイグレーションには `bundle exec rake db:migrate` を使うべきである。同様に、Virtualenvを使っているPythonプログラムは、仮想環境内の `bin/python` をTornado Webサーバーとすべての `manage.py` 管理プロセスの両方で利用するべきである。 diff --git a/content/ja/background.md b/content/ja/background.md index 9ac0b07c4..859b586eb 100644 --- a/content/ja/background.md +++ b/content/ja/background.md @@ -3,6 +3,6 @@ このドキュメントへの寄稿者は、何百ものアプリケーションの開発とデプロイに直接関わり、[Heroku](http://www.heroku.com/)プラットフォーム上での仕事を通して、何百何千ものアプリケーションの開発・運用・スケールに間接的に立ち会った。 -このドキュメントは、多種多様な野生のSaaSアプリケーションにおける私たちの経験と観察をすべてまとめたものである。これは、アプリケーション開発における理想的なプラクティスを見出すための三角測量である。特に、アプリケーションが時間と共に有機的に成長する力学、アプリケーションのコードベースに取り組む開発者間のコラボレーションの力学、そして[ソフトウェア腐敗によるコストの回避](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)に注目している。 +このドキュメントは、多種多様なSaaSアプリケーション開発現場での私たちの経験と観察をすべてまとめたものである。これは、アプリケーション開発における理想的なプラクティスを見出すための三角測量である。特に、アプリケーションが時間と共に有機的に成長する力学、アプリケーションのコードベースに取り組む開発者間のコラボレーションの力学、そして[ソフトウェア腐敗によるコストの回避](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)に注目している。 私たちの動機は、私たちがモダンなアプリケーション開発で見てきたある種のシステム的な問題への関心を高めること、この問題を議論するための共通の語彙を提供すること、そしてこの問題に対する広い概念的な解決策と専門用語を提供することである。フォーマットはMartin Fowlerの書籍、*[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* および *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* に着想を得ている。 diff --git a/content/ja/disposability.md b/content/ja/disposability.md index d07e9f633..810ea811f 100644 --- a/content/ja/disposability.md +++ b/content/ja/disposability.md @@ -3,7 +3,7 @@ **Twelve-Factor Appの [プロセス](./processes) は *廃棄容易* である、すなわち即座に起動・終了することができる。** この性質が、素早く柔軟なスケールと、[コード](./codebase) や [設定](./config) に対する変更の素早いデプロイを容易にし、本番デプロイの堅牢性を高める。 -プロセスは、 **起動時間を最小化する** よう努力するべきである。理想的には、1つのプロセスは、起動コマンドが実行されてから数秒間でリクエストやジョブを受け取れるようになるべきである。起動時間が短いと、[リリース](./build-release-run)作業やスケールアップのアジリティが高くなる。さら、プロセスマネージャーが必要に応じてプロセスを新しい物理マシンに簡単に移動できるようになるため、堅牢性も高くなる。 +プロセスは、 **起動時間を最小化する** よう努力するべきである。理想的には、1つのプロセスは、起動コマンドが実行されてから数秒間でリクエストやジョブを受け取れるようになるべきである。起動時間が短いと、[リリース](./build-release-run)作業やスケールアップのアジリティが高くなる。さらに、プロセスマネージャーが必要に応じてプロセスを新しい物理マシンに簡単に移動できるようになるため、堅牢性も高くなる。 プロセスは、プロセスマネージャーから **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)シグナルを受け取ったときに、グレースフルにシャットダウンする。** Webプロセスの場合、グレースフルシャットダウンは、サービスポートのリッスンを中止し(従って新しいリクエストを拒み)、処理中のリクエストが終了するまで待ち、シャットダウンすることで実現される。このモデルでは暗黙的にHTTPリクエストが短い(せいぜい数秒)ことを仮定している。ロングポーリングの場合、クライアントはコネクションが失われたときに途切れなく再接続を試みるべきである。 From 3d714e598b5653510f0dfc5e872b5b7955fe203f Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 30 Mar 2015 09:04:13 +0100 Subject: [PATCH 118/472] update spring links --- content/ko/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/config.md b/content/ko/config.md index c2c946b68..4fc4415f9 100644 --- a/content/ko/config.md +++ b/content/ko/config.md @@ -11,10 +11,10 @@ 애플리케이션의 모든 설정이 정상적으로 코드 바깥으로 분리되어 있는지 확인할 수 있는 간단한 테스트는 어떠한 인증정보도 유출시키지 않고 코드베이스가 지금 당장 오픈 소스가 될 수 있는지 확인하는 것입니다. -이 "설정"의 정의는 애플리케이션 내부 설정을 *포함하지 않는다는 점*에 유의해야 합니다. Rails의 `config/routes.rb`이나 [Spring](http://www.springsource.org/)의 ["어떻게 코드 모듈이 연결되는 가](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html)과 같은 설정들은 배치 사이에서 변하지 않기 때문에 코드의 내부에 있는 것이 가장 좋습니다. +이 "설정"의 정의는 애플리케이션 내부 설정을 *포함하지 않는다는 점*에 유의해야 합니다. Rails의 `config/routes.rb`이나 [Spring](http://spring.io/)의 ["어떻게 코드 모듈이 연결되는 가](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html)과 같은 설정들은 배치 사이에서 변하지 않기 때문에 코드의 내부에 있는 것이 가장 좋습니다. 설정에 대한 또 다른 접근방식은 Rails의 `config/database.yaml`처럼 버전 관리 시스템에 등록되지 않은 설정 파일을 이용하는 것입니다. 이 방법은 코드 저장소에 등록된 상수를 사용하는 것에 비하면 매우 큰 발전이지만, 설정 파일이 여러 위치에 여러 포맷으로 흝어지고 모든 설정을 한 곳에서 확인하고 관리하기 어렵게 만드는 경향이 있습니다. 게다가, 이러한 형식들은 언어와 프레임워크을 따라가는 경향이 있습니다. - + **Twelve-Factor App은 설정을 *환경 변수*** (envvars나 env라고도 불림)에 저장합니다. 환경 변수는 코드 변경 없이 쉽게 배포 떄마다 쉽게 변경할 수 있습니다. 설정 파일과 달리, 잘못해서 코드 저장소에 올라갈 가능성도 낮습니다. 또한, 커스텀 설정 파일이나 Java System Property와 같은 다른 설정 매커니즘과 달리 언어나 OS에 의존하지 않는 표준입니다. 설정 관리의 다른 측면은 그룹핑입니다. 종종 애플리케이션은 설정을 명명된 그룹("environments"라고도 함)으로 구성하기도 합니다. 해당 그룹은 Rails의 'development', 'test', 'production' environments처럼, 배포의 이름을 따서 명명됩니다. 이 방법은 깔끔하게 확장하기 어렵습니다. 응용 프로그램의 배포가 증가함에 따라, 'staging'이라던가 'qa'같은 새로운 그룹의 이름이 필요하게 됩니다. 프로젝트가 성장함에 따라, 개발자은 자기 자신의 그룹를 추가하게 됩니다. 결과적으로 설정이 각 그룹의 조합으로 폭발하게 되고, 애플리케이션의 배포를 불안정하게 만듭니다. From 0e824ac4bc4022d894fc4b7cb9c0b54bc88f0d9e Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 30 Mar 2015 09:13:28 +0100 Subject: [PATCH 119/472] update ruby version and gems --- Gemfile | 10 ++++++---- Gemfile.lock | 37 ++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index 3e1c8d5a0..a80d1ac97 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'http://rubygems.org' -gem 'sinatra', '1.2.6' -gem 'thin', '1.2.7' -gem 'maruku', '0.7.1' -gem 'i18n', '0.6.9' +ruby '2.2.1' + +gem 'sinatra' +gem 'thin' +gem 'maruku' +gem 'i18n' diff --git a/Gemfile.lock b/Gemfile.lock index 9a19d6b8b..65e9dc77a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,25 +1,28 @@ GEM remote: http://rubygems.org/ specs: - daemons (1.1.3) - eventmachine (0.12.10) - i18n (0.6.9) - maruku (0.7.1) - rack (1.3.0) - sinatra (1.2.6) - rack (~> 1.1) - tilt (>= 1.2.2, < 2.0) - thin (1.2.7) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) - tilt (1.3.2) + daemons (1.2.2) + eventmachine (1.0.7) + i18n (0.7.0) + maruku (0.7.2) + rack (1.6.0) + rack-protection (1.5.3) + rack + sinatra (1.4.6) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (>= 1.3, < 3) + thin (1.6.3) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0) + rack (~> 1.0) + tilt (2.0.1) PLATFORMS ruby DEPENDENCIES - i18n (= 0.6.9) - maruku (= 0.7.1) - sinatra (= 1.2.6) - thin (= 1.2.7) + i18n + maruku + sinatra + thin From 1fd98651009e5d429e355086219d8011fdd21c6e Mon Sep 17 00:00:00 2001 From: Francesco Malatesta Date: Mon, 30 Mar 2015 19:13:15 +0200 Subject: [PATCH 120/472] Italian translation add. --- content/it/admin-processes.md | 14 ++++++ content/it/background.md | 8 ++++ content/it/backing-services.md | 14 ++++++ content/it/build-release-run.md | 18 ++++++++ content/it/codebase.md | 17 ++++++++ content/it/concurrency.md | 14 ++++++ content/it/config.md | 22 ++++++++++ content/it/dependencies.md | 12 ++++++ content/it/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/it/disposability.md | 12 ++++++ content/it/intro.md | 12 ++++++ content/it/logs.md | 16 +++++++ content/it/port-binding.md | 14 ++++++ content/it/processes.md | 14 ++++++ content/it/toc.md | 38 +++++++++++++++++ content/it/who.md | 4 ++ locales/it.yml | 7 +++ 17 files changed, 312 insertions(+) create mode 100644 content/it/admin-processes.md create mode 100644 content/it/background.md create mode 100644 content/it/backing-services.md create mode 100644 content/it/build-release-run.md create mode 100644 content/it/codebase.md create mode 100644 content/it/concurrency.md create mode 100644 content/it/config.md create mode 100644 content/it/dependencies.md create mode 100644 content/it/dev-prod-parity.md create mode 100644 content/it/disposability.md create mode 100644 content/it/intro.md create mode 100644 content/it/logs.md create mode 100644 content/it/port-binding.md create mode 100644 content/it/processes.md create mode 100644 content/it/toc.md create mode 100644 content/it/who.md create mode 100644 locales/it.yml diff --git a/content/it/admin-processes.md b/content/it/admin-processes.md new file mode 100644 index 000000000..74f7e5ba4 --- /dev/null +++ b/content/it/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Processi di Amministrazione +### Esegui i task di amministrazione come processi una tantum + +La "[process formation](./concurrency)" è l'array dei processi che vengono usati durante le normali operazioni dell'applicazione (ad esempio, la gestione delle richieste web). Non è tutto, però: ci sono dei task che lo sviluppatore può voler eseguire, una volta ogni tanto. Ad esempio: + +* Esecuzione delle migration del database (esempi: `manage.py migrate` in Django, `rake db:migrate` in Rails). +* Esecuzione di una console (una [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) in modo tale da avviare del codice arbitrariamente o analizzare alcuni aspetti dell'applicazione specifici. Molti linguaggi prevedono una REPL, in genere avviando l'interprete senza opzioni ed argomenti aggiuntivi (esempi: `python` o `perl`) o in alcuni casi eseguibile con un comando separato (esempi: `irb` per Ruby, `rails console` per Rails). +* Esecuzione one-time di alcuni script specifici (esempio: `php scripts/fix_bad_records.php`). + +Tali processi dovrebbero essere avviati in un ambiente identico a quello in cui [lavorano gli altri](./processes) nel contesto dell'applicazione. Dovrebbero essere eseguiti quindi su una specifica [release](./build-release-run), partendo dalla stessa [codebase](./codebase) ed impostazioni di [configurazione](./config). Il codice per l'amministrazione dovrebbe inoltre essere incluso nel codice dell'applicazione, in modo tale da evitare qualsiasi problema di sincronizzazione. + +La stessa tecnica di [isolamento delle dipendenze](./dependencies) dovrebbe poter essere usata allo stesso modo su tutti i processi. Ad esempio, se il processo web di Ruby può usare il comando `bundle exec thin start`, una migration del database dovrebbe poter usare `bundle exec rake db:migrate` senza problemi. Allo stesso modo, un programma Python che usa Virtualenv dovrebbe usare il `bin/python` per eseguire sia i server Tornado che processi di amministrazione. + +La metodologia twelve-factor favorisce molto tutti quei linguaggi che offrono una shell REPL out of the box, rendendo quindi semplice l'esecuzione di script una tantum. In un deploy locale, gli sviluppatori possono invocare questi processi speciali tramite un semplice comando diretto. In un ambiente di produzione, invece, gli sviluppatori possono raggiungere lo stesso obiettivo tramite SSH o un qualsiasi altro sistema di esecuzione di comandi remoto. \ No newline at end of file diff --git a/content/it/background.md b/content/it/background.md new file mode 100644 index 000000000..19e5f254d --- /dev/null +++ b/content/it/background.md @@ -0,0 +1,8 @@ +Background +========== + +Chi ha scritto questo documento è stato coinvolto direttamente nella realizzazione e deploy di centinaia di applicazioni, ed indirettamente assistito allo sviluppo, operazioni e scaling di centinaia (o migliaia) di app tramite il proprio lavoro sulla piattaforma [Heroku](http://www.heroku.com/). + +Questo documento riassume tutta quella che è stata la nostra esperienza, basata sull'osservazione di un grande numero di applicazioni SaaS. Si tratta di una "triangolazione" di pratiche di sviluppo ideali (con una particolare attenzione alla crescita organica dell'app nel tempo), la collaborazione dinamica nel corso del tempo tra gli sviluppatori sulla codebase e la necessità di evitare i costi di [software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +La nostra motivazione è di far crescere la consapevolezza intorno ad alcuni problemi sistemici che abbiamo scoperto nello sviluppo di applicazioni moderne, cercando di fornire un vocabolario condiviso per la discussione di tali problemi. Oltre, ovviamente, ad offrire delle soluzioni concettuali a queste situazioni (senza però tralasciare il fattore tecnologia). Questo format si rifà ai libri di Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file diff --git a/content/it/backing-services.md b/content/it/backing-services.md new file mode 100644 index 000000000..0a8ee8109 --- /dev/null +++ b/content/it/backing-services.md @@ -0,0 +1,14 @@ +## IV. Backing Service +### Tratta i backing service come "risorse" + +Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](http://kr.github.com/beanstalkd/)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). + +Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), ed anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). + +**Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). Ad un qualsiasi [deploy](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale ad uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. + +Ogni backing service è quindi definibile come una "risorsa connessa". Un Database MySQL è una risorsa. Due database MySQL (utilizzati per lo sharding a livello di applicazione) saranno visti come due distinte risorse. Un'app twelve-factor vede questi database come *risorse* anche per sottolineare la separazione dal deploy a cui fanno riferimento. + +Un deploy di produzione collegato a quattro backing service. + +Le risorse possono essere collegate e scollegate da un deploy a piacimento. Ad esempio, supponiamo che il database dell'applicazione si comporti in modo anomalo per problemi hardware. L'amministratore potrebbe decidere di voler configurare un altro server di database ripreso da un recente backup. Il vecchio database verrebbe scollegato, quello nuovo connesso -- senza modifiche al codice. \ No newline at end of file diff --git a/content/it/build-release-run.md b/content/it/build-release-run.md new file mode 100644 index 000000000..abe85269d --- /dev/null +++ b/content/it/build-release-run.md @@ -0,0 +1,18 @@ +## V. Build, release, esecuzione +### Separare in modo netto lo stadio di build dall'esecuzione + +Una [codebase](./codebase) viene "trasformata" in deploy attraverso tre fasi: + +* la fase di *build*, che converte il codice del repo in una build "eseguibile". Usando una certa versione del codice, ad una specifica commit, nella fase di build vengono compilati i binari con gli asset appropriati includendo anche le eventuali dipendenze; +* la fase di *release* prende la build prodotta nella fase precedente e la combina con l'attuale insieme di impostazioni di configurazione del deploy specifico. La *release* risultante contiene sia la build che le impostazioni; +* la fase di *esecuzione* (conosciuta anche come "runtime") vede l'applicazione in esecuzione nell'ambiente di destinazione, attraverso l'avvio di processi della release scelta; + +![Il codice diventa build, che combinata con le impostazioni diventa release.](/images/release.png) + +**Un'app twelve-factor definisce una separazione netta tra build, release ed esecuzione.** Ad esempio, è impossibile effettuare dei cambiamenti del codice a runtime, dato che non c'è modo di propagare queste modifiche all'"indietro", verso la fase di build. + +I tool di deploy offrono tipicamente dei tool di gestione delle release, in particolare alcuni dedicati ad un rollback verso una release precedente. Ad esempio, [Capistrano](https://github.com/capistrano/capistrano/wiki) memorizza le varie release in una sotto-directory chiamata `releases`, in cui la release attuale non è che un symlink verso la directory della release attuale. Il comando di rollback permette di tornare indietro ad una certa release velocemente. + +Ogni release dovrebbe inoltre possedere un ID univoco di rilascio, come ad esempio un timestamp (es. `2011-04-06-20:32:17`) o un numero incrementale (es. `v100`). In un certo senso, la creazione di una release è una procedura "a senso unico" e una certa release non può essere modificata dopo la sua creazione. Qualsiasi cambiamento deve quindi prevedere una nuova release. + +Una fase di build è sempre avviata da uno sviluppatore, non appena il codice viene modificato. Al contrario, l'esecuzione può essere anche gestita in modo automatico (si pensi al riavvio del server oppure ad un crash con successivo riavvio del processo). Ad ogni modo, una volta in esecuzione, la regola aurea è di evitare il più possibile (se non del tutto) modifiche che potrebbero rompere qualche equilibrio. Magari nel bel mezzo della notte, quando non c'è nessuno disponibile. La fase di build può essere sicuramente più "faticosa", comunque, visto che possono verificarsi degli errori da risolvere prima di proseguire. \ No newline at end of file diff --git a/content/it/codebase.md b/content/it/codebase.md new file mode 100644 index 000000000..e4f2c4bf3 --- /dev/null +++ b/content/it/codebase.md @@ -0,0 +1,17 @@ +## I. Codebase +### Una sola codebase sotto controllo di versione, tanti deploy + +Un'app conforme alla metodologia twelve-factor è sempre sotto un sistema di controllo di versione, sia essa [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). Una copia della codebase è detta *code repository*, oppure più in breve *code repo* o *repo*. + +Una *codebase* è quindi un singolo repository (in un sistema centralizzato come Subversion), oppure un set di repo che condividono una root commit (in un sistema di controllo decentralizzato come Git). + +![Una codebase, N deploy](/images/codebase-deploys.png) + +C'è sempre una relazione uno-ad-uno tra codebase ed applicazione: + +* Se ci sono più codebase, non si parla più di applicazione ma di sistema distribuito. Ogni componente in un sistema distribuito è un'applicazione, ed ognuna di queste applicazioni può individualmente aderire alla metodologia twelve-factor. +* Se più applicazioni condividono lo stesso codice si ha una violazione del twelve-factor. La soluzione è, ovviamente, quella di sistemare il codice in modo adeguato, in modo tale da essere incluso eventualmente dove necessario tramite un [dependency manager](./dependencies). + +Quindi: una sola codebase per applicazione, ma ci saranno comunque tanti deploy della stessa app. Per *deploy* si intende un'istanza dell'applicazione. Può essere il software in produzione, oppure una delle varie istanze in staging. Ancora, un deploy può essere la copia posseduta dal singolo sviluppatore nel suo ambiente locale. + +La codebase rimane comunque sempre la stessa su tutti i deploy, anche se potrebbero essere attive diverse versioni nello stesso istante. Si pensi ad esempio ad uno sviluppatore che possiede dei commit in più che non ha ancora mandato in staging. Nonostante questo, comunque, rimane la condivisione della stessa codebase, nonostante la possibilità di avere più deploy della stessa app. \ No newline at end of file diff --git a/content/it/concurrency.md b/content/it/concurrency.md new file mode 100644 index 000000000..85e2bb9b1 --- /dev/null +++ b/content/it/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concorrenza +### Scalare attraverso il process model + +Ogni software, una volta avviato, è rappresentato da uno o più processi. Le web application in particolare hanno assunto nel tempo una gran varietà di forme e di tipologie di esecuzione, in tal senso. Ad esempio, i processi PHP vengono eseguiti come sotto-processi figli di Apache, avviati su richiesta quando necessari in base al volume di richieste. Java invece gestisce le cose nella maniera opposta, tramite un superprocesso unico che usa una grande quantità di risorse sul server (CPU e memoria) dall'avvio, con una concorrenza gestita "internamente" tramite i threads. In entrambi i casi, comunque, i processi non sono esplicitamente visibili allo sviluppatore. + +![Il fattore di scale è espresso con un numero di processi dello stesso tipo avviati, la diversità del carico di lavoro, invece, come le varie tipologie di processo.](/images/process-types.png) + +**In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro ad un tipo di processo ben definito. Ad esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. + +Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo ed interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. + +Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice ed affidabile. L'array dei tipi di processo ed il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). + +I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [Upstart](http://upstart.ubuntu.com/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. \ No newline at end of file diff --git a/content/it/config.md b/content/it/config.md new file mode 100644 index 000000000..2ef8dc89e --- /dev/null +++ b/content/it/config.md @@ -0,0 +1,22 @@ +## III. Configurazione +### Memorizza le informazioni di configurazione nell'ambiente + +La "configurazione" di un'applicazione è tutto quello che può variare da un [deploy](./codebase) all'altro (staging, production, ambienti di sviluppo). Ad esempio: + +* Valori da usare per connettersi ad un database, Memcached, oppure altri [backing service](./backing-services); +* Credenziali per servizi esterni, come Amazon S3 o Twitter; +* Valori eventualmente definiti per i singoli deploy, come l'hostname; + +Molto spesso, queste informazioni vengono memorizzate come costanti nel codice: la cosa viola la metodologia twelve-factor, che richiede una **separazione ben definita delle impostazioni di configurazione dal codice**. Le impostazioni possono infatti variare da un deploy all'altro: il codice, invece, no. + +Il codice dell'applicazione, infatti, potrebbe essere reso open-source in ogni momento: un buon motivo per separare le due cose. + +Nota che comunque la definizione di "configurazione" **non** include eventuali configurazione interne dell'applicazione, come `config/routes.rb` in Rails, o come [i moduli di codice sono connessi](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). Questo tipo di configurazione non varia da deploy a deploy: come giusto che sia, quindi, rimane nel codice. + +Un ottimo approccio al "rispetto" di questo principio consiste nell'usare dei file di configurazione non coinvolti dal version control, come ad esempio `config/database.yml` in Rails. Stiamo parlando di un miglioramento enorme rispetto all'uso di costanti nel codice, ma c'è da dire la cosa ha il suo lato negativo: basta poco per sbagliarsi ed includere nel repo il file di configurazione che, invece, non dovrebbe essere lì. C'è una certa tendenza, infatti, a non avere tutti i file di configurazione necessari nello stesso posto. Inoltre, i vari formati tendono ad essere collegati ad un certo linguaggio/framework. + +**L'applicazione che rispetta la metodologia twelve-factor memorizza tutte le impostazioni in *variabili d'ambiente*** (spesso dette *env vars* o *env*). Le variabili d'ambiente sono molto semplici da cambiare di deploy in deploy senza dover toccare il codice direttamente. Inoltre, a differenza dei file di configurazione classici, c'è una probabilità molto bassa di venire inclusi nel repo. Infine, questi file sono indipendenti sia dal linguaggio che dal sistema operativo utilizzato. + +Un altro aspetto del config management è il raggruppamento. A volte, infatti, alcune applicazioni prevedono la memorizzazione delle impostazioni in gruppi (chiamati spesso "ambienti") dal nome ben preciso: "development", "test" e "production", ad esempio. Questo metodo non scala correttamente, se ci pensi: potrebbero essere necessari nuovi ambienti, come "staging" e "qa". Oppure, i vari sviluppatori potrebbero aver bisogno di creare i propri ambienti "speciali", come "joes-staging" e così via. Il risultato? Una quantità di combinazioni ingestibile e disordinata. + +In una buona twelve-factor app, le variabili di ambiente sono controllate in modo più "granulare", in modo totalmente ortogonale alle altre. Non sono mai raggruppate e classificate sotto "ambienti" specifici, ma vengono gestite in modo totalmente indipendente per ogni deploy. Il prodotto finale ne risente positivamente in termini di scalabilità. \ No newline at end of file diff --git a/content/it/dependencies.md b/content/it/dependencies.md new file mode 100644 index 000000000..8b86314d2 --- /dev/null +++ b/content/it/dependencies.md @@ -0,0 +1,12 @@ +## II. Dipendenze +### Dipendenze dichiarate ed isolate + +Molti linguaggi di programmazione offrono dei sistemi di packaging per la distribuzione delle proprie librerie, come [CPAN](http://www.cpan.org/) per Perl o [Rubygems](http://rubygems.org/) per Ruby. Le librerie installate attraverso questi sistemi, inoltre, possono essere identificate come "system-wide" (attive a livello di sistema), oppure posizionate nella directory della singola applicazione (in questo caso si parla di "vendoring" o "bundling"). + +**Un'applicazione che aderisce alla twelve-factor non si basa mai sull'esistenza implicita di librerie system-wide**. Le dipendenze vengono tutte dichiarate, tramite un manifest dedicato. Inoltre, viene contemplato anche l'uso di un tool di *isolamento delle dipendenze* durante l'esecuzione, in modo tale da assicurarsi che non ci siano delle "dipendenze implicite" che creino interferenze nel sistema in cui ci si trova. La specifica completa ed esplicita delle dipendenze si applica in modo uniforme: sia in production che in sviluppo. + +Ad esempio, [Gem Bundler](http://gembundler.com/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. + +Un altro importante beneficio di una dichiarazione esplicita delle dipendenze sta nel fatto che semplifica di molto la configurazione iniziale per gli sviluppatori appena entrati a lavorare al progetto. Il nuovo arrivato non dovrà fare altro che effettuare un check out della codebase nella propria macchina di sviluppo, occupandosi di dover installare solo ed esclusivamente le dipendenze, appunto, dichiarate. Molto spesso è inoltre presente un *build command* che permette di automatizzare il processo. Per Ruby/Bundler si usa `bundle install`, mentre per Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'è `lein deps`. + +Ogni applicazione che aderisce alla metodologia twelve-factor, inoltre, non si basa mai sull'esistenza di un qualsiasi tool di sistema. Alcuni esempi sono *ImageMagick* o *curl*. Nonostante questi software esistano già su buona parte dei sistemi in circolazione, non è comunque detto che siano presenti su tutti quelli su cui girerà l'applicazione in futuro. Se l'app non può fare a meno di questo tool, si dovrebbe prendere in considerazione l'idea di "vendorizzarlo" nell'applicazione stessa. \ No newline at end of file diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md new file mode 100644 index 000000000..94cd34ce1 --- /dev/null +++ b/content/it/dev-prod-parity.md @@ -0,0 +1,76 @@ +## 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 ad un [deploy](./codebase) in locale) e quello di produzione (un deploy 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 deploy; +* **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite ed OS X, mentre in produzione per il deploy verrebbero installati Apache, MySQL e Linux. + +**Un'applicazione twelve-factor è progettata per il [rilascio continuo](http://www.avc.com/a_vc/2011/02/continuous-deployment.html), 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 TradizionaleApp Twelve-factor
Tempo tra i DeploySettimaneOre
Sviluppatori e OpsSono diversiSono gli stessi/td> +
Sviluppo e ProduzioneDivergentiIl 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: + + + + + + + + + + + + + + + + + + + + + + + + + + +
TipologiaLinguaggioLibreriaAdattatore
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
CodePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, 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. Ad esempio, usando SQLite localmente e PostgreSQL in produzone. 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 ed usare senza difficoltà tramite alcuni sistemi di packaging come [Homebrew](http://mxcl.github.com/homebrew/) ed [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 deploy. + +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 deploy di un'applicazione. \ No newline at end of file diff --git a/content/it/disposability.md b/content/it/disposability.md new file mode 100644 index 000000000..876d59cd3 --- /dev/null +++ b/content/it/disposability.md @@ -0,0 +1,12 @@ +## IX. Rilasciabilità +### Massimizzare la robustezza con avvii veloci e shutdown graduali + +**I [processi](./processes) di un'applicazione twelve-factor sono *rilasciabili*, cioè possono essere avviati o fermati senza problemi al momento del bisogno.** Questa caratteristica ovviamente facilita le procedure di scaling, deploy rapido della [codebase](./codebase) o cambi dei file di [configurazione](./config). + +I processi dovrebbero inoltre ambire a **minimizzare i tempi di avvio**. Idealmente, un processo impiega pochi secondi dal tempo di lancio al momento in cui tutto è pronto per ricevere nuove richieste. Dei tempi brevi di avvio inoltre forniscono una maggiore agilità in fase di [release](./build-release-run); il tutto a vantaggio della robustezza dell'applicazione, dato che il process manager può così muoversi agevolmente verso un'altra macchina fisica, se necessario. + +I processi dovrebbero inoltre **terminare in modo tutt'altro che brusco, quindi graduale, in caso di ricezione di un segnale [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** dal process manager. Per un'applicazione web, la giusta terminazione di un processo viene ottenuta quando si cessa innanzitutto di ascoltare sulla porta dedicata del servizio (evitando quindi di ricevere altre richieste), permettendo poi di terminare le richieste esistenti ed infine di concludere la fase di terminazione in modo definitivo. + +Per un processo worker, invece, la fase di terminazione più adatta vede il ritorno del job corrente alla coda. Ad esempio, su [RabbitMQ](http://www.rabbitmq.com/) il worker può inviare un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); su [Beanstalkd](http://kr.github.com/beanstalkd/), il job viene automaticamente rimandato in coda nel caso in cui il worker si disconnette. I sistemi basati su lock come [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) prevedono una "messa in sicurezza" prima di rilasciare il loro lock sul record del job attuale. Basandosi su questo modello risulta implicito che tutti i vari job sono di tipo [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), obiettivo raggiungibile wrappando il risultato in una transazione o rendendo l'operazione [idempotente](http://en.wikipedia.org/wiki/Idempotence). + +I processi dovrebbero, inoltre, essere "robusti nei confronti di situazioni di crash improvviso", cosa che si verifica ad esempio in caso di problemi a livello di hardware sottostante. Nonostante questa seconda evenienza si verifichi meno frequentemente di una chiusura con `SIGTERM`, può comunque succedere. L'approccio raccomandato, in questi casi, è l'uso di un sistema robusto di code, come Beanstalkd, che rimanda il job in coda in caso di timeout o disconnessione. Ad ogni modo, una buona applicazione twelve-factor deve poter gestire senza problemi le terminazioni inaspettate. Il [Crash-only design](http://lwn.net/Articles/191059/) porta questo concetto alla sua [logica conclusione](http://docs.couchdb.org/en/latest/intro/overview.html). \ No newline at end of file diff --git a/content/it/intro.md b/content/it/intro.md new file mode 100644 index 000000000..2574ae917 --- /dev/null +++ b/content/it/intro.md @@ -0,0 +1,12 @@ +Introduzione +============ + +Nell'era moderna, il software viene fornito sempre più di frequente come servizio (delivered as a service): si parla di *web app* o *software as a service* (SaaS). La **twelve-factor app** è una metodologia di sviluppo orientata alla costruzione di applicazioni software-as-a-service che: + +* Seguono un formato **dichiarativo** per l'automazione della configurazione, minimizzando tempi e costi di ingresso per ogni sviluppatore che si aggiunge al progetto; +* **Si interfacciano in modo pulito** con il sistema operativo sottostante, in modo tale da offrire la **massima portabilità** sui vari ambienti di esecuzione; +* Sono **adatti allo sviluppo** sulle più recenti **cloud platform**, ovviando alla necessità di server ed amministrazioni di sistema; +* **Minimizzano la divergenza** tra sviluppo e produzione, permettendo il **contiuous deployment** per una massima "agilità"; +* Possono **scalare significativamente** senza troppi cambiamenti ai tool, all'architettura e al processo di sviluppo; + +La metodologia twelve-factor può essere applicata ad ogni software, scritto in qualsiasi linguaggio di programmazione, che fa uso di una serie di servizi come database, code, cache e così via. \ No newline at end of file diff --git a/content/it/logs.md b/content/it/logs.md new file mode 100644 index 000000000..ae6e901f5 --- /dev/null +++ b/content/it/logs.md @@ -0,0 +1,16 @@ +## 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). Ad ogni modo, è solo un formato. + +Un log può essere definito infatti come uno [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) di eventi aggregati ed 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 i 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 ed 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 [Fluent](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 ad un sistema di analisi ed indicizzazione di log, come [Splunk](http://www.splunk.com/), oppure ad 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 ad 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); \ No newline at end of file diff --git a/content/it/port-binding.md b/content/it/port-binding.md new file mode 100644 index 000000000..536c2c071 --- /dev/null +++ b/content/it/port-binding.md @@ -0,0 +1,14 @@ +## VII. Binding delle Porte +### Esporta i servizi tramite binding delle porte + +Normalmente, le applicazioni web sono qualcosa di eseguito all'interno di un server web, che fa da contenitore. Ad esempio, le applicazioni PHP possono venire eseguite come modulo all'interno di [Apache HTTPD](http://httpd.apache.org/), così come un'applicazione Java viene eseguita in [Tomcat](http://tomcat.apache.org/). + +**L'applicazione twelve-factor** è completamente self-contained (contenuta in se stessa) e non si affida ad un altro servizio (come appunto un webserver) nell'ambiente di esecuzione. La web app **esporta HTTP come un servizio effettuando un binding specifico ad una porta**, rimanendo in ascolto su tale porta per le richieste in entrata. + +In un ambiente di sviluppo locale, lo sviluppatore accede al servizio tramite un URL come `http://localhost:5000/`. In fase di deploy, invece, un layer di routing gestisce le richieste da un hostname pubblico alla specifica porta desiderata. + +Tale funzionalità viene, frequentemente, implementata tramite [dichiarazione delle opportune dipendenze](./dependencies), aggiungendo una libreria webserver all'applicazionecome [Tornado](http://www.tornadoweb.org/) per Python, [Thin](http://code.macournoyer.com/thin/) per Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) per Java ed altri linguaggi basati su JVM. L'evento, nella sua interezza, "ha luogo" nello spazio dell'utente, nel codice dell'applicazione. + +HTTP non è l'unico servizio che può essere esportato tramite port binding. In realtà quasi ogni tipo di software può essere eseguito tramite uno specifico binding tra processo e porta dedicata. Alcuni esempi includono [ejabberd](http://www.ejabberd.im/) (a tal proposito, leggere su [XMPP](http://xmpp.org/)), e [Redis](http://redis.io/) (a proposito del [protoccolo Redis](http://redis.io/topics/protocol)). + +Nota inoltre che usare il binding delle porte permette ad un'applicazione di diventare il backing service di un'altra applicazione, tramite un URL dedicato o comunque come una risorsa la cui configurazione si può gestire tramite appositi file di [config](./config) dell'app consumer del servizio. \ No newline at end of file diff --git a/content/it/processes.md b/content/it/processes.md new file mode 100644 index 000000000..06afde1d9 --- /dev/null +++ b/content/it/processes.md @@ -0,0 +1,14 @@ +## VI. Processi +### Esegui l'applicazione come uno o più processi stateless + +L'app viene eseguita nell'ambiente di esecuzione come uno o più *processi*. + +Nel caso più semplice, il codice non è che uno script stand-alone, l'ambiente di esecuzione è il laptop dello sviluppatore ed il processo viene lanciato tramite linea di comando (ad esempio, `python my_script.py`). Tuttavia, il deploy in produzione di un'app sofisticata potrebbe usare più [tipologie di processo, istanziate in zero o più processi](./concurrency). + +***I processi twelve-factor sono stateless (senza stato) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Tutti i dati che devono persistere devono essere memorizzati in un [backing service](./backing-services), come ad esempio un database. + +Lo spazio di memoria o il filesystem di un processo possono essere visti come una "singola transazione" breve. Come il download di un file, le successive operazioni su di esso ed infine la memorizzazione del risultato sul database. Un'app twelve-factor non assume mai che qualsiasi cosa messa in cache sarà poi disponibile successivamente -- con tanti processi in esecuzione, le possibilità che una certa richiesta venga servita da un altro processo sono molto alte. Comunque, anche nel caso in cui si usi un singolo processo in esecuzione, un riavvio (dovuto a deploy di codice, cambio di file di configurazione e così via) resetterà lo stato in cui si trova il sistema. + +I packager di asset (come [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usano il filesystem come cache per gli asset compilati. Un'app twelve-factor vuole questa compilazione durante la [fase di build](./build-release-run), così come [l'asset pipeline di Rails](http://guides.rubyonrails.org/asset_pipeline.html), e non a runtime. + +Alcuni sistemi web si basano inoltre sulle cosiddette ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- che consistono nel mettere in cache i dati di sessione dell'utente presenti nella memoria del processo, aspettandosi future richieste identiche dallo stesso visitatore, venendo quindi reindirizzati allo stesso processo. Le sticky session sono una palese violazione della metodologia twelve-factor. I dati di sessione sono un ottimo candidato per quei sistemi di datastore che offrono la feature di scadenza, come [Memcached](http://memcached.org/) o [Redis](http://redis.io/). \ No newline at end of file diff --git a/content/it/toc.md b/content/it/toc.md new file mode 100644 index 000000000..c04592c15 --- /dev/null +++ b/content/it/toc.md @@ -0,0 +1,38 @@ +I "Dodici Fattori" +================== + +## [I. Codebase](./codebase) +### Una sola codebase sotto controllo di versione, tanti deploy + +## [II. Dipendenze](./dependencies) +### Dipendenze dichiarate ed isolate + +## [III. Configurazione](./config) +### Memorizza le informazioni di configurazione nell'ambiente + +## [IV. Backing Service](./backing-services) +### Tratta i backing service come "risorse" + +## [V. Build, release, esecuzione](./build-release-run) +### Separare in modo netto lo stadio di build dall'esecuzione + +## [VI. Processi](./processes) +### Esegui l'applicazione come uno o più processi stateless + +## [VII. Binding delle Porte](./port-binding) +### Esporta i servizi tramite binding delle porte + +## [VIII. Concorrenza](./concurrency) +### Scalare attraverso il process model + +## [IX. Rilasciabilità](./disposability) +### Massimizzare la robustezza con avvii veloci e chiusure non brusche + +## [X. Parità tra Sviluppo e Produzione](./dev-prod-parity) +### Mantieni lo sviluppo, staging e produzione simili il più possibile + +## [XI. Log](./logs) +### Tratta i log come stream di eventi + +## [XII. Processi di Amministrazione](./admin-processes) +### Esegui i task di amministrazione/management come processi una tantum \ No newline at end of file diff --git a/content/it/who.md b/content/it/who.md new file mode 100644 index 000000000..ed88b2651 --- /dev/null +++ b/content/it/who.md @@ -0,0 +1,4 @@ +A chi è destinato questo documento? +============================== + +Ad ogni sviluppatore che costruisce applicazioni SaaS (Software As a Service), e ad ogni ops che effettua il deploy e gestisce queste applicazioni. \ No newline at end of file diff --git a/locales/it.yml b/locales/it.yml new file mode 100644 index 000000000..e16ec3c69 --- /dev/null +++ b/locales/it.yml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: Italiano + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Questo testo è una traduzione della versione originale in Inglese." From d6222c0e01e55602802cb3845cce483a765a24e9 Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 2 May 2015 21:42:08 -0300 Subject: [PATCH 121/472] add processes --- content/pt_br/processes.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index dd13c37f2..66d63fffb 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -1,15 +1,17 @@ -## VI. Processes -### Execute the app as one or more stateless processes +## VI. Processos +### Execute a aplicação como um ou mais processos que não armazenam estado -The app is executed in the execution environment as one or more *processes*. +A aplicação é executada em um ambiente de exeução como um ou mais *processos*. -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). +No caso mais simples, o código é um script autônomo, o ambiente de excução é o laptop local de um desenvolvedor com o runtime da linguagem instalado, e o processo é iniciado pela linha de comando (por exemplo, `python my_script`). Na outra extremidade do espectro, o deploy em produção de uma aplicação sofisticada pode utilizar vários [tipos de processos, instanciado em zero ou mais processos em andamento](./concurrency). -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. +**Processos twelve-factor são stateless(não armazenam estado) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Quaisquer dados que precise persistir deve ser armazenado em um serviço de apoio stateful(que amazena o seu estado), tipicamente uma base de dados. -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. +O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transacção única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação twelve-factor nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em um futuro request ou job -- com muitos processos de cada tipo rodando, as chances são altas de que um futuro request será servido por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), rather than at runtime. +Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação twelve-factor prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do twelve-factor e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). + From 061d3aeb7a7859c4506cef63b0c4b34efb5db64f Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 2 May 2015 21:45:00 -0300 Subject: [PATCH 122/472] tranlate config.md --- content/pt_br/config.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index 2d2ff384b..ae480e620 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -1,23 +1,22 @@ -## III. Config -### Store config in the environment +## III. Configurações +### Armazene as configurações no ambiente -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: +A *configuração* de uma aplicação é tudo o que é provável variar entre [deploys](/codebase) (teste, produção, ambientes de desenvolvimento, etc). Isto inclui: -* Resource handles to the database, Memcached, and other [backing services](./backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy +* Recursos para a base de dados, Memcached, e outros [serviços de apoio](/backing-services) +* Credenciais para serviços externos como Amazon S3 ou Twitter +* Valores por deploy como o nome canônico do host para o deploy -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. +Aplicações as vezes armazenam as configurações no código como constantes. Isto é uma violação do twelve-factor, o que exige uma **estrita separação da configuração a partir do código**. Configuração varia substancialmente entre deploys, código não. -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. +A prova de fogo para saber se uma aplicação tem todas as configurãções corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). This type of config does not vary between deploys, and so is best done in the code. +Note que esta definição de "configuração" **não** inclui configuração interna da aplicação, como `config/routes.rb` em Rails, ou como [módulos de códigos são conectados](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) em [Spring](http://www.springsource.org/). Este tipo de configuração não varia entre deploys, e por isso é melhor que seja feito no código. -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. +Outra abordagem para configuração é o uso de arquivos de configuração que não são verificados no controle de revisão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são verificadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. +**A aplicação twelve-factor armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código. ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. - -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments," but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamadas de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. +Em uma aplicação twelve-factor, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas como a aplicação que se expande naturalmente em muitos deploys durante seu ciclo de vida. From 6618909edba26c83aa2e2bc2747ae6e37502a8dd Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 2 May 2015 22:46:12 -0300 Subject: [PATCH 123/472] add paragraph 1,2 and 3 --- content/pt_br/concurrency.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index 5ae4706b9..8b5ef1914 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -1,11 +1,11 @@ -## VIII. Concurrency -### Scale out via the process model +## VIII. Concorrência +### Escale através do processo modelo -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. +Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processo PHP rodam como processos filho do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicilização, com concorrência gerenciada internamente via threads. Em ambos os casos, o processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) +![Escala é expressado como processos em execução, a diversidade da carga de trabalho é expressada como tipos de processo.](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**Na aplicação twelve-factor, processos são cidadãos de primeira classe.** Processos na aplicação twelve-factor tomam fortes sinais do [modelo de processo unix para a execução de serviços daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. From cfb6ba6906ad76c000cfeccb442e7fdba04fb15c Mon Sep 17 00:00:00 2001 From: George Moura Date: Sat, 2 May 2015 22:50:04 -0300 Subject: [PATCH 124/472] update spring links --- content/pt_br/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index ae480e620..0ad7baa70 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -11,7 +11,7 @@ Aplicações as vezes armazenam as configurações no código como constantes. I A prova de fogo para saber se uma aplicação tem todas as configurãções corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. -Note que esta definição de "configuração" **não** inclui configuração interna da aplicação, como `config/routes.rb` em Rails, ou como [módulos de códigos são conectados](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) em [Spring](http://www.springsource.org/). Este tipo de configuração não varia entre deploys, e por isso é melhor que seja feito no código. +Note que esta definição de "configuração" **não** inclui configuração interna da aplicação, como `config/routes.rb` em Rails, ou como [módulos de códigos são conectados](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) em [Spring](http://spring.io/). Este tipo de configuração não varia entre deploys, e por isso é melhor que seja feito no código. Outra abordagem para configuração é o uso de arquivos de configuração que não são verificados no controle de revisão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são verificadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. From cb9208dff2f1029b1931a8592c9ed7ccb3a4524c Mon Sep 17 00:00:00 2001 From: George Moura Date: Sun, 3 May 2015 17:40:45 -0300 Subject: [PATCH 125/472] ajustes informados pelo @lfilho --- content/pt_br/config.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index 0ad7baa70..4dece4261 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -1,7 +1,7 @@ ## III. Configurações ### Armazene as configurações no ambiente -A *configuração* de uma aplicação é tudo o que é provável variar entre [deploys](/codebase) (teste, produção, ambientes de desenvolvimento, etc). Isto inclui: +A *configuração* de uma aplicação é tudo o que é provável variar entre [deploys](/codebase) (homologação, produção, ambientes de desenvolvimento, etc). Isto inclui: * Recursos para a base de dados, Memcached, e outros [serviços de apoio](/backing-services) * Credenciais para serviços externos como Amazon S3 ou Twitter @@ -9,14 +9,14 @@ A *configuração* de uma aplicação é tudo o que é provável variar entre [d Aplicações as vezes armazenam as configurações no código como constantes. Isto é uma violação do twelve-factor, o que exige uma **estrita separação da configuração a partir do código**. Configuração varia substancialmente entre deploys, código não. -A prova de fogo para saber se uma aplicação tem todas as configurãções corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. +A prova de fogo para saber se uma aplicação tem todas as configurações corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. Note que esta definição de "configuração" **não** inclui configuração interna da aplicação, como `config/routes.rb` em Rails, ou como [módulos de códigos são conectados](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) em [Spring](http://spring.io/). Este tipo de configuração não varia entre deploys, e por isso é melhor que seja feito no código. -Outra abordagem para configuração é o uso de arquivos de configuração que não são verificados no controle de revisão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são verificadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. +Outra abordagem para configuração é o uso de arquivos de configuração que não são versionados no controle de versão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são versionadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. **A aplicação twelve-factor armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código. ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. -Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamadas de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. +Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. -Em uma aplicação twelve-factor, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas como a aplicação que se expande naturalmente em muitos deploys durante seu ciclo de vida. +Em uma aplicação twelve-factor, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. From 3731a058e69bed3b7ef0d054ea60a014dfcd09f1 Mon Sep 17 00:00:00 2001 From: George Moura Date: Sun, 3 May 2015 17:48:23 -0300 Subject: [PATCH 126/472] =?UTF-8?q?ajustes=20no=20erros=20de=20portugu?= =?UTF-8?q?=C3=AAs=20identificados=20por=20mim=20e=20pelo=20@lfilho;=20rem?= =?UTF-8?q?o=C3=A7=C3=A3o=20do=20par=C3=A1grafo=20em=20ingl=C3=AAs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/processes.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index 66d63fffb..b05eaf8b5 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -1,17 +1,15 @@ ## VI. Processos ### Execute a aplicação como um ou mais processos que não armazenam estado -A aplicação é executada em um ambiente de exeução como um ou mais *processos*. +A aplicação é executada em um ambiente de execução como um ou mais *processos*. -No caso mais simples, o código é um script autônomo, o ambiente de excução é o laptop local de um desenvolvedor com o runtime da linguagem instalado, e o processo é iniciado pela linha de comando (por exemplo, `python my_script`). Na outra extremidade do espectro, o deploy em produção de uma aplicação sofisticada pode utilizar vários [tipos de processos, instanciado em zero ou mais processos em andamento](./concurrency). +No caso mais simples, o código é um script autônomo, o ambiente de execução é o laptop local de um desenvolvedor com o runtime da linguagem instalado, e o processo é iniciado pela linha de comando (por exemplo, `python my_script`). Na outra extremidade do espectro, o deploy em produção de uma aplicação sofisticada pode utilizar vários [tipos de processos, instanciado em zero ou mais processos em andamento](./concurrency). -**Processos twelve-factor são stateless(não armazenam estado) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Quaisquer dados que precise persistir deve ser armazenado em um serviço de apoio stateful(que amazena o seu estado), tipicamente uma base de dados. +**Processos twelve-factor são stateless(não armazenam estado) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Quaisquer dados que precise persistir deve ser armazenado em um serviço de apoio stateful(que armazena o seu estado), tipicamente uma base de dados. -O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transacção única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação twelve-factor nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em um futuro request ou job -- com muitos processos de cada tipo rodando, as chances são altas de que um futuro request será servido por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). +O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transação única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação twelve-factor nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em uma futura solicitação ou job -- com muitos processos de cada tipo rodando, as chances são altas de que uma futura solicitação será servida por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). -Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação twelve-factor prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. - -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação twelve-factor prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do twelve-factor e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). From c9bb13f8a22fce06dfdc8ac6a2b246bd3836c20a Mon Sep 17 00:00:00 2001 From: George Moura Date: Sun, 3 May 2015 21:49:55 -0300 Subject: [PATCH 127/472] add new paragraph --- content/pt_br/concurrency.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index 8b5ef1914..2ee8c34f3 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -1,14 +1,16 @@ ## VIII. Concorrência ### Escale através do processo modelo -Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processo PHP rodam como processos filho do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicilização, com concorrência gerenciada internamente via threads. Em ambos os casos, o processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. +Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processo PHP rodam como processos filho do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. ![Escala é expressado como processos em execução, a diversidade da carga de trabalho é expressada como tipos de processo.](/images/process-types.png) **Na aplicação twelve-factor, processos são cidadãos de primeira classe.** Processos na aplicação twelve-factor tomam fortes sinais do [modelo de processo unix para a execução de serviços daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação twelve-factor](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. + +Processos de uma app twelve-factor [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. From 0dcd5d44aec1ed5da8c4f024f07f50b392e06e27 Mon Sep 17 00:00:00 2001 From: George Moura Date: Mon, 4 May 2015 07:35:16 -0300 Subject: [PATCH 128/472] add last paragraph --- content/pt_br/concurrency.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index 2ee8c34f3..e89efcc66 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -11,6 +11,4 @@ Isto não exclui processos individuais da manipulação de sua própria multiple O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação twelve-factor](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. -Processos de uma app twelve-factor [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), - -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +Processos de uma app twelve-factor [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário. From f9850c47c92e6b3a2dd8571546c4c90280e2841d Mon Sep 17 00:00:00 2001 From: Eugeny Vlasenko Date: Sun, 9 Mar 2014 17:01:22 +0700 Subject: [PATCH 129/472] russian translation, logs part --- content/ru/logs.md | 16 ++++++++++++++++ locales/ru.yml | 7 +++++++ 2 files changed, 23 insertions(+) create mode 100644 content/ru/logs.md create mode 100644 locales/ru.yml diff --git a/content/ru/logs.md b/content/ru/logs.md new file mode 100644 index 000000000..0a83aa202 --- /dev/null +++ b/content/ru/logs.md @@ -0,0 +1,16 @@ +## XI. Логи +### Рассматривает логи как потоки событий + +*Логи* обеспечивают видимость поведения работающего приложения. Обычно в серверной среде они записываются в файл на диске ("logfile"), но это только выходной формат. + +Лог - это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потока вывода всех запущенных процессов и вспомогательных сервисов. Логи в сыром виде обычно представлены текстовым форматом с одним событием на строчку (хотя трассировки исключений может занимать несколько строк). Логи не имеют фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. + +**Twelve-Factor приложение никогда не занимается маршрутизацией или хранением своего потока вывода.** Приложение не должно записывать лог в файл или управлять файлами логов. Вместо этого каждый выполняющийся процесс записывает свой поток событий, без буферизации, в `stdout`. Во время локальной разработки разработчик может просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. + +При промежуточном или продакшн развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения, и направляен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти архивные направления не являются видимыми для приложения и настраиваемыми приложением, вместо этого полностью управляются средой выполнения. Маршрутизаторы логов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) доступны для этой цели. + +Поток событий приложения может быть направлен в файл для просмотра конца файла в режиме реального времени в терминале. Самое главное, поток может быть направлен в сиситемы индексирования и анализа логов, такие как [Splunk](http://www.splunk.com/) или системы общего назначения хранения данных, таких как [Hadoop/Hive](HTTP://hive.apache.org/). Эти системы обладают большей мощности и гибкостью для внутреннего анализа поведения приложение с течением времени, в том числе: + +* Поиск конкретных события в прошлом. +* Крупномасштабные графики трендов (например, запросов в минуту). +* Активное оповещение по определённым пользователем параметрам (например, оповещение, когда количество ошибок в минуту превышает определенный порог). \ No newline at end of file diff --git a/locales/ru.yml b/locales/ru.yml new file mode 100644 index 000000000..e85f7348f --- /dev/null +++ b/locales/ru.yml @@ -0,0 +1,7 @@ +ru: + # Name of language listed in locales menu + language: Русский (ru) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: (Русский перевод) \ No newline at end of file From 5146eb8bf44c077d9e5eb0976569f9a17a5eca64 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Tue, 5 May 2015 23:32:16 +0600 Subject: [PATCH 130/472] fix translation, log part --- content/ru/logs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/logs.md b/content/ru/logs.md index 0a83aa202..e30d55856 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -1,7 +1,7 @@ ## XI. Логи -### Рассматривает логи как потоки событий +### Рассматривайте логи как потоки событий -*Логи* обеспечивают видимость поведения работающего приложения. Обычно в серверной среде они записываются в файл на диске ("logfile"), но это только выходной формат. +*Логи* обеспечивают видимость поведения работающего приложения. Обычно в серверной среде они записываются в файл на диске ("logfile"), но это только один из форматов вывода. Лог - это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потока вывода всех запущенных процессов и вспомогательных сервисов. Логи в сыром виде обычно представлены текстовым форматом с одним событием на строчку (хотя трассировки исключений может занимать несколько строк). Логи не имеют фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. From 3249f8f13b01a3886d5a7060401c381caa64b588 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 16:38:09 +0600 Subject: [PATCH 131/472] logs: fixes in translation --- content/ru/logs.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/ru/logs.md b/content/ru/logs.md index e30d55856..885c1879d 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -1,16 +1,16 @@ -## XI. Логи -### Рассматривайте логи как потоки событий +## XI. Журналирование (Logs) +### Рассматривайте журнал как поток событий -*Логи* обеспечивают видимость поведения работающего приложения. Обычно в серверной среде они записываются в файл на диске ("logfile"), но это только один из форматов вывода. +*Журналирование* обеспечивает наглядное представление поведения работающего приложения. Обычно в серверной среде журнал записывается в файл на диске ("logfile"), но это только один из форматов вывода. -Лог - это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потока вывода всех запущенных процессов и вспомогательных сервисов. Логи в сыром виде обычно представлены текстовым форматом с одним событием на строчку (хотя трассировки исключений может занимать несколько строк). Логи не имеют фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. +Журнал - это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потоков вывода всех запущенных процессов и вспомогательных сервисов. Журнал в своём сыром виде обычно представлен текстовым форматом с одним событием на строчку (хотя трассировки исключений могут занимать несколько строк). Журнал не имеет фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. -**Twelve-Factor приложение никогда не занимается маршрутизацией или хранением своего потока вывода.** Приложение не должно записывать лог в файл или управлять файлами логов. Вместо этого каждый выполняющийся процесс записывает свой поток событий, без буферизации, в `stdout`. Во время локальной разработки разработчик может просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. +**Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий, без буферизации, в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. -При промежуточном или продакшн развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения, и направляен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти архивные направления не являются видимыми для приложения и настраиваемыми приложением, вместо этого полностью управляются средой выполнения. Маршрутизаторы логов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) доступны для этой цели. +При промежуточном и рабочем развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения, и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. -Поток событий приложения может быть направлен в файл для просмотра конца файла в режиме реального времени в терминале. Самое главное, поток может быть направлен в сиситемы индексирования и анализа логов, такие как [Splunk](http://www.splunk.com/) или системы общего назначения хранения данных, таких как [Hadoop/Hive](HTTP://hive.apache.org/). Эти системы обладают большей мощности и гибкостью для внутреннего анализа поведения приложение с течением времени, в том числе: +Поток событий приложения может быть перенаправлен в файл или просматриваться в терминале в режиме реального времени. Наиболее значимым является то, что поток событий может быть направлен в систему индексирования и анализа журналов, такую как [Splunk](http://www.splunk.com/) или систему хранения данных общего назначения, такую как [Hadoop/Hive](http://hive.apache.org/). Эти системы обладают большими возможностями и гибкостью для досконального анализа поведения приложение в течении времени, что включает в себя: -* Поиск конкретных события в прошлом. +* Поиск конкретных событий в прошлом. * Крупномасштабные графики трендов (например, запросов в минуту). -* Активное оповещение по определённым пользователем параметрам (например, оповещение, когда количество ошибок в минуту превышает определенный порог). \ No newline at end of file +* Активные оповещения согласно эвристическим правилам, определяемых пользователем (например, оповещение, когда количество ошибок в минуту превышает определенный порог). From ad9fd6c272a729c0c33f780af3d15d5b8c5b79d2 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 16:51:39 +0600 Subject: [PATCH 132/472] intro: added russian translation --- content/ru/intro.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/ru/intro.md diff --git a/content/ru/intro.md b/content/ru/intro.md new file mode 100644 index 000000000..620b86fc0 --- /dev/null +++ b/content/ru/intro.md @@ -0,0 +1,12 @@ +Введение +============ + +В наши дни, программное обеспечение обычно распространяется в виде сервисов, называемых *веб-приложения* (web apps) или *software-as-a-service* (SaaS). Приложение двенадцати факторов — это методология для создания SaaS-приложений, которые: + +* Используют **декларативный** формат для описания процесса установки и настройки, что сводит к минимуму затраты времени и ресурсов для новых разработчиков подключенных к проекту; +* Имеют **соглашение** с операционной системой, предполагающее **максимальную переносимость** между средами выполнения; +* Подходят для **развертывания** на современных **облачных платформах**, устраняя необходимость в серверах и системном администрировании; +* **Сводят к минимуму расхождения** между средой разработки и средой выполнения, что позволяет использовать **непрерывное развертывание** (continuous deployment) для максимальной гибкости; +* И могут **масштабироваться** без существенных изменений в инструментах, архитектуре и практике разработки. + +Методология двенадцати факторов может быть применена для приложений, написанных на любом языке программирования, и которые используют любые комбинации сторонних служб (backing services) (базы данных, очереди сообщений, кэш-памяти, и т.д.). From 7a436484e60dfa0ff6d653e0304dc57b810d58fc Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 16:54:58 +0600 Subject: [PATCH 133/472] background: added russian translation --- content/ru/background.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 content/ru/background.md diff --git a/content/ru/background.md b/content/ru/background.md new file mode 100644 index 000000000..d48cc6280 --- /dev/null +++ b/content/ru/background.md @@ -0,0 +1,8 @@ +Предпосылки +========== + +Участники внёсшие вклад в этот документ были непосредственно вовлечены в разработку и развёртывание сотен приложений и косвенно были свидетелями разработки, выполнения и масштабирования сотен тысяч приложений во время нашей работы над платформой [Heroku](http://www.heroku.com/). + +В этом документе обобщаются весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделение особого внимания динамике органического роста приложения с течением времени, динамике сотрудничества разработчиков, работающих над кодовой базой приложения и [устранении последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Наша мотивация заключается в повышении осведомлённости о некоторых системных проблемах, которые мы встретили в практике разработки современных приложений, а также, для того чтобы предоставить общие основные понятия для обсуждения этих проблем и предложить набор общих концептуальных решений этих проблем с сопутствующей терминологией. Формат навеян книгами Мартина Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* и *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 498d746d6a57b14647c94fc8226deb80ecde977a Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 16:59:26 +0600 Subject: [PATCH 134/472] who: added russian translation --- content/ru/who.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 content/ru/who.md diff --git a/content/ru/who.md b/content/ru/who.md new file mode 100644 index 000000000..a11e3803b --- /dev/null +++ b/content/ru/who.md @@ -0,0 +1,4 @@ +Кому следует читать этот документ? +============================== + +Разработчикам, которые создают SaaS-приложения. Ops инженерам, выполняющим развёртывание и управление такими приложениями. From 08aebfeeb1e69adb63333b843ea08ac6092d4c46 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 17:10:49 +0600 Subject: [PATCH 135/472] codebase: added russian translation --- content/ru/codebase.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 content/ru/codebase.md diff --git a/content/ru/codebase.md b/content/ru/codebase.md new file mode 100644 index 000000000..ef01dc2c9 --- /dev/null +++ b/content/ru/codebase.md @@ -0,0 +1,17 @@ +## I. Кодовая база +### Одна кодовая база отслеживаемая в системе контроля версий, множество развертываний + +Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* + +*Кодовая база* - это один репозиторий (в централизованных системах контроля версий, как Subvertion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системых контроля версий, как Git). + +![Одна кодовая база, множество развёртываний](/images/codebase-deploys.png) + +Всегда есть однозначного соответствие между кодовой базой и приложением: + +* Если есть несколько кодовых баз, то это не приложение — это распределенная система. Каждый компонент в распределенной системе является приложением и каждый компонент может индивидуально соответствовать двенадцати факторам. +* Факт того, что несколько приложений совместно используют тот же самый код, является нарушением двенадцати факторов. Решением в данной ситуации является выделение общего кода в библиотеки, которые могут быть подключены через [менеджер зависимостей](./dependencies). + +Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того, каждый разработчик имеет копию приложения запущеного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). + +Кодовая база обязана быть единой для всех развёртываний, однако разные версии одной кодовой базы могут выполняться в каждом из развертываний. Например разработчик может иметь некоторые изменения которые еще не добавлены в промежуточное развёртывание; промежуточное развёртывание может иметь некоторые изменения, которые еще не добавлены в рабочее развёртывание. Однако, все эти развёртывания используют одну и ту же кодовую базу, таким образом можно их идентифицировать как разные развертывания одного и того же приложения. From a83125521ee0f58425242e1fe8a4b50f0cd24778 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 17:19:45 +0600 Subject: [PATCH 136/472] dependencies: added russian translation --- content/ru/dependencies.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/ru/dependencies.md diff --git a/content/ru/dependencies.md b/content/ru/dependencies.md new file mode 100644 index 000000000..7f40ff23b --- /dev/null +++ b/content/ru/dependencies.md @@ -0,0 +1,12 @@ +## II. Зависимости +### Явно объявляйте и изолируйте зависимости + +Большинство языков программирования поставляются вместе с менеджером пакетов для распространения библиотек, таким как [CPAN](http://www.cpan.org/) в Perl или [Rubygems](http://rubygems.org/) в Ruby. Библиотеки, устанавливаемые менеджером пакетов, могут быть установлены доступными для всей системы (так называемые "системные пакеты") или доступными только приложению в директорию содержащую приложение (так называемые "vendoring" и "bundling"). + +**Приложение двенадцати факторов никогда не зависит от неявно существующих доступных всей системе пакетов.** Приложение объявляет все свои зависимости, полностью и точно с помощью манифеста *декларации зависимостей*. Кроме того, оно использует инструмент *изоляции зависимостей* во время выполнения для обеспечения того, что неявные зависимости не "просочились" из окружающей системы. Полная и явная спецификация зависимостей применяется равным образом как при разработке, так и при работе приложения. + +Например, [Gem Bundler](http://gembundler.com/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` для изоляции зависимостей. Python имеет два различных инструмента для этих задач -- [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. + +Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличия среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. + +Приложение двенадцати факторов также не полагается на неявное существование любых инструментов системы. Примером являются запуск программ ImageMagick и `curl`. Хотя эти инструменты могут присутствовать во многих или даже в большинстве систем, нет никакой гарантии, что они будут присутствовать на всех системах, где приложение может работать в будущем, или будет ли версия найденная в другой системе совместима с приложением. Если приложению необходимо запустить инструмент системы, то этот инструмент должен быть включен в приложение. From 48e8d4bf1ee3b6882f30cefee01e7b0f5ead3364 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 17:30:38 +0600 Subject: [PATCH 137/472] config: added russian translation --- content/ru/config.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 content/ru/config.md diff --git a/content/ru/config.md b/content/ru/config.md new file mode 100644 index 000000000..6f236ceee --- /dev/null +++ b/content/ru/config.md @@ -0,0 +1,22 @@ +## 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`, в результате происходит комбинаторный взрыв конфигураций, который делает управление развертываниями приложения очень хрупким. + +В приложении двенадцати факторов переменные окружения являются не связанными между собой средствами управления, где каждая переменная окружения полностью независима от других. Они никогда не группируются вместе в "окружения", а вместо этого управляются независимо для каждого развертывания. Эта модель которая масштабируется постепенно вместе с естественным появлением большего количества развёртываний приложения за время его жизни. From a9512bd4d7fb79ba65baf37a26ca7e9b7afcc718 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 17:45:30 +0600 Subject: [PATCH 138/472] backing-services: added russian translation --- content/ru/backing-services.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/ru/backing-services.md diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md new file mode 100644 index 000000000..2fb72cf7d --- /dev/null +++ b/content/ru/backing-services.md @@ -0,0 +1,14 @@ +## IV. Сторонние службы (Backing Services) +### Считайте сторонние службы (backing services) подключаемыми ресурсами + +*Сторонняя служба* — это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Такие как хранилища данных (например [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например [Postfix](http://www.postfix.org/)) и кэширующие системы (например [Memcached](http://memcached.org/)). + +Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (напрмер [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). + +**Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развертывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. + +Каждая различная сторонняя служба является *ресурсом*. Например база данных MySQL является ресурсом, две базы данных MySQL (используются для фрагментации на уровне приложения) квалифицируются как два отдельных ресурса. Приложение двенадцати факторов считает эти базы данных *подключенными ресурсами*, что указывает на их слабое связывание с развертыванием в котором они подключены. + +Рабочее развёртывание приложения подключенного к 4 сторонним сервисам. + +Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например если база данных приложения функционирует некорректно из-за аппаратные проблемы, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. From 47892edb1a22c7a10d34285129116ca7401409b0 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 17:55:08 +0600 Subject: [PATCH 139/472] build-release-run: added russian translation --- content/ru/build-release-run.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 content/ru/build-release-run.md diff --git a/content/ru/build-release-run.md b/content/ru/build-release-run.md new file mode 100644 index 000000000..e42e06716 --- /dev/null +++ b/content/ru/build-release-run.md @@ -0,0 +1,18 @@ +## V. Сборка, релиз, выполнение +### Строго разделяйте стадии сборки и выполнения + +[Кодовая база](./codebase) трансформируется в развёртывание (не учитывая развёртывание для разработки) за три этапа: + +* *Этап сборки* это трансформация, которая преобразует репозиторий кода в исполняемый пакет, называемый *сборка*. Используя версию кода по указанному процессом развёртывания комиту, этап сборки загружает сторонние [зависимости](./dependencies) и компилирует двоичные файлы и ресурсы (assets). +* *Этап релиза* принимает сборку, полученную на этапе сборки и объединяет её с текущей [конфигурацией](./config) развёртывания. Полученный *релиз* содержит сборку и конфигурацию и готов к немедленному запуску в среде выполнения. +* *Этап выполнения* (также известный как "runtime") запускает приложение в среде выполнения путём запуска некоторого набора [процессов](./processes) приложения из определённого релиза. + +![Код становится сборкой, которая объединяется с конфигурацией для создания релиза.](/images/release.png) + +**Приложение двенадцати факторов использует строгое разделение между этапами сборки, релиза и выполнения.** Например, невозможно внести изменения в код во время выполнения, так как нет способа распространить эти изменения обратно на этап сборки. + +Инструменты развертывания, как правило, представляют собой инструменты управления релизами, и что немаловажно, дают возможность отката к предыдущему релизу. Например инструмент развертывания [Capistrano](https://github.com/capistrano/capistrano/wiki) сохраняет релизы в подкаталогах каталога с именем `releases`, где текущий релиз является символической ссылкой на каталог текущего релиза. Команда Capistrano `rollback` даёт возможность быстро откатится к предыдущему релизу. + +Каждый релиз должен иметь уникальный идентификатор, такой как отметка времени релиза (например `2015-04-06-15:42:17`) или увеличивающееся число (например `v100`). Релизы могут только добавляться и каждый релиз невозможно изменить после его создания. Любые изменения обязаны создавать новый релиз. + +Сборка инициируется разработчиком приложения всяких раз, когда разворачивается новый код. Запуск этапа выполнения, напротив, может происходить автоматически в таких случаях, как перезагрузка сервера, или перезапуск упавшего процесса менеджером процессов. Таким образом, этап выполнения должен быть как можно более технически простым, так как проблемы, которые могут помешать приложению запуститься могут возникнуть в середине ночи, когда нет доступных разработчиков. Этап сборки может быть более сложным, так как возможные ошибки всегда видимы разработчику, который запустил развёртывание. From 7c2196392674a8fd1d9c6dd36718420f04f1588f Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 18:38:53 +0600 Subject: [PATCH 140/472] processes: added russian translation --- content/ru/processes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/ru/processes.md diff --git a/content/ru/processes.md b/content/ru/processes.md new file mode 100644 index 000000000..f0d019de2 --- /dev/null +++ b/content/ru/processes.md @@ -0,0 +1,14 @@ +## VI. Процессы +### Запускайте приложение как один или несколько процессов не сохраняющих внутреннее состояние (stateless) + +Приложение выполняется в среде выполнения как один или несколько *процессов*. + +В простейшем случае, код является независимым скриптом, среда выполнения ноутбуком разработчика с установленной средой исполнения языка, а процесс запускается из командной строки (например как `python my_script.py`). Другой крайний вариант -- это рабочее развёртывание сложного приложения, которое может использовать много [типов процессов, каждый из которых запущен в необходимом количестве экземпляров](./concurrency). + +**Процессы приложения двенадцати факторов не сохраняют внутреннее состояние (stateless) и [не имеют разделяемых данных (share-nothing)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Любые данные, которые требуется сохранять должны быть сохранены в хранящей состояние [сторонней службе](./backing-services), обычно в базе данных. + +Память и файловая система процесса может быть использована в качестве временного кэша для одной транзакции. Например, загрузка, обработка и сохранение большого файла в базе данных. Приложение двенадцати факторов не предполагает, что что-либо закэшированное в памяти или на диске будет доступно следующим запросам или задачам -- с большим количеством разноплановых процессов высока вероятность, что следующий запрос будет обработан другим процессом. Даже с одним запущенным процессом, перезапуск (вызванный развёртыванием, изменением конфигураций или переносом процесса на другое физическое устройство) приведет к уничтожению всех локальных (памяти, файловой системы) состояний. + +Упаковщики ресурсов (asset) (например, [Jammit](http://documentcloud.github.com/jammit/) или [django-compressor](http://django-compressor.readthedocs.org/)) используют файловую систему как кэш для скомпилированных ресурсов. Приложение двенадцати факторов предпочитает делать данную компиляцию во время [этапа сборки](./build-release-run), например как в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не во время выполнения. + +Некоторые веб-системы полагаются на ["липкие сессий"] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- то есть, кэшируют данные пользовательских сессии в памяти процесса приложения и ожидают того, что последующие запросы того же пользователя будут перенаправлены к тому же процессу. Липкие сессии являются нарушением двенадцати факторов и их никогда не следует использовать или полагаться на них. Данные пользовательской сессии являются хорошими кандидатами для хранилища данных, которое предоставляет функцию ограничения времени хранения, например [Memcached](http://memcached.org/) и [Redis](http://redis.io/). From 0fdeb9451898c934f7d6d68f9b4b6d01d02ecfa5 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:00:52 +0600 Subject: [PATCH 141/472] port-binding: added russian translation --- content/ru/port-binding.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/ru/port-binding.md diff --git a/content/ru/port-binding.md b/content/ru/port-binding.md new file mode 100644 index 000000000..f8776055a --- /dev/null +++ b/content/ru/port-binding.md @@ -0,0 +1,14 @@ +## VII. Привязка портов (Port binding) +### Экспортируйте сервисы через привязку портов + +Иногда веб-приложения запускают внутри контейнера веб-сервера. Например PHP-приложение может быть запущено как модуль внутри [Apache HTTPD](http://httpd.apache.org/), или Java-приложение может быть запущено внутри [Tomcat](http://tomcat.apache.org/). + +**Приложение двенадцати факторов является полностью самодостаточным** и не полагается на инъекцию веб-сервера во время выполнения для того чтобы создать веб-сервис. Веб-приложение **экспортирует HTTP-сервис путем привязки к порту** и прослушивает запросы, поступающих на этот порт. + +Во время локальной разработки, разработчик переходит по URL-адресу вида `http://localhost:5000/` чтобы получить доступ к сервису, предоставляемым его приложением. При развертывании, слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. + +Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению, такой как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://jetty.codehaus.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть, в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. + +HTTP-это не единственный сервис, который может быть экспортирован посредством привязки порта. Почти любой тип серверного ПО может быть запущен как процесс привязанный к порту и ожидающий входящих запросов. Примеры включают [ejabberd](http://www.ejabberd.im/) (предоставляет [XMPP протокол](http://xmpp.org/)) и [Redis](http://redis.io/) (предоставляет [Redis протокол](http://redis.io/topics/protocol)). + +Также, обратите внимание, что подход привязки к порту означает, что одно приложение может выступать [сторонней службой](./backing-services) для другого приложения путём предоставления URL-адреса стороннего приложения как идентификатор ресурса в конфигурации потребляющего приложения. From 732faeb83e271bcfaadeeb00064fe90d9f6a9352 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:07:38 +0600 Subject: [PATCH 142/472] concurrenc: added russian translation --- content/ru/concurrency.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/ru/concurrency.md diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md new file mode 100644 index 000000000..7f6cb09f9 --- /dev/null +++ b/content/ru/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Параллелизм +### Масштабируйте приложение с помошью процессов + +Любая компьютерная программа после запуска представляет собой один или несколько работающих процессов. Исторически веб-приложения принимали различные формы выполнения процессов. К примеру, PHP-процессы выполнятся как дочерние процессы Apache и запускаются по требованию в необходимом для обслуживания поступивших запросов количестве. Java-процессы используют противоположный подход, JVM представляет собой один монолитный мета-процесс, который резервирует большой объем системных ресурсов (процессор и память) при запуске и управляет параллельностью внутри себя с помощью нитей исполнения (threads). В обоих случаях запущенные процессы лишь минимально видны для разработчика приложения. + +![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) + +**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели, разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработанные веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. + +Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах, таких как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложения должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. + +Модель построенная на процессах действительно сияет, когда приходит время масштабирования. [Отсутсвие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называется *формированием процессов (process formation)*. + +Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого, они должны полагаться на менеджер процессов операционной системы (например [Upstart](http://upstart.ubuntu.com/), распределенный менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. From 096bec658251bb95e5240a7825829a2fda88ed54 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:29:44 +0600 Subject: [PATCH 143/472] disposability: added russian translation --- content/ru/disposability.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/ru/disposability.md diff --git a/content/ru/disposability.md b/content/ru/disposability.md new file mode 100644 index 000000000..68f0afac3 --- /dev/null +++ b/content/ru/disposability.md @@ -0,0 +1,12 @@ +## IX. Одноразовость (Disposability) +### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы + +**[Процессы](./processes) приложения двенадцати факторов являются *одноразовыми*, это означает, что они могут быть запущены и остановилены любой в момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. + +Процессы должны стараться **минимизировать время запуска**. В идеале, процесс должен затратить всего несколько секунд, от момента времени когда выполнена команда запуска и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет болшую гибкость для [релиза](./build-release-run) и масштабирования. Также, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. + +Процессы должны **завершаться корректно, когда они получают [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал от диспетчера процессов. Для веб-процесса корректное завершение работы достигается путем прекращения прослушивания порта сервиса (таким образом, отказаться от каких-либо новых запросов), что позволяет завершить текущие запросы и затем завершиться. В этой модели подразумевается, что HTTP-запросы короткие (не более чем на несколько секунд), в случае длинных запросов клиент должен плавно попытаться восстановить подключение при потере соединения. + +Для процесса выполняющего фоновые задачи (worker) корректное завершение работы достигается путем возвращения текущей задачи назад в очередь задач. Например в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках, такие как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путем оборачивать результатов работы в транзакции или путем использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. + +Процессы также должны быть **устойчивыми к внезапной смерти**, в случае отказа аппаратного обеспечения. Хотя это гораздо менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно все же может случиться. Рекомендуемым подходом является использование надежных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае, приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и не изящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). From ab9b839b4c5c62821da1f392e36d6bc3b60818f8 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:46:06 +0600 Subject: [PATCH 144/472] dev-prod-parity: added russian translation --- content/ru/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 content/ru/dev-prod-parity.md diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md new file mode 100644 index 000000000..45495ed81 --- /dev/null +++ b/content/ru/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Паритет разработки/работы приложения +### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими + +Исторически существуют значительные различия между разработкой (разработчик делает живые изменения на локальном [развёртывании](./codebase) приложения) и работой приложения (развёртывание приложения с доступом к нему конечных пользователей). Эти различия проявляются в трех областях: + +* **Различие во времени:** разработчик может работать с кодом, который попадёт в рабочую версию приложения только через дни, недели или даже месяцы. +* **Различие персонала**: разработчики пишут код, OPS инженеры разворачивают его. +* **Различие инструментов**: разработчики могут использовать стек технологий такой как Nginx, SQLite, и OS X, в то время как при рабочем развертывании используется Apache, MySQL и Linux. + +**Приложение двенадцати факторов спроектировано для [непрерывного развертывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: + +* Сделать различие во времени небольшим: разработчик может написать код и он будет развёрнут через несколько часов или даже минут. +* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывание и наблюдет за его поведением во время работы приложения. +* Сделать различия инструментов небольшими: держать окружение разработки и работы приложения максимально похожими. + +Резюмируя сказанное выше в таблицу: + + + + + + + + + + + + + + + + + + + + + + +
Традиционное приложениеПриложение двенадцати факторов
Время между развёртываниямиНеделиЧасы
Автор кода/тот кто разворачиваетРазные людиТе же люди
Окружение разработки/работы приложенияРазличныеМаксимально похожие
+ +[Сторонние службы](./backing-services), такие как базы данных, системы очередей сообщений и кэш, является одной из областей, где паритет при разработке и работе приложения имеет важное значение. Многие языки предоставляют библиотеки, которые упрощают доступ к сторонним службам, включая *адаптеры* для доступа к различных типам сервисов. Некоторые примеры, в таблице ниже. + + + + + + + + + + + + + + + + + + + + + + + + + + +
ТипЯзыкБиблиотекаАдаптеры
База данныхRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
Очередь сообщенийPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
КэшRuby/RailsActiveSupport::CacheПамять, файловая система, Memcached
+ +Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьезные и надежные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кеширования при разработке и Memcached в рабочем окружении. + +**Разработчик приложения двенадцати факторов должен сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. + +Установка локальных сервисов стала менее непреодолимой задачей, чем она когда то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению выгодой получаемой от паритета разработки/работы приложения и непрерывного развёртывания. + +Адаптеры для различных сторонних сервисов по-прежнему полезны, потому что они позволяют портировать приложение для использования новых сторонних сервисов относительно безболезненно. Но все развёртывания приложения (окружение разработчика, промежуточное и рабочее развёртывание) должны использовать тот же тип и ту же версию каждого из сторонних сервисов. From 7eb808bac0a2495d81b4c1dd4d93e2e540676605 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:52:20 +0600 Subject: [PATCH 145/472] admin-processes: added russian translation --- content/ru/admin-processes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/ru/admin-processes.md diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md new file mode 100644 index 000000000..ec2a38c89 --- /dev/null +++ b/content/ru/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Задачи администрирования +### Выполнйте задачи администратрирования/управления с помошью разовых процессов + +[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов) когда оно исполняется. В дополнение к этому, разработчикам переодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: + +* Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). +* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`) или в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). +* Запуск разовых скриптов хранящихся в репозитории приложения (например `php scripts/fix_bad_records.php`). + +Разовые процессы администрирования следует запускать в среде идентичной регулярным [длительным процессам](./processes) приложения. Они запускаются на уровне [релиза](./build-release-run), используя те же [кодовую базу](./codebase) и [конфигурацию](./config), как и любой другой процесс выполняющий этот релиз. Код администрирования должен поставляться вместе с кодом приложения, чтобы избежать проблем синхронизации. + +Те же самые методы [изоляции зависимостей](./dependencies), должны быть использованы для всех типов процессов. Например, если веб-процесс Ruby использует команду `bundle exec thin start`, то для миграции базы данных следует использовать `bundle exec rake db:migrate`. Аналогичным образом для программы на Python с использованием Virtualenv следует использовать поставляемый `bin/python` как для запуска веб-сервера Tornado, так и для запуска любых `manage.py` процессов администрирования. + +Методология двенадцати факторов отдаёт предпочтение языкам, которые предоставляют REPL оболочки из коробки, и которые позволяют легко выполнять разовые скрипты. В локальном развертывании разработчики выполняют разовый процесс администрирования с помощью консольной команды внутри каталога с приложением. В рабочем развертывании разработчики могут использовать ssh или другой механизм выполнения удаленной команды, предоставленный средой выполнения, для запуска такого процесса. From 5a56ec6228ae082cc6dae7497b12bc145b293298 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 23 May 2015 19:57:57 +0600 Subject: [PATCH 146/472] toc: added russian translation --- content/ru/toc.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 content/ru/toc.md diff --git a/content/ru/toc.md b/content/ru/toc.md new file mode 100644 index 000000000..34ab8219e --- /dev/null +++ b/content/ru/toc.md @@ -0,0 +1,38 @@ +Двенадцать факторов +================== + +## [I. Кодовая база](./codebase) +### Одна кодовая база отслеживаемая в системе контроля версий, множество развертываний + +## [II. Зависимости](./dependencies) +### Явно объявляйте и изолируйте зависимости + +## [III. Конфигурация](./config) +### Сохраняйте конфигурацию в среде выполнения + +## [IV. Сторонние службы (Backing Services)](./backing-services) +### Считайте сторонние службы (backing services) подключаемыми ресурсами + +## [V. Сборка, релиз, выполнение](./build-release-run) +### Строго разделяйте стадии сборки и выполнения + +## [VI. Процессы](./processes) +### Запускайте приложение как один или несколько процессов не сохраняющих внутреннее состояние (stateless) + +## [VII. Привязка портов (Port binding)](./port-binding) +### Экспортируйте сервисы через привязку портов + +## [VIII. Параллелизм](./concurrency) +### Масштабируйте приложение с помошью процессов + +## [IX. Одноразовость (Disposability)](./disposability) +### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы + +## [X. Паритет разработки/работы приложения](./dev-prod-parity) +### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими + +## [XI. Журналирование (Logs)](./logs) +### Рассматривайте журнал как поток событий + +## [XII. Задачи администрирования](./admin-processes) +### Выполнйте задачи администратрирования/управления с помошью разовых процессов From 8b473c393f8f26f14c745eed63e3475873b67562 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Mon, 25 May 2015 22:46:02 +0600 Subject: [PATCH 147/472] russian tranlation: fixed mistypes and punctuation --- content/ru/admin-processes.md | 10 +++++----- content/ru/background.md | 6 +++--- content/ru/backing-services.md | 10 +++++----- content/ru/build-release-run.md | 4 ++-- content/ru/codebase.md | 10 +++++----- content/ru/concurrency.md | 8 ++++---- content/ru/config.md | 4 ++-- content/ru/dependencies.md | 8 ++++---- content/ru/dev-prod-parity.md | 4 ++-- content/ru/disposability.md | 6 +++--- content/ru/intro.md | 4 ++-- content/ru/logs.md | 8 ++++---- content/ru/port-binding.md | 12 ++++++------ content/ru/processes.md | 12 ++++++------ content/ru/toc.md | 2 +- 15 files changed, 54 insertions(+), 54 deletions(-) diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md index ec2a38c89..7a53f2dc3 100644 --- a/content/ru/admin-processes.md +++ b/content/ru/admin-processes.md @@ -1,14 +1,14 @@ ## XII. Задачи администрирования ### Выполнйте задачи администратрирования/управления с помошью разовых процессов -[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов) когда оно исполняется. В дополнение к этому, разработчикам переодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: +[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам переодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: * Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). -* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`) или в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). -* Запуск разовых скриптов хранящихся в репозитории приложения (например `php scripts/fix_bad_records.php`). +* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). +* Запуск разовых скриптов, хранящихся в репозитории приложения (например, `php scripts/fix_bad_records.php`). -Разовые процессы администрирования следует запускать в среде идентичной регулярным [длительным процессам](./processes) приложения. Они запускаются на уровне [релиза](./build-release-run), используя те же [кодовую базу](./codebase) и [конфигурацию](./config), как и любой другой процесс выполняющий этот релиз. Код администрирования должен поставляться вместе с кодом приложения, чтобы избежать проблем синхронизации. +Разовые процессы администрирования следует запускать в среде идентичной регулярным [длительным процессам](./processes) приложения. Они запускаются на уровне [релиза](./build-release-run), используя те же [кодовую базу](./codebase) и [конфигурацию](./config), как и любой другой процесс, выполняющий этот релиз. Код администрирования должен поставляться вместе с кодом приложения, чтобы избежать проблем синхронизации. -Те же самые методы [изоляции зависимостей](./dependencies), должны быть использованы для всех типов процессов. Например, если веб-процесс Ruby использует команду `bundle exec thin start`, то для миграции базы данных следует использовать `bundle exec rake db:migrate`. Аналогичным образом для программы на Python с использованием Virtualenv следует использовать поставляемый `bin/python` как для запуска веб-сервера Tornado, так и для запуска любых `manage.py` процессов администрирования. +Те же самые методы [изоляции зависимостей](./dependencies) должны быть использованы для всех типов процессов. Например, если веб-процесс Ruby использует команду `bundle exec thin start`, то для миграции базы данных следует использовать `bundle exec rake db:migrate`. Аналогичным образом для программы на Python с использованием Virtualenv следует использовать поставляемый `bin/python` как для запуска веб-сервера Tornado, так и для запуска любых `manage.py` процессов администрирования. Методология двенадцати факторов отдаёт предпочтение языкам, которые предоставляют REPL оболочки из коробки, и которые позволяют легко выполнять разовые скрипты. В локальном развертывании разработчики выполняют разовый процесс администрирования с помощью консольной команды внутри каталога с приложением. В рабочем развертывании разработчики могут использовать ssh или другой механизм выполнения удаленной команды, предоставленный средой выполнения, для запуска такого процесса. diff --git a/content/ru/background.md b/content/ru/background.md index d48cc6280..e7efaa4d1 100644 --- a/content/ru/background.md +++ b/content/ru/background.md @@ -1,8 +1,8 @@ Предпосылки ========== -Участники внёсшие вклад в этот документ были непосредственно вовлечены в разработку и развёртывание сотен приложений и косвенно были свидетелями разработки, выполнения и масштабирования сотен тысяч приложений во время нашей работы над платформой [Heroku](http://www.heroku.com/). +Участники, внёсшие вклад в этот документ, были непосредственно вовлечены в разработку и развёртывание сотен приложений и косвенно были свидетелями разработки, выполнения и масштабирования сотен тысяч приложений во время нашей работы над платформой [Heroku](http://www.heroku.com/). -В этом документе обобщаются весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделение особого внимания динамике органического роста приложения с течением времени, динамике сотрудничества разработчиков, работающих над кодовой базой приложения и [устранении последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +В этом документе обобщается весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделение особого внимания динамике органического роста приложения с течением времени, динамике сотрудничества разработчиков, работающих над кодовой базой приложения и [устранене последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). -Наша мотивация заключается в повышении осведомлённости о некоторых системных проблемах, которые мы встретили в практике разработки современных приложений, а также, для того чтобы предоставить общие основные понятия для обсуждения этих проблем и предложить набор общих концептуальных решений этих проблем с сопутствующей терминологией. Формат навеян книгами Мартина Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* и *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +Наша мотивация заключается в повышении осведомлённости о некоторых системных проблемах, которые мы встретили в практике разработки современных приложений, а также для того, чтобы предоставить общие основные понятия для обсуждения этих проблем и предложить набор общих концептуальных решений этих проблем с сопутствующей терминологией. Формат навеян книгами Мартина Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* и *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 2fb72cf7d..4924fc974 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -1,14 +1,14 @@ ## IV. Сторонние службы (Backing Services) ### Считайте сторонние службы (backing services) подключаемыми ресурсами -*Сторонняя служба* — это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Такие как хранилища данных (например [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например [Postfix](http://www.postfix.org/)) и кэширующие системы (например [Memcached](http://memcached.org/)). +*Сторонняя служба*-- это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Например, хранилища данных (например, [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например, [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например, [Postfix](http://www.postfix.org/)) и кэширующие системы (например, [Memcached](http://memcached.org/)). -Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (напрмер [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). +Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (напрмер [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). **Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развертывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. -Каждая различная сторонняя служба является *ресурсом*. Например база данных MySQL является ресурсом, две базы данных MySQL (используются для фрагментации на уровне приложения) квалифицируются как два отдельных ресурса. Приложение двенадцати факторов считает эти базы данных *подключенными ресурсами*, что указывает на их слабое связывание с развертыванием в котором они подключены. +Каждая различная сторонняя служба является *ресурсом*. Например, база данных MySQL является ресурсом, две базы данных MySQL (используются для фрагментации на уровне приложения) квалифицируются как два отдельных ресурса. Приложение двенадцати факторов считает эти базы данных *подключенными ресурсами*, что указывает на их слабое связывание с развертыванием, в котором они подключены. -Рабочее развёртывание приложения подключенного к 4 сторонним сервисам. +Рабочее развёртывание приложения, подключенного к 4 сторонним сервисам. -Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например если база данных приложения функционирует некорректно из-за аппаратные проблемы, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. +Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например, если база данных приложения функционирует некорректно из-за аппаратные проблемы, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. diff --git a/content/ru/build-release-run.md b/content/ru/build-release-run.md index e42e06716..dace1677a 100644 --- a/content/ru/build-release-run.md +++ b/content/ru/build-release-run.md @@ -3,8 +3,8 @@ [Кодовая база](./codebase) трансформируется в развёртывание (не учитывая развёртывание для разработки) за три этапа: -* *Этап сборки* это трансформация, которая преобразует репозиторий кода в исполняемый пакет, называемый *сборка*. Используя версию кода по указанному процессом развёртывания комиту, этап сборки загружает сторонние [зависимости](./dependencies) и компилирует двоичные файлы и ресурсы (assets). -* *Этап релиза* принимает сборку, полученную на этапе сборки и объединяет её с текущей [конфигурацией](./config) развёртывания. Полученный *релиз* содержит сборку и конфигурацию и готов к немедленному запуску в среде выполнения. +* *Этап сборки* -- это трансформация, которая преобразует репозиторий кода в исполняемый пакет, называемый *сборка*. Используя версию кода по указанному процессом развёртывания комиту, этап сборки загружает сторонние [зависимости](./dependencies) и компилирует двоичные файлы и ресурсы (assets). +* *Этап релиза* принимает сборку, полученную на этапе сборки, и объединяет её с текущей [конфигурацией](./config) развёртывания. Полученный *релиз* содержит сборку и конфигурацию и готов к немедленному запуску в среде выполнения. * *Этап выполнения* (также известный как "runtime") запускает приложение в среде выполнения путём запуска некоторого набора [процессов](./processes) приложения из определённого релиза. ![Код становится сборкой, которая объединяется с конфигурацией для создания релиза.](/images/release.png) diff --git a/content/ru/codebase.md b/content/ru/codebase.md index ef01dc2c9..e37e06dc7 100644 --- a/content/ru/codebase.md +++ b/content/ru/codebase.md @@ -1,17 +1,17 @@ ## I. Кодовая база -### Одна кодовая база отслеживаемая в системе контроля версий, множество развертываний +### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развертываний Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* -*Кодовая база* - это один репозиторий (в централизованных системах контроля версий, как Subvertion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системых контроля версий, как Git). +*Кодовая база* -- это один репозиторий (в централизованных системах контроля версий, как Subvertion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системах контроля версий, как Git). -![Одна кодовая база, множество развёртываний](/images/codebase-deploys.png) +![Одна кодовая база -- множество развёртываний](/images/codebase-deploys.png) -Всегда есть однозначного соответствие между кодовой базой и приложением: +Всегда есть однозначное соответствие между кодовой базой и приложением: * Если есть несколько кодовых баз, то это не приложение — это распределенная система. Каждый компонент в распределенной системе является приложением и каждый компонент может индивидуально соответствовать двенадцати факторам. * Факт того, что несколько приложений совместно используют тот же самый код, является нарушением двенадцати факторов. Решением в данной ситуации является выделение общего кода в библиотеки, которые могут быть подключены через [менеджер зависимостей](./dependencies). -Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того, каждый разработчик имеет копию приложения запущеного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). +Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того каждый разработчик имеет копию приложения, запущеного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). Кодовая база обязана быть единой для всех развёртываний, однако разные версии одной кодовой базы могут выполняться в каждом из развертываний. Например разработчик может иметь некоторые изменения которые еще не добавлены в промежуточное развёртывание; промежуточное развёртывание может иметь некоторые изменения, которые еще не добавлены в рабочее развёртывание. Однако, все эти развёртывания используют одну и ту же кодовую базу, таким образом можно их идентифицировать как разные развертывания одного и того же приложения. diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index 7f6cb09f9..abd11488b 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -5,10 +5,10 @@ ![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) -**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели, разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработанные веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. +**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. -Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах, таких как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложения должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. +Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. -Модель построенная на процессах действительно сияет, когда приходит время масштабирования. [Отсутсвие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называется *формированием процессов (process formation)*. +Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутсвие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. -Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого, они должны полагаться на менеджер процессов операционной системы (например [Upstart](http://upstart.ubuntu.com/), распределенный менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. +Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого они должны полагаться на менеджер процессов операционной системы (например, [Upstart](http://upstart.ubuntu.com/), распределенный менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. diff --git a/content/ru/config.md b/content/ru/config.md index 6f236ceee..17048d617 100644 --- a/content/ru/config.md +++ b/content/ru/config.md @@ -5,11 +5,11 @@ * Идентификаторы подключения к ресурсам типа базы данных, кэш-памяти и другим [сторонним службам](./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/). Этот тип конфигурации не меняется между развёртываниями и поэтому лучше всего держать его в коде. diff --git a/content/ru/dependencies.md b/content/ru/dependencies.md index 7f40ff23b..0421cf1ec 100644 --- a/content/ru/dependencies.md +++ b/content/ru/dependencies.md @@ -3,10 +3,10 @@ Большинство языков программирования поставляются вместе с менеджером пакетов для распространения библиотек, таким как [CPAN](http://www.cpan.org/) в Perl или [Rubygems](http://rubygems.org/) в Ruby. Библиотеки, устанавливаемые менеджером пакетов, могут быть установлены доступными для всей системы (так называемые "системные пакеты") или доступными только приложению в директорию содержащую приложение (так называемые "vendoring" и "bundling"). -**Приложение двенадцати факторов никогда не зависит от неявно существующих доступных всей системе пакетов.** Приложение объявляет все свои зависимости, полностью и точно с помощью манифеста *декларации зависимостей*. Кроме того, оно использует инструмент *изоляции зависимостей* во время выполнения для обеспечения того, что неявные зависимости не "просочились" из окружающей системы. Полная и явная спецификация зависимостей применяется равным образом как при разработке, так и при работе приложения. +**Приложение двенадцати факторов никогда не зависит от неявно существующих, доступных всей системе пакетов.** Приложение объявляет все свои зависимости полностью и точно с помощью манифеста *декларации зависимостей*. Кроме того, оно использует инструмент *изоляции зависимостей* во время выполнения для обеспечения того, что неявные зависимости не "просочились" из окружающей системы. Полная и явная спецификация зависимостей применяется равным образом как при разработке, так и при работе приложения. -Например, [Gem Bundler](http://gembundler.com/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` для изоляции зависимостей. Python имеет два различных инструмента для этих задач -- [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. +Например, [Gem Bundler](http://gembundler.com/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` -- для изоляции зависимостей. Python имеет два различных инструмента для этих задач: [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) -- для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей, и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. -Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличия среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. +Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличие среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например, для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. -Приложение двенадцати факторов также не полагается на неявное существование любых инструментов системы. Примером являются запуск программ ImageMagick и `curl`. Хотя эти инструменты могут присутствовать во многих или даже в большинстве систем, нет никакой гарантии, что они будут присутствовать на всех системах, где приложение может работать в будущем, или будет ли версия найденная в другой системе совместима с приложением. Если приложению необходимо запустить инструмент системы, то этот инструмент должен быть включен в приложение. +Приложение двенадцати факторов также не полагается на неявное существование любых инструментов системы. Примером является запуск программ ImageMagick и `curl`. Хотя эти инструменты могут присутствовать во многих или даже в большинстве систем, нет никакой гарантии, что они будут присутствовать на всех системах, где приложение может работать в будущем, или будет ли версия найденная в другой системе совместима с приложением. Если приложению необходимо запустить инструмент системы, то этот инструмент должен быть включен в приложение. diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 45495ed81..7ea8880c7 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -5,11 +5,11 @@ * **Различие во времени:** разработчик может работать с кодом, который попадёт в рабочую версию приложения только через дни, недели или даже месяцы. * **Различие персонала**: разработчики пишут код, OPS инженеры разворачивают его. -* **Различие инструментов**: разработчики могут использовать стек технологий такой как Nginx, SQLite, и OS X, в то время как при рабочем развертывании используется Apache, MySQL и Linux. +* **Различие инструментов**: разработчики могут использовать стек технологий, такой как Nginx, SQLite, и OS X, в то время как при рабочем развертывании используются Apache, MySQL и Linux. **Приложение двенадцати факторов спроектировано для [непрерывного развертывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: -* Сделать различие во времени небольшим: разработчик может написать код и он будет развёрнут через несколько часов или даже минут. +* Сделать различие во времени небольшим: разработчик может написать код, и он будет развёрнут через несколько часов или даже минут. * Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывание и наблюдет за его поведением во время работы приложения. * Сделать различия инструментов небольшими: держать окружение разработки и работы приложения максимально похожими. diff --git a/content/ru/disposability.md b/content/ru/disposability.md index 68f0afac3..5615cd8a0 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -3,10 +3,10 @@ **[Процессы](./processes) приложения двенадцати факторов являются *одноразовыми*, это означает, что они могут быть запущены и остановилены любой в момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. -Процессы должны стараться **минимизировать время запуска**. В идеале, процесс должен затратить всего несколько секунд, от момента времени когда выполнена команда запуска и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет болшую гибкость для [релиза](./build-release-run) и масштабирования. Также, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. +Процессы должны стараться **минимизировать время запуска**. В идеале процесс должен затратить всего несколько секунд от момента времени, когда выполнена команда запуска, и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет большую гибкость для [релиза](./build-release-run) и масштабирования. Кроме того, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. Процессы должны **завершаться корректно, когда они получают [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал от диспетчера процессов. Для веб-процесса корректное завершение работы достигается путем прекращения прослушивания порта сервиса (таким образом, отказаться от каких-либо новых запросов), что позволяет завершить текущие запросы и затем завершиться. В этой модели подразумевается, что HTTP-запросы короткие (не более чем на несколько секунд), в случае длинных запросов клиент должен плавно попытаться восстановить подключение при потере соединения. -Для процесса выполняющего фоновые задачи (worker) корректное завершение работы достигается путем возвращения текущей задачи назад в очередь задач. Например в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках, такие как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путем оборачивать результатов работы в транзакции или путем использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. +Для процесса, выполняющего фоновые задачи (worker), корректное завершение работы достигается путем возвращения текущей задачи назад в очередь задач. Например, в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках такие, как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путем оборачивания результатов работы в транзакции или путем использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. -Процессы также должны быть **устойчивыми к внезапной смерти**, в случае отказа аппаратного обеспечения. Хотя это гораздо менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно все же может случиться. Рекомендуемым подходом является использование надежных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае, приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и не изящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). +Процессы также должны быть **устойчивыми к внезапной смерти** в случае отказа аппаратного обеспечения. Хотя это менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно все же может случиться. Рекомендуемым подходом является использование надежных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и неизящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/ru/intro.md b/content/ru/intro.md index 620b86fc0..b3369285d 100644 --- a/content/ru/intro.md +++ b/content/ru/intro.md @@ -1,9 +1,9 @@ Введение ============ -В наши дни, программное обеспечение обычно распространяется в виде сервисов, называемых *веб-приложения* (web apps) или *software-as-a-service* (SaaS). Приложение двенадцати факторов — это методология для создания SaaS-приложений, которые: +В наши дни программное обеспечение обычно распространяется в виде сервисов, называемых *веб-приложения* (web apps) или *software-as-a-service* (SaaS). Приложение двенадцати факторов — это методология для создания SaaS-приложений, которые: -* Используют **декларативный** формат для описания процесса установки и настройки, что сводит к минимуму затраты времени и ресурсов для новых разработчиков подключенных к проекту; +* Используют **декларативный** формат для описания процесса установки и настройки, что сводит к минимуму затраты времени и ресурсов для новых разработчиков, подключенных к проекту; * Имеют **соглашение** с операционной системой, предполагающее **максимальную переносимость** между средами выполнения; * Подходят для **развертывания** на современных **облачных платформах**, устраняя необходимость в серверах и системном администрировании; * **Сводят к минимуму расхождения** между средой разработки и средой выполнения, что позволяет использовать **непрерывное развертывание** (continuous deployment) для максимальной гибкости; diff --git a/content/ru/logs.md b/content/ru/logs.md index 885c1879d..63efd1701 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -3,13 +3,13 @@ *Журналирование* обеспечивает наглядное представление поведения работающего приложения. Обычно в серверной среде журнал записывается в файл на диске ("logfile"), но это только один из форматов вывода. -Журнал - это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потоков вывода всех запущенных процессов и вспомогательных сервисов. Журнал в своём сыром виде обычно представлен текстовым форматом с одним событием на строчку (хотя трассировки исключений могут занимать несколько строк). Журнал не имеет фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. +Журнал -- это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потоков вывода всех запущенных процессов и вспомогательных сервисов. Журнал в своём сыром виде обычно представлен текстовым форматом с одним событием на строчку (хотя трассировки исключений могут занимать несколько строк). Журнал не имеет фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. -**Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий, без буферизации, в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. +**Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий без буферизации в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. -При промежуточном и рабочем развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения, и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. +При промежуточном и рабочем развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. -Поток событий приложения может быть перенаправлен в файл или просматриваться в терминале в режиме реального времени. Наиболее значимым является то, что поток событий может быть направлен в систему индексирования и анализа журналов, такую как [Splunk](http://www.splunk.com/) или систему хранения данных общего назначения, такую как [Hadoop/Hive](http://hive.apache.org/). Эти системы обладают большими возможностями и гибкостью для досконального анализа поведения приложение в течении времени, что включает в себя: +Поток событий приложения может быть перенаправлен в файл или просматриваться в терминале в режиме реального времени. Наиболее значимым является то, что поток событий может быть направлен в систему индексирования и анализа журналов, такую как [Splunk](http://www.splunk.com/), или систему хранения данных общего назначения, такую как [Hadoop/Hive](http://hive.apache.org/). Эти системы обладают большими возможностями и гибкостью для досконального анализа поведения приложение в течении времени, что включает в себя: * Поиск конкретных событий в прошлом. * Крупномасштабные графики трендов (например, запросов в минуту). diff --git a/content/ru/port-binding.md b/content/ru/port-binding.md index f8776055a..ec61c5e41 100644 --- a/content/ru/port-binding.md +++ b/content/ru/port-binding.md @@ -1,14 +1,14 @@ ## VII. Привязка портов (Port binding) ### Экспортируйте сервисы через привязку портов -Иногда веб-приложения запускают внутри контейнера веб-сервера. Например PHP-приложение может быть запущено как модуль внутри [Apache HTTPD](http://httpd.apache.org/), или Java-приложение может быть запущено внутри [Tomcat](http://tomcat.apache.org/). +Иногда веб-приложения запускают внутри контейнера веб-сервера. Например, PHP-приложение может быть запущено как модуль внутри [Apache HTTPD](http://httpd.apache.org/), или Java-приложение может быть запущено внутри [Tomcat](http://tomcat.apache.org/). -**Приложение двенадцати факторов является полностью самодостаточным** и не полагается на инъекцию веб-сервера во время выполнения для того чтобы создать веб-сервис. Веб-приложение **экспортирует HTTP-сервис путем привязки к порту** и прослушивает запросы, поступающих на этот порт. +**Приложение двенадцати факторов является полностью самодостаточным** и не полагается на инъекцию веб-сервера во время выполнения для того, чтобы создать веб-сервис. Веб-приложение **экспортирует HTTP-сервис путем привязки к порту** и прослушивает запросы, поступающих на этот порт. -Во время локальной разработки, разработчик переходит по URL-адресу вида `http://localhost:5000/` чтобы получить доступ к сервису, предоставляемым его приложением. При развертывании, слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. +Во время локальной разработки разработчик переходит по URL-адресу вида `http://localhost:5000/`, чтобы получить доступ к сервису, предоставляемым его приложением. При развертывании слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. -Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению, такой как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://jetty.codehaus.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть, в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. +Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению такой, как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://jetty.codehaus.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. -HTTP-это не единственный сервис, который может быть экспортирован посредством привязки порта. Почти любой тип серверного ПО может быть запущен как процесс привязанный к порту и ожидающий входящих запросов. Примеры включают [ejabberd](http://www.ejabberd.im/) (предоставляет [XMPP протокол](http://xmpp.org/)) и [Redis](http://redis.io/) (предоставляет [Redis протокол](http://redis.io/topics/protocol)). +HTTP -- это не единственный сервис, который может быть экспортирован посредством привязки порта. Почти любой тип серверного ПО может быть запущен как процесс, привязанный к порту и ожидающий входящих запросов. Примеры этого включают [ejabberd](http://www.ejabberd.im/) (предоставляет [XMPP протокол](http://xmpp.org/)) и [Redis](http://redis.io/) (предоставляет [Redis протокол](http://redis.io/topics/protocol)). -Также, обратите внимание, что подход привязки к порту означает, что одно приложение может выступать [сторонней службой](./backing-services) для другого приложения путём предоставления URL-адреса стороннего приложения как идентификатор ресурса в конфигурации потребляющего приложения. +Также обратите внимание, что подход привязки к порту означает, что одно приложение может выступать [сторонней службой](./backing-services) для другого приложения путём предоставления URL-адреса стороннего приложения как идентификатор ресурса в конфигурации потребляющего приложения. diff --git a/content/ru/processes.md b/content/ru/processes.md index f0d019de2..c45fc0035 100644 --- a/content/ru/processes.md +++ b/content/ru/processes.md @@ -1,14 +1,14 @@ ## VI. Процессы -### Запускайте приложение как один или несколько процессов не сохраняющих внутреннее состояние (stateless) +### Запускайте приложение как один или несколько процессов, не сохраняющих внутреннее состояние (stateless) Приложение выполняется в среде выполнения как один или несколько *процессов*. -В простейшем случае, код является независимым скриптом, среда выполнения ноутбуком разработчика с установленной средой исполнения языка, а процесс запускается из командной строки (например как `python my_script.py`). Другой крайний вариант -- это рабочее развёртывание сложного приложения, которое может использовать много [типов процессов, каждый из которых запущен в необходимом количестве экземпляров](./concurrency). +В простейшем случае код является независимым скриптом, среда выполнения -- ноутбуком разработчика с установленной средой исполнения языка, а процесс запускается из командной строки (например, как `python my_script.py`). Другой крайний вариант -- это рабочее развёртывание сложного приложения, которое может использовать много [типов процессов, каждый из которых запущен в необходимом количестве экземпляров](./concurrency). -**Процессы приложения двенадцати факторов не сохраняют внутреннее состояние (stateless) и [не имеют разделяемых данных (share-nothing)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Любые данные, которые требуется сохранять должны быть сохранены в хранящей состояние [сторонней службе](./backing-services), обычно в базе данных. +**Процессы приложения двенадцати факторов не сохраняют внутреннее состояние (stateless) и [не имеют разделяемых данных (share-nothing)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Любые данные, которые требуется сохранить, должны быть сохранены в хранящей состояние [сторонней службе](./backing-services), обычно, в базе данных. -Память и файловая система процесса может быть использована в качестве временного кэша для одной транзакции. Например, загрузка, обработка и сохранение большого файла в базе данных. Приложение двенадцати факторов не предполагает, что что-либо закэшированное в памяти или на диске будет доступно следующим запросам или задачам -- с большим количеством разноплановых процессов высока вероятность, что следующий запрос будет обработан другим процессом. Даже с одним запущенным процессом, перезапуск (вызванный развёртыванием, изменением конфигураций или переносом процесса на другое физическое устройство) приведет к уничтожению всех локальных (памяти, файловой системы) состояний. +Память и файловая система процесса может быть использована в качестве временного кэша для одной транзакции. Например, загрузка, обработка и сохранение большого файла в базе данных. Приложение двенадцати факторов не предполагает, что что-либо закэшированное в памяти или на диске будет доступно следующим запросам или задачам -- с большим количеством разноплановых процессов высока вероятность, что следующий запрос будет обработан другим процессом. Даже с одним запущенным процессом перезапуск (вызванный развёртыванием, изменением конфигураций или переносом процесса на другое физическое устройство) приведет к уничтожению всех локальных (памяти, файловой системы) состояний. -Упаковщики ресурсов (asset) (например, [Jammit](http://documentcloud.github.com/jammit/) или [django-compressor](http://django-compressor.readthedocs.org/)) используют файловую систему как кэш для скомпилированных ресурсов. Приложение двенадцати факторов предпочитает делать данную компиляцию во время [этапа сборки](./build-release-run), например как в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не во время выполнения. +Упаковщики ресурсов (asset) (например, [Jammit](http://documentcloud.github.com/jammit/) или [django-compressor](http://django-compressor.readthedocs.org/)) используют файловую систему как кэш для скомпилированных ресурсов. Приложение двенадцати факторов предпочитает делать данную компиляцию во время [этапа сборки](./build-release-run), например, как в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не во время выполнения. -Некоторые веб-системы полагаются на ["липкие сессий"] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- то есть, кэшируют данные пользовательских сессии в памяти процесса приложения и ожидают того, что последующие запросы того же пользователя будут перенаправлены к тому же процессу. Липкие сессии являются нарушением двенадцати факторов и их никогда не следует использовать или полагаться на них. Данные пользовательской сессии являются хорошими кандидатами для хранилища данных, которое предоставляет функцию ограничения времени хранения, например [Memcached](http://memcached.org/) и [Redis](http://redis.io/). +Некоторые веб-системы полагаются на ["липкие сессий"] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- то есть кэшируют данные пользовательских сессии в памяти процесса приложения и ожидают того, что последующие запросы того же пользователя будут перенаправлены к тому же процессу. Липкие сессии являются нарушением двенадцати факторов и их никогда не следует использовать или полагаться на них. Данные пользовательской сессии являются хорошими кандидатами для хранилища данных, которое предоставляет функцию ограничения времени хранения, например, [Memcached](http://memcached.org/) и [Redis](http://redis.io/). diff --git a/content/ru/toc.md b/content/ru/toc.md index 34ab8219e..aa56557f8 100644 --- a/content/ru/toc.md +++ b/content/ru/toc.md @@ -2,7 +2,7 @@ ================== ## [I. Кодовая база](./codebase) -### Одна кодовая база отслеживаемая в системе контроля версий, множество развертываний +### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развертываний ## [II. Зависимости](./dependencies) ### Явно объявляйте и изолируйте зависимости From 2623372c34910ab31eaf680d9e1d084fedc5e6ad Mon Sep 17 00:00:00 2001 From: clement Date: Fri, 22 May 2015 13:30:47 +0200 Subject: [PATCH 148/472] french translation Added all the chapters, TOC, who, background in french proofreading by bobmaerteens and eunomie update of the contributor list --- Readme.md | 3 +- content/fr/admin-processes.md | 14 ++++++ content/fr/background.md | 9 ++++ content/fr/backing-services.md | 14 ++++++ content/fr/build-release-run.md | 19 +++++++++ content/fr/codebase.md | 18 ++++++++ content/fr/concurrency.md | 14 ++++++ content/fr/config.md | 22 ++++++++++ content/fr/dependencies.md | 12 ++++++ content/fr/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/fr/disposability.md | 14 ++++++ content/fr/intro.md | 12 ++++++ content/fr/logs.md | 16 +++++++ content/fr/port-binding.md | 14 ++++++ content/fr/processes.md | 16 +++++++ content/fr/toc.md | 38 +++++++++++++++++ content/fr/who.md | 4 ++ locales/fr.yml | 7 +++ 18 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 content/fr/admin-processes.md create mode 100644 content/fr/background.md create mode 100644 content/fr/backing-services.md create mode 100644 content/fr/build-release-run.md create mode 100644 content/fr/codebase.md create mode 100644 content/fr/concurrency.md create mode 100644 content/fr/config.md create mode 100644 content/fr/dependencies.md create mode 100644 content/fr/dev-prod-parity.md create mode 100644 content/fr/disposability.md create mode 100644 content/fr/intro.md create mode 100644 content/fr/logs.md create mode 100644 content/fr/port-binding.md create mode 100644 content/fr/processes.md create mode 100644 content/fr/toc.md create mode 100644 content/fr/who.md create mode 100644 locales/fr.yml diff --git a/Readme.md b/Readme.md index 124a7ca56..a9403cbba 100644 --- a/Readme.md +++ b/Readme.md @@ -25,7 +25,8 @@ Created by Adam Wiggins Contributions from: James Lindenbaum, Mark McGranaghan, Chris Stolt, Ryan Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel -Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson +Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson, Clément +Camin, Bob Marteen Released under the MIT License: http://www.opensource.org/licenses/mit-license.php diff --git a/content/fr/admin-processes.md b/content/fr/admin-processes.md new file mode 100644 index 000000000..0db77d4f7 --- /dev/null +++ b/content/fr/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Processus d'administration +### Lancez les processus d'administration et de maintenance comme des processus + +La [formation de processus](./concurrency) est la liste des processus qui sont utilisés pour le fonctionnement normal de l'application (comme gérer les requêtes web) lorsqu'elle tourne. Les développeurs vont souvent vouloir effectuer des tâches occasionnelles d'administration ou de maintenance, comme : + +* Lancer les migrations de base de données (par ex. `manage.py migrate` avec Django, `rake db:migrate` avec Rails). +* Lancer une console (également appelée terminal [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) pour jouer du code arbitraire ou inspecter les modèles de l'application dans la base de donnée. La plupart des langages fournissent un terminal REPL en lançant l'interpréteur sans arguments (par exemple `python` ou `perl`), ou dans certains cas à l'aide d'une commande dédiée (par ex. `irb` pour Ruby, `rails console` pour Rails). +* Exécuter des scripts ponctuels inclus dans le dépot de code (par ex. `php scripts/fix_bad_records.php`). + +Les processus ponctuels d'administration devraient être lancés dans un environnement identique à ceux des [processus normaux non terminaux](./processes) de l'application. Ils s'exécutent sur une [release](./build-release-run), en utilisant la même [base de code](./codebase) et [configuration](./config) que tout processus qui tourne pour cette release. Le code d'administration doit être livré avec le code de l'application afin d'éviter les problèmes de synchronisation. + +La même technique d'[isolation de dépendances](./dependencies) doit être utilisée sur tous les types de processus. Par exemple, si le processus web de Ruby utilise la commande `bundle exec thin start`, alors une migration de base de données devrait être faite via `bundle exec rake db:migrate`. De la même manière, un programme Python qui utilise Virtualenv devrait utiliser la commande incluse `bin/python` pour lancer à la fois le serveur web Tornado et tout processus administrateur `manage.py`. + +Les applications 12 facteurs préfèrent les languages qui fournissent un terminal REPL prêt à l'emploi, et qui facilitent l'exécution de scripts ponctuels. Dans un déploiement local, les développeurs invoquent les processus ponctuels d'administration depuis le terminal, par une commande directement dans le répertoire où se trouve l'application. Dans un déploiement de production, les développeurs peuvent utiliser ssh ou d'autres mécanismes d'exécution de commandes fournis par l'environnement d'exécution de ce déploiement pour exécuter un tel processus. diff --git a/content/fr/background.md b/content/fr/background.md new file mode 100644 index 000000000..3b5367b45 --- /dev/null +++ b/content/fr/background.md @@ -0,0 +1,9 @@ +Contexte +========== + +Les contributeurs de ce document on été directement impliqués dans le développement et le déploiement de centaines d'applications, et ont vu, indirectement, le développement, la gestion et le grossissement de centaines de milliers d'applications via le travail fait sur la plateforme [Heroku](http://www.heroku.com/). + +Ce document fait la synthèse de toutes nos expériences et observations sur une large variété d'applications software-as-a-service. C'est la triangulation de pratiques idéales pour le développement d'applications, en portant un soin tout particulier aux dynamiques de la croissance organique d'une application au cours du temps, les dynamiques de la collaboration entre les développeurs qui travaillent sur le code de l'application, en [évitant le coût de la lente détérioration du logiciel dans un environnement qui évolue](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Notre motivation est de faire prendre conscience de certains problèmes systèmiques que nous avons rencontrés dans le développement d'applications modernes, afin de fournir un vocabulaire partagé pour discuter ces problèmes, et pour offrir un ensemble de solutions conceptuelles générales à ces problèmes, ainsi que la terminologie correspondante. Le format est inspiré par celui des livres de Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* et *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. + diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md new file mode 100644 index 000000000..167a88f0c --- /dev/null +++ b/content/fr/backing-services.md @@ -0,0 +1,14 @@ +## IV. Services externes +### Traitez les services externes comme des ressources attachées + +Un *service externe* (backing service) correspond à tout service que l'application utilise à travers le réseau pour son fonctionnement nominal. Cela concerne par exemple les bases de données (tel que [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), les systèmes de messages/files (tel que [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), les services SMTP pour l'envoi d'email (comme [Postfix](http://www.postfix.org/)), ainsi que les systèmes de cache (comme [Memcached](http://memcached.org/)). + +Les *service externe* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). + +**Le code d'une application 12 facteurs ne fait pas de distinction entre les services locaux et les services tiers**. Pour l'application, ce sont tous les deux des ressources attachées, accessibles via une URL ou un autre système de localisation et d'authentification stockée dans la [configuration](./config). Un [déploiement](./codebase) d'une application 12 facteurs doit pouvoir remplacer une base de données MySQL locale par une autre gérée par des tiers ([Amazon RDS](http://aws.amazon.com/rds/), par exemple) sans le moindre changement dans le code de l'application. De la même manière, un serveur SMTP local doit pouvoir être remplacé par un service tiers (Postmark, par exemple) sans changements dans le code. Dans les deux cas, seules les informations de configurations doivent changer. + +Chaque service externe est une *ressource*. Par exemple, une base de données MySQL est une ressource. Deux bases de données MySQL (utilisées pour faire du sharding dans la couche applicative) correspondent à deux ressources distinctes. L'application 12 facteurs traite ces base de données comme des ressources attachées, ce qui indique leur couplage faible au déploiement auquel elles sont rattachées. + +Un déploiement de production lié à quatre services externes. + +Les resources peuvent être attachées et détachées à volonté à des déploiements. Par exemple, si la base de données de l'application pose problème pour des raisons matérielles, l'administrateur de l'application peut vouloir lancer un nouveau serveur de base de données restauré à partir d'une sauvegarde récente. L'application courante pourrait être détachée à l'ancienne, puis rattachée à la nouvelle — le tout sans changement dans le code. diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md new file mode 100644 index 000000000..e3f331a8f --- /dev/null +++ b/content/fr/build-release-run.md @@ -0,0 +1,19 @@ +## V. Assemblez, publiez, exécutez +### Séparez strictment les étapes d'assemblage et d'exécution + +Une [base de code](./codebase) est transformée en un déploiement (non-développement) à travers les étapes suivantes : + +* L'*étapes d'assemblage* (ou "build") est une transformation qui convertit un dépôt de code en un paquet autonome exécutable appelé l'assemblage (ou "build"). En utilisant une version du code référencée par un commit spécifié lors du processus de déploiement, l'étape d'assemblage va chercher toutes les [dépendances externes](./dependencies) et compile les fichiers binaires et les ressources. +* L'*étape de publication * (ou "release") prend le l'assemblage produit à l'étape précédente et la combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'asseblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. +* L'*étape d'exécution* (ou "runtime") fait fonctionner l'application dans l'environnement d'exécution, en lancant un ensemble de [processus](./processes) de l'application associée à la release considérée. + +![Le code devient un assemblage, qui est combiné à la configuration pour créer une release](/images/release.png) + +**Les applications 12 facteurs ont une séparation stricte entre les étapes d'assemblage, de publication et d'exécution.** Par exemple, il est impossible de faire des changements dans le code au moment de son exécution, car il n'y a pas moyen de propager ces changements vers l'étape de build. + +Les outils de déploiement offrent généralement des outils de gestion de release, permettant notamment de revenir à une release antérieure. Par exemple, l'outil de déploiement [Capistrano](https://github.com/capistrano/capistrano/wiki) stocke les releases dans un sous-répertoire appelé `releases`, où la release courante est un lien symbolique vers le répertoire de release courante. Sa commande `rollback` permet de facilement revenir à une release précédente. + +Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). Les liste des releases est accessible en écriture uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. + +Les assemblages sont initiées par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entrainer des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolus par le développeur qui réalise le déploiement. + diff --git a/content/fr/codebase.md b/content/fr/codebase.md new file mode 100644 index 000000000..67842e1e8 --- /dev/null +++ b/content/fr/codebase.md @@ -0,0 +1,18 @@ +## I. Base de code +### Une base de code suivie avec un système de contrôle de version, plusieurs déploiements + +Une application 12 facteurs est toujours suivie dans un système de contrôle de version, tel que [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Une copie de la base de donnée de suivi des révisions est appelée *dépôt de code*, souvent raccourci en *dépôt*. Le terme anglais *code repository*, raccourci en *repository* et *repo* est également utilisé. + +Une *base de code* correspond à chaque dépôt (dans un système de contrôle de version centralisé tel que Subversion), ou tout ensemble de dépôts qui partage un commit racine (dans un système de contrôle de version décentralisé comme Git). + +![Une base de code est associée à plusieurs déploiements](/images/codebase-deploys.png) + +Il y a toujours un rapport direct entre la base de code et l'application : + +* S'il y a plusieurs bases de code, ce n'est pas une application, c'est un système distribué. Chaque composant du système distribué est une application, et chacun peut individuellement respecter la méthodologie 12 facteurs. +* Plusieurs applications qui partagent le même code est une violation des 12 facteurs. La solution dans ce cas est de factoriser le code partagé dans des librairies qui peuvent être intégrées via un [gestionnaire de dépendances](./dependencies). + +Il y a seulement une base de code par application, mais il y aura plusieurs déploiements de l'application. Un *déploiement* est une instance en fonctionnement de l'application. C'est, par exemple, le site en production, ou bien un ou plusieurs sites de validation. En plus de cela, chaque développeur a une copie de l'application qui fonctionne dans son environnement local de développement, ce qui compte également comme un déploiement. + +La base de code est la même à travers tous les déploiements, bien que différentes versions puisse être actives dans chaque déploiement. Par exemple, un développeur a des commits qui ne sont pas encore déployés dans l'environnement de validation. L'environnement de validation a des commits qui ne sont pas encore déployés en production. Par contre, ils partagent tous la même base de code, ce qui les identifie comme étant des déploiements différents d'une même application. + diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md new file mode 100644 index 000000000..a99a57fe6 --- /dev/null +++ b/content/fr/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrence +### Grossissez à l'aide du modèle de processus + +Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou plusieurs processus. Les applications web ont adopté différentes approches d'exécution de processus. Par exemple, les processus PHP s'exécutent comme des processus fils d'Apache, démarrés à la demande lorsque c'est requis par le volume de requêtes. Les processus Java ont adopté l'approche inverse, avec une machine virtuelle qui fournit un super-processus massif qui réserve un gros bloc de ressources système (processeur et mémoire) au démarrage, et la concurrence est gérée en interne à l'aide de threads. Dans les deux cas, les processus qui tournent sont à peine visibles aux développeurs de l'application. + +![La scalabilité est exprimée par des processus qui s'exécutent, la diversité de la charge de travail est exprimée par les types de processus](/images/process-types.png) + +**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". + +Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrone que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. + +Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et le nombre de processus de chaque type est appelée *formation de processus*. + +Les processus des applications 12 facteurs ne devraient [jamais être des daemons](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. diff --git a/content/fr/config.md b/content/fr/config.md new file mode 100644 index 000000000..61530f8b2 --- /dev/null +++ b/content/fr/config.md @@ -0,0 +1,22 @@ +## III. Configuration +### Stockez la configuration dans l'environnement + +La *configuration* d'une application est tout ce qui est susceptible de varier entre des [déploiements](./codebase) (validation, production, environnement de développement, etc). Cela inclue : + +* Les ressources gérées par la base de données, Memcached, ou tout autre [service de stockage](./backing-services) +* Les identifiants pour des services externes, tel qu'Amazon S3 ou Twitter +* Les valeurs spécifiques au déploiement, tel que son nom d'hôte canonique + +Les applications stockent parfois la configuration avec des constantes dans le code. C'est une violation des 12 facteurs, qui requiert une **stricte séparation de la configuration et du code**. La configuration peut varier substantiellement à travers les déploiements, alors que ce n'est pas le cas du code. + +Un bon moyen de tester si une application a correctement séparé son code, c'est de se demander si l'application pourrait être rendu open-source à tout instant, sans compromettre d'identifiants. + +Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connecté](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé via le code. + +Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un language ou un framework. + +**Les applications 12 facteurs stockent la configuration dans des *variables d'environnement*** (souvent raccourcies en *variables d'env*, ou *env*). Les variables d'environnement sont faciles à changer entre des déploiements sans changer le moindre code ; contrairement aux fichiers de configuration, il y a peu de chance pour qu'elles soient ajoutées au dépôt de code accidentellement ; et contrairement aux fichiers de configuration personnalisés, ou tout autre mécanisme de configuration comme les propriétés système Java, ce sont des standards agnostiques du langage ou du système d'exploitation. + +Un autre aspect de la gestion de configuration est le groupage. Parfois les applications regroupent la configuration dans des groupes nommés (souvent appelés les "environnements"), nommés ainsi d'après des déploiements spécifiques, comme les environnements `development`, `test`, et `production` de Rails. Cette méthode ne permet pas de grossir proprement : lorsque l'on ajoute de nouveaux déploiement à l'application, de nouveaux noms d'environnement sont nécessaires, comme `validation` ou `qa`. Quand le projet grossit encore plus, les développeurs vont avoir tendance à ajouter leur propres environnement particuliers, comme `joes-validation`, ce qui entraine une explosion combinatoire de la configuration qui rend la gestion des déploiement de l'application très fragile. + +Dans une application 12 facteurs, les variables d'environnement permettent un contrôle granulaire, chacune complètement orthogonale aux autres variables d'environnement. Elles ne sont jamais groupées ensemble en "environnements", mais sont plutôt gérées indépendamment pour chaque déploiement. C'est un modèle qui permet de grossir verticalement en souplesse, lorsque l'application grossit naturellement en un plus grand nombre de déploiements au cours de sa vie. diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md new file mode 100644 index 000000000..1abfdd8b3 --- /dev/null +++ b/content/fr/dependencies.md @@ -0,0 +1,12 @@ +## II. Dépendances +### Déclarez explicitement et isolez les dépendances + +La plupart des languages de programmation offrent des systèmes pour créer des paquets à partir de librairies afin de les distribuer, tel que [CPAN](http://www.cpan.org/) pour Perl ou [Rubygems](http://rubygems.org/) pour Ruby. Les librairies installées à travers un système de packaging peuvent être installés à travers tout le système, ou bien limités 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épendances 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, [Gem Bundler](http://gembundler.com/) 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. Peut importe la chaine 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 oeil à 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'asseblage 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, comme par exemple ImageMagick ou `curl`. Bien que ces outils puissent exister sur beaucoup voire la plupart des systèmes d'exploitations, 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. diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md new file mode 100644 index 000000000..5a0a7054f --- /dev/null +++ b/content/fr/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Parité dev/prod +### Gardez le développement, la validation et la production aussi proches que possible + +Historiquement, il y a eu un fossé conséquent entre le développent (un développeur qui fait des modifications sur un [déploiement](./codebase) local de l'application) et la production (un déploiement de l'application accessible aux utilisateurs finaux). Ce fossé se manifeste de trois manières : + +* **Le fossé temporel** : un développeur peut travailler sur du code qui peut prendre des jours, des semaines ou des mois avant d'aller en production +* **Le fossé des personnes** : les développeurs écrivent le code, et d'autres personnes le déploient. +* **Le fossé des outils** : les développeurs peuvent utiliser une pile comme Nginx, SQLite, et OS X, alors que le déploiement de production utilise Apache, MySQL, et Linux. + +**Les applications 12 facteurs sont conçues pour le [déploiement continu](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : + +* Réduire le fossé temporel : un développeur peut écrire du code et le déployer quelques heures ou même juste quelques minutes plus tard. +* Réduire le fossé des personnes : les personnes qui écrivent le code sont impliquées dans son déploiement et pour surveiller son comportement en production +* Réduire le fossé des outils : réduire, autant que possible, les différences entre le développement et la production + +Si l'on résume cela en un tableau : + + + + + + + + + + + + + + + + + + + + + + +
Application traditionnelleApplication 12 facteurs
Temps entre les déploiementsSemainesheures
Auteurs du code et ceux qui le déploientDes personnes différentesLes mêmes personnes
L'environnement de développement et celui de productionDivergentsAussi similaires que possible
+ +[Les services externes](./backing-services), tel que la base de données, la file de messages, ou le cache sont des éléments importants de la parité développement/production. La plupart des langages fournissent des librairies qui simplifient l'accès à ces services externes, en fournissant des adaptateurs pour différents types de services. Voici quelques exemples dans le tableau ci dessous. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLangageLibrarieAdaptateurs
Base de donnéesRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
File de messagesPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMémoire, système de fichiers, Memcached
+ +Les développeurs trouvent parfois agréable d'utiliser des services externes légers dans leur environnement local, alors qu'un service externe plus sérieux et robuste est utilisé en production. Par exemple, utiliser SQLite en local, et PostgreSQL en production; ou bien, durant le développement, mettre les données en cache dans la mémoire des processus locaux, et utiliser Memcached en production. + +**Les développeurs des applications 12 facteurs résistent au besoin d'utiliser des services externes différents entre le développement local et la production**, même lorsque les adaptateurs permettent d'abstraire en théorie beaucoup de différences entre les services externes. Les différences entre les services externes signifient que de petites incompatibilités surviennent, ce qui va faire que du code qui fonctionnait et qui passait les tests durant le développement ou la validation ne fonctionnera pas en production. Ce type d'erreurs crée de la friction en défaveur du déploiement continu. Le coût de cette friction et son impact négatif sur le déploiement continu est extrèmement élevé lorsqu'il est cumulé sur toute la vie de l'application. + +Les services locaux légers sont moins attirants aujourd'hui qu'ils ne l'étaient autrefois. Les services externes modernes tel que Memcached, PostgreSQL, et RabbitMQ ne sont pas difficiles à installer et à faire fonctionner grâce aux systèmes de paquets modernes comme [Homebrew](http://mxcl.github.com/homebrew/) et [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Autre possibilité, des outils de provisionnement comme [Chef](http://www.opscode.com/chef/) et [Puppet](http://docs.puppetlabs.com/), combinés à des environnements virtuels légers comme [Vagrant](http://vagrantup.com/) permettent aux développeurs de faire fonctionner des environnements locaux qui reproduisent de très près les environnements de production. Le coût d'installation et d'utilisation de ces systèmes est faible comparé aux bénéfices d'une bonne parité développement/production et du déploiement continu. + +Les adaptateurs à ces différents systèmes externes sont malgré tout utiles, car ils rendent le portage vers de nouveaux services externes relativement indolores. Mais tous les déploiements de l'application (environnement de développement, validation, production) devraient utiliser le même type et la même version de chacun de ces services externes. diff --git a/content/fr/disposability.md b/content/fr/disposability.md new file mode 100644 index 000000000..2df6694fb --- /dev/null +++ b/content/fr/disposability.md @@ -0,0 +1,14 @@ +## IX. Jetable +### Maximisez la robustessse avec des démarrages rapides et des arrêts gracieux + +**Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est à dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustess des déploiements de production. + +Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release)(./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. + +Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. + +Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le orker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente](http://fr.wikipedia.org/wiki/Idempotence). + +Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non gracieuses. Le [design crash-only](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique](http://docs.couchdb.org/en/latest/intro/overview.html). + + diff --git a/content/fr/intro.md b/content/fr/intro.md new file mode 100644 index 000000000..97ee31241 --- /dev/null +++ b/content/fr/intro.md @@ -0,0 +1,12 @@ +Introduction +============ + +A l'époque actuelle, les logiciels sont régulièrement délivrés en tant que services : on les appelles 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 adapaté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 continue* pour une agilité maximum; +* et peuvent **grossir verticalement** sans changements significatifs 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ée, file, cache mémoire, etc.) diff --git a/content/fr/logs.md b/content/fr/logs.md new file mode 100644 index 000000000..c721c22c3 --- /dev/null +++ b/content/fr/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Traitez les logs comme des flux d'évènements + +Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits sur un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. + +Les logs sont des [flux](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. + +**Une application 12 facteurs ne s'inquiète jamais du routage ou du stockage de ses flux de sortie.** Elle ne devrait pas tenter d'écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d'événements, sans tampon, vers `stdout`, la sortie standard ; en phase de développement local, les développeurs pourront voir ce flux dans leur terminal et observer le comportement de l'application. + +Dans les déploiements de validation ou de production, les flux de chaque processus seront capturés par leur environnement d'exécution, assemblés avec les autres flux de l'application, et routés vers une ou plusieurs destinations pour un visionnage et un archivage de longue durée. Le lieu d'archivage n'est pas visible et ne peut être configuré par l'application : ils sont complètements gérés par l'environnement d'exécution. Des routeurs opensource de logs, (tel que [Logplex](https://github.com/heroku/logplex) et [Fluent](https://github.com/fluent/fluentd)) existent pour cela. + +Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepot de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : + +* Trouver un événements spécifique dans le passé +* Faire des graphiques à grande échelle des tendances (comme les requêtes par minutes) +* Lever des alertes, à partir d'heuristiques définies par l'utilisateur (comme alerter dès que la quantité d'erreurs par minutes dépasse un certain seuil) diff --git a/content/fr/port-binding.md b/content/fr/port-binding.md new file mode 100644 index 000000000..4e90f9f42 --- /dev/null +++ b/content/fr/port-binding.md @@ -0,0 +1,14 @@ +## 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 [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 librairie de serveur web, tel que [Tornado](http://www.tornadoweb.org/) pour Python, [Thin](http://code.macournoyer.com/thin/) pour Ruby, ou [Jetty](http://jetty.codehaus.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. diff --git a/content/fr/processes.md b/content/fr/processes.md new file mode 100644 index 000000000..500911122 --- /dev/null +++ b/content/fr/processes.md @@ -0,0 +1,16 @@ +## VI. Processus +### Exécutez l'application comme un ou plusieurs processus sans état + +L'application est exécutée dans l'environnement d'exécution comme un ou plusieurs *processus*. + +Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiqué peut utiliser plusieurs [types de processus, instanciés dans 0 ou plus processus en fonctionnement](./concurrency). + +**Les processus 12 facteurs sont sans état et ne partagent [rien](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. + +L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de donnes. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est à dire en mémoire et sur le disque). + +Des outils de création de paquets de ressources (ou "asset packagers") (tel que [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) utilisent le système de fichier comme cache pour les ressources compilées. Une application 12 facteurs préfère faire cette compilation durant l'[étape d'assemblage](./build-release-run), comme avec le [pipeline des ressources de Rails](http://guides.rubyonrails.org/asset_pipeline.html), plutôt que durant l'exécution. + +Certains systèmes web s'appuient sur des ["sessions persistantes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- c'est à dire, mettre en cache les données de session utilisateur dans le processus de l'application et attendre que les requêtes futures du même visiteur seront routées dans le même process. Les sessions persistantes sont une violation des 12 facteurs, qu'il ne faudrait jamais utiliser. +Les états de session sont de bons candidats pour un datastore qui offre des dates d'expiration, comme [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). + diff --git a/content/fr/toc.md b/content/fr/toc.md new file mode 100644 index 000000000..f1d516d41 --- /dev/null +++ b/content/fr/toc.md @@ -0,0 +1,38 @@ +Les 12 facteurs +================== + +## [I. Base de code](./codebase) +### Une base de code suivie avec un système de contrôle de version, plusieurs déploiements + +## [II. Dépendances](./dependencies) +### Déclarez explicitement et isolez les dépendances + +## [III. Configuration](./config) +### Stockez la configuration dans l'environnement + +## [IV. Services externes](./backing-services) +### Traitez les services externes comme des ressources attachées + +## [V. Build, release, run](./build-release-run) +### Séparez strictement les étapes d'assemblage et d'exécution + +## [VI. Processus](./processes) +### Exécutez l'application comme un ou plusieurs processus sans état + +## [VII. Associations de ports](./port-binding) +### Exportez les services via des associations de ports + +## [VIII. Concurrence](./concurrency) +### Grossissez à l'aide du modèle de processus + +## [IX. Jetable](./disposability) +### Maximisez la robustessse avec des démarrages rapides et des arrêts gracieux + +## [X. Parité dev/prod](./dev-prod-parity) +### Gardez le développement, la validation et la production aussi proches que possible + +## [XI. Logs](./logs) +### Traitez les logs comme des flux d'évènements + +## [XII. Processus d'administration](./admin-processes) +### Lancez les processus d'administration et de maintenance comme des processus diff --git a/content/fr/who.md b/content/fr/who.md new file mode 100644 index 000000000..3396c7aec --- /dev/null +++ b/content/fr/who.md @@ -0,0 +1,4 @@ +Qui devrait lire ce document ? +============================== + +Tout développeur qui construit des applications qui fonctionnent en tant que service, ainsi que les personnes qui déploient et gèrent de telles applications. diff --git a/locales/fr.yml b/locales/fr.yml new file mode 100644 index 000000000..b00ac5da8 --- /dev/null +++ b/locales/fr.yml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: "Français (fr)" + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Ce texte est une traduction" From a7e7d8fc7780d08706b224613c1a605807ebd639 Mon Sep 17 00:00:00 2001 From: Evgeny Vlasenko Date: Sat, 13 Jun 2015 12:43:08 +0600 Subject: [PATCH 149/472] russian translation: better translation for `disposability` word --- content/ru/disposability.md | 4 ++-- content/ru/toc.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ru/disposability.md b/content/ru/disposability.md index 5615cd8a0..ebf82d80d 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -1,7 +1,7 @@ -## IX. Одноразовость (Disposability) +## IX. Утилизируемость (Disposability) ### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы -**[Процессы](./processes) приложения двенадцати факторов являются *одноразовыми*, это означает, что они могут быть запущены и остановилены любой в момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. +**[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановилены любой в момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. Процессы должны стараться **минимизировать время запуска**. В идеале процесс должен затратить всего несколько секунд от момента времени, когда выполнена команда запуска, и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет большую гибкость для [релиза](./build-release-run) и масштабирования. Кроме того, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. diff --git a/content/ru/toc.md b/content/ru/toc.md index aa56557f8..752433217 100644 --- a/content/ru/toc.md +++ b/content/ru/toc.md @@ -25,7 +25,7 @@ ## [VIII. Параллелизм](./concurrency) ### Масштабируйте приложение с помошью процессов -## [IX. Одноразовость (Disposability)](./disposability) +## [IX. Утилизируемость (Disposability)](./disposability) ### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы ## [X. Паритет разработки/работы приложения](./dev-prod-parity) From 79dd0df3cf33118693a0949c653ddd16f864282d Mon Sep 17 00:00:00 2001 From: yongsung Date: Thu, 18 Jun 2015 17:39:23 +0900 Subject: [PATCH 150/472] Fixed typo in Korean --- content/ko/backing-services.md | 6 +++--- content/ko/config.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/ko/backing-services.md b/content/ko/backing-services.md index a82ac560b..cec356f47 100644 --- a/content/ko/backing-services.md +++ b/content/ko/backing-services.md @@ -1,11 +1,11 @@ -## IV. 백엑드 서비스 +## IV. 백엔드 서비스 ### 백엔드 서비스를 연결된 리소스로 취급 *백엔드 서비스*는 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스입니다. 예를 들어, 데이터 저장소(예: [MySQL](http://dev.mysql.com/), [CouchDB](http://couchdb.apache.org/)), 메시지 큐잉 시스템(예: [RabbitMQ](http://www.rabbitmq.com/), [Beanstalkd](http://kr.github.com/beanstalkd/)), 메일을 보내기 위한 SMTP 서비스 (예: [Postfix](http://www.postfix.org/)), 캐시 시스템(예: [Memcached](http://memcached.org/)) 등이 있습니다. -데이터 저장소와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))등이 있습니다. +데이터베이스와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))등이 있습니다. -**Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다.** 애플리케이션에게는 양 쪽 모두 연결된 리소스이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. +**Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다.** 애플리케이션에게는 양 쪽 모두 연결된 리소스이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. 각각의 다른 백엔드 서비스는 *리소스*입니다. 예를 들어, 하나의 MySQL DB는 하나의 리소스입니다. 애플리케이션 레이어에서 샤딩을 하는 두 개의 MySQL 데이터베이스는 두 개의 서로 다른 리소스라고 볼 수 있습니다. Twelve-Factor App은 이러한 데이터베이스들을 *첨부된(Attached) 리소스*으로 다룹니다. 이는 서로 느슨하게 결합된다는 점을 암시합니다. diff --git a/content/ko/config.md b/content/ko/config.md index 4fc4415f9..6675e5184 100644 --- a/content/ko/config.md +++ b/content/ko/config.md @@ -7,7 +7,7 @@ * Amazon S3 이나 트위터 등의 외부 서비스 인증 정보 * 배포된 호스트의 정규화된 호스트 이름(canonical hostname)처럼 각 배포마다 달라지는 값 -애플리케이션은 종종 설정을 상수로 코드에 저장합니다. 이것은 Twelve-Factor를 위한하며, Twelve-Factor는 **설정을 코드에서 엄격하게 분리하는 것**을 요구합니다. 설정은 배치마다 크게 다르지만, 코드는 그렇지 않습니다. +애플리케이션은 종종 설정을 상수로 코드에 저장합니다. 이것은 Twelve-Factor를 위반하며, Twelve-Factor는 **설정을 코드에서 엄격하게 분리하는 것**을 요구합니다. 설정은 배치마다 크게 다르지만, 코드는 그렇지 않습니다. 애플리케이션의 모든 설정이 정상적으로 코드 바깥으로 분리되어 있는지 확인할 수 있는 간단한 테스트는 어떠한 인증정보도 유출시키지 않고 코드베이스가 지금 당장 오픈 소스가 될 수 있는지 확인하는 것입니다. From 12d7f05d8df0d580fcafb3fc9e71ffdea0196f4d Mon Sep 17 00:00:00 2001 From: yongsung Date: Thu, 18 Jun 2015 17:45:13 +0900 Subject: [PATCH 151/472] Fixed wrong translation in Korean --- content/ko/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/admin-processes.md b/content/ko/admin-processes.md index 206a33e95..5648e8cdd 100644 --- a/content/ko/admin-processes.md +++ b/content/ko/admin-processes.md @@ -9,7 +9,7 @@ 일회성 admin 프로세스는 애플리케이션의 일반적인 [오래 실행되는 프로세스](./processes)들과 동일한 환경에서 실행되어야 합니다. 일회성 admin 프로세스들은 릴리즈를 기반으로 실행되며, 해당 릴리즈를 기반으로 돌아가는 모든 프로세스처럼 같은 [코드베이스](./codebase)와 [설정](./config)를 사용해야 합니다. admin 코드는 동기화 문제를 피하기 위해 애플리케이션 코드와 함께 배포되어야 합니다. -모든 종류 프로세스는 같은 [종속성](./dependencies)을 가져야 합니다. 예를 들어, +모든 프로세스 타입들에는 동일한 [종속성 분리](./dependencies) 기술이 사용되어야 합니다. 예를 들어, 루비 웹 프로세스가 `bundle exec thin start` 명령어를 사용한다면, 데이터베이스 마이그레이션은 `bundle exec rake db:migrate`를 사용해야합니다. 마찬가지로, virtualenv를 사용하는 파이썬 프로그램은 tornado 웹 서버와 모든 `manage.py` admin 프로세스가 같은 virtualenv에서의 `bin/python`을 사용해야 합니다. -Twelve-Factor는 별도의 설치나 구성없이 REPL shell을 제공하는 언어를 강하게 선호합니다. 이러한 점은 일회성 스크립트를 실행하기 쉽게 만들어주기 때문입니다. 로컬 배포에서, 개발자는 앱을 체크아웃한 디렉토리에서 일회성 admin 프로세스를 shell 명령어로 바로 실행시킵니다. production 배포에서, 개발자는 ssh나 배포의 실행 환경에서 제공하는 다른 원격 명령어 실행 메커니즘을 사용하여 admin 프로세스를 실행할 수 있습니다. \ No newline at end of file +Twelve-Factor는 별도의 설치나 구성없이 REPL shell을 제공하는 언어를 강하게 선호합니다. 이러한 점은 일회성 스크립트를 실행하기 쉽게 만들어주기 때문입니다. 로컬 배포에서, 개발자는 앱을 체크아웃한 디렉토리에서 일회성 admin 프로세스를 shell 명령어로 바로 실행시킵니다. production 배포에서, 개발자는 ssh나 배포의 실행 환경에서 제공하는 다른 원격 명령어 실행 메커니즘을 사용하여 admin 프로세스를 실행할 수 있습니다. \ No newline at end of file From 9d47d1713b96a99ab7c32fbe30065eaccf26e4ac Mon Sep 17 00:00:00 2001 From: mengyd Date: Mon, 29 Jun 2015 00:36:54 +0800 Subject: [PATCH 152/472] =?UTF-8?q?change=20'=E5=86=A5=E7=AD=89'=20to=20'?= =?UTF-8?q?=E5=B9=82=E7=AD=89'.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/zh_cn/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/disposability.md b/content/zh_cn/disposability.md index bae8394b4..dbb4444f7 100644 --- a/content/zh_cn/disposability.md +++ b/content/zh_cn/disposability.md @@ -7,7 +7,7 @@ 进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 -对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [冥等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 +对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [幂等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。[Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 From 53c6171684c2b9557814ddf6c4927f80ef7fc129 Mon Sep 17 00:00:00 2001 From: clement Date: Mon, 29 Jun 2015 10:16:45 +0200 Subject: [PATCH 153/472] fixed typo --- content/fr/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/background.md b/content/fr/background.md index 3b5367b45..7b8e84d3a 100644 --- a/content/fr/background.md +++ b/content/fr/background.md @@ -1,7 +1,7 @@ Contexte ========== -Les contributeurs de ce document on été directement impliqués dans le développement et le déploiement de centaines d'applications, et ont vu, indirectement, le développement, la gestion et le grossissement de centaines de milliers d'applications via le travail fait sur la plateforme [Heroku](http://www.heroku.com/). +Les contributeurs de ce document ont été directement impliqués dans le développement et le déploiement de centaines d'applications, et ont vu, indirectement, le développement, la gestion et le grossissement de centaines de milliers d'applications via le travail fait sur la plateforme [Heroku](http://www.heroku.com/). Ce document fait la synthèse de toutes nos expériences et observations sur une large variété d'applications software-as-a-service. C'est la triangulation de pratiques idéales pour le développement d'applications, en portant un soin tout particulier aux dynamiques de la croissance organique d'une application au cours du temps, les dynamiques de la collaboration entre les développeurs qui travaillent sur le code de l'application, en [évitant le coût de la lente détérioration du logiciel dans un environnement qui évolue](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). From c00922dee3e70123d80ecf0fc3f2a38df84af999 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 29 Jun 2015 13:29:42 +0100 Subject: [PATCH 154/472] fix config for Italiano --- locales/it.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/it.yml b/locales/it.yml index e16ec3c69..a2ce7cff0 100644 --- a/locales/it.yml +++ b/locales/it.yml @@ -1,7 +1,7 @@ -en: +it: # Name of language listed in locales menu - language: Italiano + language: Italiano (it) # A text to make known that the article is a translation not an original. # Empty for English, original. - translation: "Questo testo è una traduzione della versione originale in Inglese." + translation: (Questo testo è una traduzione della versione originale in Inglese.) From b01bc21685a97076f66500bf442aa1d6b8b997c1 Mon Sep 17 00:00:00 2001 From: clement Date: Tue, 30 Jun 2015 11:35:54 +0200 Subject: [PATCH 155/472] fixed stuff noticed by dmathieu --- content/fr/admin-processes.md | 6 +++--- content/fr/background.md | 4 ++-- content/fr/backing-services.md | 2 +- content/fr/build-release-run.md | 4 ++-- content/fr/concurrency.md | 4 ++-- content/fr/config.md | 2 +- content/fr/dependencies.md | 2 +- content/fr/dev-prod-parity.md | 4 ++-- content/fr/disposability.md | 10 +++++----- content/fr/logs.md | 2 +- content/fr/processes.md | 4 ++-- content/fr/toc.md | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/content/fr/admin-processes.md b/content/fr/admin-processes.md index 0db77d4f7..69ff90f02 100644 --- a/content/fr/admin-processes.md +++ b/content/fr/admin-processes.md @@ -1,13 +1,13 @@ ## XII. Processus d'administration -### Lancez les processus d'administration et de maintenance comme des processus +### Lancez les processus d'administration et de maintenance comme des one-off-processes La [formation de processus](./concurrency) est la liste des processus qui sont utilisés pour le fonctionnement normal de l'application (comme gérer les requêtes web) lorsqu'elle tourne. Les développeurs vont souvent vouloir effectuer des tâches occasionnelles d'administration ou de maintenance, comme : * Lancer les migrations de base de données (par ex. `manage.py migrate` avec Django, `rake db:migrate` avec Rails). -* Lancer une console (également appelée terminal [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) pour jouer du code arbitraire ou inspecter les modèles de l'application dans la base de donnée. La plupart des langages fournissent un terminal REPL en lançant l'interpréteur sans arguments (par exemple `python` ou `perl`), ou dans certains cas à l'aide d'une commande dédiée (par ex. `irb` pour Ruby, `rails console` pour Rails). +* Lancer une console (également appelée terminal [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) pour exécuter du code arbitraire ou inspecter les modèles de l'application dans la base de donnée. La plupart des langages fournissent un terminal REPL en lançant l'interpréteur sans arguments (par exemple `python` ou `perl`), ou dans certains cas à l'aide d'une commande dédiée (par ex. `irb` pour Ruby, `rails console` pour Rails). * Exécuter des scripts ponctuels inclus dans le dépot de code (par ex. `php scripts/fix_bad_records.php`). -Les processus ponctuels d'administration devraient être lancés dans un environnement identique à ceux des [processus normaux non terminaux](./processes) de l'application. Ils s'exécutent sur une [release](./build-release-run), en utilisant la même [base de code](./codebase) et [configuration](./config) que tout processus qui tourne pour cette release. Le code d'administration doit être livré avec le code de l'application afin d'éviter les problèmes de synchronisation. +Les processus ponctuels d'administration devraient être lancés dans un environnement identique à ceux des [processus standards](./processes) de l'application. Ils s'exécutent sur une [release](./build-release-run), en utilisant la même [base de code](./codebase) et [configuration](./config) que tout processus qui tourne pour cette release. Le code d'administration doit être livré avec le code de l'application afin d'éviter les problèmes de synchronisation. La même technique d'[isolation de dépendances](./dependencies) doit être utilisée sur tous les types de processus. Par exemple, si le processus web de Ruby utilise la commande `bundle exec thin start`, alors une migration de base de données devrait être faite via `bundle exec rake db:migrate`. De la même manière, un programme Python qui utilise Virtualenv devrait utiliser la commande incluse `bin/python` pour lancer à la fois le serveur web Tornado et tout processus administrateur `manage.py`. diff --git a/content/fr/background.md b/content/fr/background.md index 7b8e84d3a..d5a179a0e 100644 --- a/content/fr/background.md +++ b/content/fr/background.md @@ -3,7 +3,7 @@ Contexte Les contributeurs de ce document ont été directement impliqués dans le développement et le déploiement de centaines d'applications, et ont vu, indirectement, le développement, la gestion et le grossissement de centaines de milliers d'applications via le travail fait sur la plateforme [Heroku](http://www.heroku.com/). -Ce document fait la synthèse de toutes nos expériences et observations sur une large variété d'applications software-as-a-service. C'est la triangulation de pratiques idéales pour le développement d'applications, en portant un soin tout particulier aux dynamiques de la croissance organique d'une application au cours du temps, les dynamiques de la collaboration entre les développeurs qui travaillent sur le code de l'application, en [évitant le coût de la lente détérioration du logiciel dans un environnement qui évolue](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +Ce document fait la synthèse de toutes nos expériences et observations sur une large variété d'applications software-as-a-service. C'est la triangulation de pratiques idéales pour le développement d'applications, en portant un soin tout particulier aux dynamiques de la croissance organique d'une application au cours du temps, les dynamiques de la collaboration entre les développeurs qui travaillent sur le code de l'application, en [évitant le coût de la lente détérioration du logiciel dans un environnement qui évolue (en)](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). -Notre motivation est de faire prendre conscience de certains problèmes systèmiques que nous avons rencontrés dans le développement d'applications modernes, afin de fournir un vocabulaire partagé pour discuter ces problèmes, et pour offrir un ensemble de solutions conceptuelles générales à ces problèmes, ainsi que la terminologie correspondante. Le format est inspiré par celui des livres de Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* et *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +Notre motivation est de faire prendre conscience de certains problèmes systémiques que nous avons rencontrés dans le développement d'applications modernes, afin de fournir un vocabulaire partagé pour discuter ces problèmes, et pour offrir un ensemble de solutions conceptuelles générales à ces problèmes, ainsi que la terminologie correspondante. Le format est inspiré par celui des livres de Martin Fowler *[Patterns of Enterprise Application Architecture (en)](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* et *[Refactoring (en)](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md index 167a88f0c..7913f39e2 100644 --- a/content/fr/backing-services.md +++ b/content/fr/backing-services.md @@ -3,7 +3,7 @@ Un *service externe* (backing service) correspond à tout service que l'application utilise à travers le réseau pour son fonctionnement nominal. Cela concerne par exemple les bases de données (tel que [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), les systèmes de messages/files (tel que [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), les services SMTP pour l'envoi d'email (comme [Postfix](http://www.postfix.org/)), ainsi que les systèmes de cache (comme [Memcached](http://memcached.org/)). -Les *service externe* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). +Les *services externes* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). **Le code d'une application 12 facteurs ne fait pas de distinction entre les services locaux et les services tiers**. Pour l'application, ce sont tous les deux des ressources attachées, accessibles via une URL ou un autre système de localisation et d'authentification stockée dans la [configuration](./config). Un [déploiement](./codebase) d'une application 12 facteurs doit pouvoir remplacer une base de données MySQL locale par une autre gérée par des tiers ([Amazon RDS](http://aws.amazon.com/rds/), par exemple) sans le moindre changement dans le code de l'application. De la même manière, un serveur SMTP local doit pouvoir être remplacé par un service tiers (Postmark, par exemple) sans changements dans le code. Dans les deux cas, seules les informations de configurations doivent changer. diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index e3f331a8f..f541cb58a 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -4,7 +4,7 @@ Une [base de code](./codebase) est transformée en un déploiement (non-développement) à travers les étapes suivantes : * L'*étapes d'assemblage* (ou "build") est une transformation qui convertit un dépôt de code en un paquet autonome exécutable appelé l'assemblage (ou "build"). En utilisant une version du code référencée par un commit spécifié lors du processus de déploiement, l'étape d'assemblage va chercher toutes les [dépendances externes](./dependencies) et compile les fichiers binaires et les ressources. -* L'*étape de publication * (ou "release") prend le l'assemblage produit à l'étape précédente et la combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'asseblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. +* L'*étape de publication * (ou "release") prend le l'assemblage produit à l'étape précédente et la combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'assemblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. * L'*étape d'exécution* (ou "runtime") fait fonctionner l'application dans l'environnement d'exécution, en lancant un ensemble de [processus](./processes) de l'application associée à la release considérée. ![Le code devient un assemblage, qui est combiné à la configuration pour créer une release](/images/release.png) @@ -15,5 +15,5 @@ Les outils de déploiement offrent généralement des outils de gestion de relea Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). Les liste des releases est accessible en écriture uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. -Les assemblages sont initiées par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entrainer des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolus par le développeur qui réalise le déploiement. +Les assemblages sont initiées par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entrainer des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolues par le développeur qui réalise le déploiement. diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index a99a57fe6..2aae5d574 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -5,10 +5,10 @@ Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou pl ![La scalabilité est exprimée par des processus qui s'exécutent, la diversité de la charge de travail est exprimée par les types de processus](/images/process-types.png) -**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". +**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrone que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et le nombre de processus de chaque type est appelée *formation de processus*. -Les processus des applications 12 facteurs ne devraient [jamais être des daemons](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. +Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. diff --git a/content/fr/config.md b/content/fr/config.md index 61530f8b2..82cefee7d 100644 --- a/content/fr/config.md +++ b/content/fr/config.md @@ -11,7 +11,7 @@ Les applications stockent parfois la configuration avec des constantes dans le c Un bon moyen de tester si une application a correctement séparé son code, c'est de se demander si l'application pourrait être rendu open-source à tout instant, sans compromettre d'identifiants. -Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connecté](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé via le code. +Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connecté (en)](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé dans le code. Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un language ou un framework. diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index 1abfdd8b3..1205db958 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -7,6 +7,6 @@ La plupart des languages de programmation offrent des systèmes pour créer des Par exemple, [Gem Bundler](http://gembundler.com/) 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. Peut importe la chaine 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 oeil à 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'asseblage pour Ruby/Bundler est `bundle install`, alors que pour Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'est `lein deps`. +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 oeil à 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, comme par exemple ImageMagick ou `curl`. Bien que ces outils puissent exister sur beaucoup voire la plupart des systèmes d'exploitations, 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. diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index 5a0a7054f..bdccc4471 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -1,13 +1,13 @@ ## X. Parité dev/prod ### Gardez le développement, la validation et la production aussi proches que possible -Historiquement, il y a eu un fossé conséquent entre le développent (un développeur qui fait des modifications sur un [déploiement](./codebase) local de l'application) et la production (un déploiement de l'application accessible aux utilisateurs finaux). Ce fossé se manifeste de trois manières : +Historiquement, il y a eu un fossé conséquent entre le développement (un développeur qui fait des modifications sur un [déploiement](./codebase) local de l'application) et la production (un déploiement de l'application accessible aux utilisateurs finaux). Ce fossé se manifeste de trois manières : * **Le fossé temporel** : un développeur peut travailler sur du code qui peut prendre des jours, des semaines ou des mois avant d'aller en production * **Le fossé des personnes** : les développeurs écrivent le code, et d'autres personnes le déploient. * **Le fossé des outils** : les développeurs peuvent utiliser une pile comme Nginx, SQLite, et OS X, alors que le déploiement de production utilise Apache, MySQL, et Linux. -**Les applications 12 facteurs sont conçues pour le [déploiement continu](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : +**Les applications 12 facteurs sont conçues pour le [déploiement continu (en)](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : * Réduire le fossé temporel : un développeur peut écrire du code et le déployer quelques heures ou même juste quelques minutes plus tard. * Réduire le fossé des personnes : les personnes qui écrivent le code sont impliquées dans son déploiement et pour surveiller son comportement en production diff --git a/content/fr/disposability.md b/content/fr/disposability.md index 2df6694fb..3d9ead3e3 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -1,14 +1,14 @@ ## IX. Jetable -### Maximisez la robustessse avec des démarrages rapides et des arrêts gracieux +### Maximisez la robustesse avec des démarrages rapides et des arrêts gracieux -**Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est à dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustess des déploiements de production. +**Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est à dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustesse des déploiements de production. Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release)(./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. -Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. +Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. -Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le orker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente](http://fr.wikipedia.org/wiki/Idempotence). +Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le orker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). -Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non gracieuses. Le [design crash-only](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique](http://docs.couchdb.org/en/latest/intro/overview.html). +Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non gracieuses. Le [design crash-only (en)](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique (en)](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/fr/logs.md b/content/fr/logs.md index c721c22c3..a78bc6ac3 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -3,7 +3,7 @@ Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits sur un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. -Les logs sont des [flux](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. +Les logs sont des [flux (en)](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. **Une application 12 facteurs ne s'inquiète jamais du routage ou du stockage de ses flux de sortie.** Elle ne devrait pas tenter d'écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d'événements, sans tampon, vers `stdout`, la sortie standard ; en phase de développement local, les développeurs pourront voir ce flux dans leur terminal et observer le comportement de l'application. diff --git a/content/fr/processes.md b/content/fr/processes.md index 500911122..cd7a0c78d 100644 --- a/content/fr/processes.md +++ b/content/fr/processes.md @@ -5,12 +5,12 @@ L'application est exécutée dans l'environnement d'exécution comme un ou plusi Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiqué peut utiliser plusieurs [types de processus, instanciés dans 0 ou plus processus en fonctionnement](./concurrency). -**Les processus 12 facteurs sont sans état et ne partagent [rien](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. +**Les processus 12 facteurs sont sans état et ne partagent [rien (en)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de donnes. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est à dire en mémoire et sur le disque). Des outils de création de paquets de ressources (ou "asset packagers") (tel que [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) utilisent le système de fichier comme cache pour les ressources compilées. Une application 12 facteurs préfère faire cette compilation durant l'[étape d'assemblage](./build-release-run), comme avec le [pipeline des ressources de Rails](http://guides.rubyonrails.org/asset_pipeline.html), plutôt que durant l'exécution. -Certains systèmes web s'appuient sur des ["sessions persistantes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- c'est à dire, mettre en cache les données de session utilisateur dans le processus de l'application et attendre que les requêtes futures du même visiteur seront routées dans le même process. Les sessions persistantes sont une violation des 12 facteurs, qu'il ne faudrait jamais utiliser. +Certains systèmes web s'appuient sur des ["sessions persistantes" (en)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- c'est à dire, mettre en cache les données de session utilisateur dans le processus de l'application et attendre que les requêtes futures du même visiteur seront routées dans le même process. Les sessions persistantes sont une violation des 12 facteurs, qu'il ne faudrait jamais utiliser. Les états de session sont de bons candidats pour un datastore qui offre des dates d'expiration, comme [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). diff --git a/content/fr/toc.md b/content/fr/toc.md index f1d516d41..6acb2daf5 100644 --- a/content/fr/toc.md +++ b/content/fr/toc.md @@ -26,7 +26,7 @@ Les 12 facteurs ### Grossissez à l'aide du modèle de processus ## [IX. Jetable](./disposability) -### Maximisez la robustessse avec des démarrages rapides et des arrêts gracieux +### Maximisez la robustesse avec des démarrages rapides et des arrêts gracieux ## [X. Parité dev/prod](./dev-prod-parity) ### Gardez le développement, la validation et la production aussi proches que possible @@ -35,4 +35,4 @@ Les 12 facteurs ### Traitez les logs comme des flux d'évènements ## [XII. Processus d'administration](./admin-processes) -### Lancez les processus d'administration et de maintenance comme des processus +### Lancez les processus d'administration et de maintenance comme des one-off-processes From eaada4858c23b0863db54c0a5dc235dcea68d788 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Tue, 30 Jun 2015 13:41:28 +0100 Subject: [PATCH 156/472] list a whole bunch of folk who help maintain this --- Readme.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index a9403cbba..e77ea5f58 100644 --- a/Readme.md +++ b/Readme.md @@ -25,8 +25,9 @@ Created by Adam Wiggins Contributions from: James Lindenbaum, Mark McGranaghan, Chris Stolt, Ryan Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel -Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson, Clément -Camin, Bob Marteen +Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson + +Translations and edits by: https://github.com/mahnunchik, https://github.com/francescomalatesta, https://github.com/astralhpi, https://github.com/liangshan, https://github.com/orangain, https://github.com/Keirua, Clément Camin, Bob Marteen, https://github.com/dmathieu and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From 85c142091bbf9427544d1cd252649af2def74fbc Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Tue, 30 Jun 2015 13:45:30 +0100 Subject: [PATCH 157/472] fix fr translation --- locales/fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.yml b/locales/fr.yml index b00ac5da8..03ec78988 100644 --- a/locales/fr.yml +++ b/locales/fr.yml @@ -1,4 +1,4 @@ -en: +fr: # Name of language listed in locales menu language: "Français (fr)" From 23379d003408211c73e5568a307ead878cc33406 Mon Sep 17 00:00:00 2001 From: Damien Mathieu Date: Tue, 30 Jun 2015 15:50:56 +0200 Subject: [PATCH 158/472] add a space between the title and the traduction mention --- views/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/layout.erb b/views/layout.erb index b32ce02f6..b36f824a2 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -3,7 +3,7 @@ - The Twelve-Factor App<%= I18n.t(:translation) %> + The Twelve-Factor App <%= I18n.t(:translation) %> From 742b31acd7d0ea5efae07a3b07b39c806bac70be Mon Sep 17 00:00:00 2001 From: greenplace Date: Thu, 9 Jul 2015 13:31:38 +0300 Subject: [PATCH 159/472] Update intro.md --- content/ru/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/intro.md b/content/ru/intro.md index b3369285d..0fcb1d772 100644 --- a/content/ru/intro.md +++ b/content/ru/intro.md @@ -9,4 +9,4 @@ * **Сводят к минимуму расхождения** между средой разработки и средой выполнения, что позволяет использовать **непрерывное развертывание** (continuous deployment) для максимальной гибкости; * И могут **масштабироваться** без существенных изменений в инструментах, архитектуре и практике разработки. -Методология двенадцати факторов может быть применена для приложений, написанных на любом языке программирования, и которые используют любые комбинации сторонних служб (backing services) (базы данных, очереди сообщений, кэш-памяти, и т.д.). +Методология двенадцати факторов может быть применена для приложений, написанных на любом языке программирования и использующих любые комбинации сторонних служб (backing services) (базы данных, очереди сообщений, кэш-памяти, и т.д.). From f506875d8e49a17b057ead75c73969d8c3fd1e0d Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 15:38:55 +0300 Subject: [PATCH 160/472] 'subversion' better --- content/ru/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/codebase.md b/content/ru/codebase.md index e37e06dc7..7a46cd21e 100644 --- a/content/ru/codebase.md +++ b/content/ru/codebase.md @@ -3,7 +3,7 @@ Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* -*Кодовая база* -- это один репозиторий (в централизованных системах контроля версий, как Subvertion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системах контроля версий, как Git). +*Кодовая база* -- это один репозиторий (в централизованных системах контроля версий, как Subversion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системах контроля версий, как Git). ![Одна кодовая база -- множество развёртываний](/images/codebase-deploys.png) From 8dedbb139834bff21d3e964afb4ec0d6f9b688a9 Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 17:00:18 +0300 Subject: [PATCH 161/472] Update backing-services.md --- content/ru/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 4924fc974..21e544866 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -11,4 +11,4 @@ Рабочее развёртывание приложения, подключенного к 4 сторонним сервисам. -Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например, если база данных приложения функционирует некорректно из-за аппаратные проблемы, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. +Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например, если база данных приложения функционирует некорректно из-за аппаратных проблем, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. From b6986033eefca2baf4490ca596721789802bf681 Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 17:05:02 +0300 Subject: [PATCH 162/472] Update background.md --- content/ru/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/background.md b/content/ru/background.md index e7efaa4d1..5902fa949 100644 --- a/content/ru/background.md +++ b/content/ru/background.md @@ -3,6 +3,6 @@ Участники, внёсшие вклад в этот документ, были непосредственно вовлечены в разработку и развёртывание сотен приложений и косвенно были свидетелями разработки, выполнения и масштабирования сотен тысяч приложений во время нашей работы над платформой [Heroku](http://www.heroku.com/). -В этом документе обобщается весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделение особого внимания динамике органического роста приложения с течением времени, динамике сотрудничества разработчиков, работающих над кодовой базой приложения и [устранене последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +В этом документе обобщается весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделения особого внимания динамике органического роста приложения с течением времени, динамики сотрудничества разработчиков, работающих над кодовой базой приложения и [устранения последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). Наша мотивация заключается в повышении осведомлённости о некоторых системных проблемах, которые мы встретили в практике разработки современных приложений, а также для того, чтобы предоставить общие основные понятия для обсуждения этих проблем и предложить набор общих концептуальных решений этих проблем с сопутствующей терминологией. Формат навеян книгами Мартина Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* и *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 76ec9db018bf4441b7a61a5a3162fafe83b7d237 Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 17:08:45 +0300 Subject: [PATCH 163/472] Update processes.md --- content/ru/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/processes.md b/content/ru/processes.md index c45fc0035..6274dc21b 100644 --- a/content/ru/processes.md +++ b/content/ru/processes.md @@ -11,4 +11,4 @@ Упаковщики ресурсов (asset) (например, [Jammit](http://documentcloud.github.com/jammit/) или [django-compressor](http://django-compressor.readthedocs.org/)) используют файловую систему как кэш для скомпилированных ресурсов. Приложение двенадцати факторов предпочитает делать данную компиляцию во время [этапа сборки](./build-release-run), например, как в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не во время выполнения. -Некоторые веб-системы полагаются на ["липкие сессий"] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- то есть кэшируют данные пользовательских сессии в памяти процесса приложения и ожидают того, что последующие запросы того же пользователя будут перенаправлены к тому же процессу. Липкие сессии являются нарушением двенадцати факторов и их никогда не следует использовать или полагаться на них. Данные пользовательской сессии являются хорошими кандидатами для хранилища данных, которое предоставляет функцию ограничения времени хранения, например, [Memcached](http://memcached.org/) и [Redis](http://redis.io/). +Некоторые веб-системы полагаются на ["липкие сессии"] (http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- то есть кэшируют данные пользовательских сессии в памяти процесса приложения и ожидают того, что последующие запросы того же пользователя будут перенаправлены к тому же процессу. Липкие сессии являются нарушением двенадцати факторов и их никогда не следует использовать или полагаться на них. Данные пользовательской сессии являются хорошими кандидатами для хранилища данных, которое предоставляет функцию ограничения времени хранения, например, [Memcached](http://memcached.org/) и [Redis](http://redis.io/). From bacdeeaa8a8133140f2a1de3d7022119573166db Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 19:53:06 +0300 Subject: [PATCH 164/472] Update dev-prod-parity.md --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 7ea8880c7..2780f3895 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -71,6 +71,6 @@ **Разработчик приложения двенадцати факторов должен сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. -Установка локальных сервисов стала менее непреодолимой задачей, чем она когда то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению выгодой получаемой от паритета разработки/работы приложения и непрерывного развёртывания. +Установка локальных сервисов стала менее непреодолимой задачей, чем она когда то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. Адаптеры для различных сторонних сервисов по-прежнему полезны, потому что они позволяют портировать приложение для использования новых сторонних сервисов относительно безболезненно. Но все развёртывания приложения (окружение разработчика, промежуточное и рабочее развёртывание) должны использовать тот же тип и ту же версию каждого из сторонних сервисов. From a46d3acfbe6bc3661beb320f26bca3522d6e8002 Mon Sep 17 00:00:00 2001 From: inner-whisper Date: Fri, 10 Jul 2015 20:24:13 +0300 Subject: [PATCH 165/472] Update dev-prod-parity.md --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 2780f3895..cf9310bd4 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -71,6 +71,6 @@ **Разработчик приложения двенадцати факторов должен сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. -Установка локальных сервисов стала менее непреодолимой задачей, чем она когда то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. +Установка локальных сервисов стала менее непреодолимой задачей, чем она когда-то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. Адаптеры для различных сторонних сервисов по-прежнему полезны, потому что они позволяют портировать приложение для использования новых сторонних сервисов относительно безболезненно. Но все развёртывания приложения (окружение разработчика, промежуточное и рабочее развёртывание) должны использовать тот же тип и ту же версию каждого из сторонних сервисов. From b41d51bcb54db6bce685ef3f715ace1539246c9d Mon Sep 17 00:00:00 2001 From: Pavel Volyntsev Date: Fri, 17 Jul 2015 14:19:18 +0600 Subject: [PATCH 166/472] Fixed misprints --- content/ru/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md index 7a53f2dc3..a38e56e8e 100644 --- a/content/ru/admin-processes.md +++ b/content/ru/admin-processes.md @@ -1,7 +1,7 @@ ## XII. Задачи администрирования -### Выполнйте задачи администратрирования/управления с помошью разовых процессов +### Выполнйте задачи администрирования и управления с помощью разовых процессов -[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам переодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: +[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам периодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: * Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). * Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). From 0dfed924bb3cb30c510b60db2fa5b414db6a0221 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Sun, 3 May 2015 12:55:21 -0300 Subject: [PATCH 167/472] Translating dev/prod parity. Closes #32 --- content/pt_br/dev-prod-parity.md | 68 ++++++++++++++++---------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index f6e573342..b40bf31ae 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -1,60 +1,60 @@ -## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +## X. Paridade entre desenv/produção +### Mantenha o desenvolvimento, homologação e produção o mais similares possível -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvolvedor editando código num [deploy](./codebase) local do app) e produção (um deploy acessado pelos usuários finais). Essas lacunas se manifestam em três áreas: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. +* **A lacuna do tempo:** Um desenvolvedor pode trabalhar em código que demora dias, semanas ou até meses para ir para produção. +* **A lacuna de pessoal:** Desenvolvedores escrevem código, engenheiros de operação fazem o deploy dele. +* **A lacuna de ferramentas:** Desenvolvedores podem estar usando um conjunto como Nginx, SQLite, e OS X, enquanto o app em produção usa Apache, MySQL, e Linux. -**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: +**O App doze-fatores é projetado para [integração contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. +* Diminua a lacuna de tempo: um desenvolvedor pode escrever código e ter o deploy feito em horas ou até mesmo minutos depois. +* Diminua a lacuna de pessoal: desenvolvedores que escrevem código estão proximamente envolvidos em realizar o deploy e acompanhar seu comportamento em produção. +* Diminua a lacuna de ferramentas: mantenha desenvolvimento e produção o mais similares possível. -Summarizing the above into a table: +Resumindo o acima em uma tabela: - - + + - - - + + + - - - + + + - - - + + +
Traditional appTwelve-factor appApp tradicionalApp doze-fatores
Time between deploysWeeksHoursTempo entre deploysSemanasHoras
Code authors vs code deployersDifferent peopleSame peopleAutores de código vs deployersPessoas diferentesMesmas pessoas
Dev vs production environmentsDivergentAs similar as possibleAmbientes de desenv vs produçãoDivergenteO mais similar possível
-[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[Serviços de apoio](./backing-services), como o banco de dados do app, sistema de filas, ou cache, são uma área onde paridade entre desenv/produção é importante. Muitas linguagens oferecem diferentes bibliotecas que simplificam o acesso ao serviço de apoio, incluindo *adaptadores* para os diferentes tipos de serviços. Alguns exemplos na tabela abaixo. - - - - + + + + - + - + @@ -63,14 +63,14 @@ Summarizing the above into a table: - +
TypeLanguageLibraryAdaptersTipoLinguagemBibliotecaAdaptadores
DatabaseBanco de dados Ruby/Rails ActiveRecord MySQL, PostgreSQL, SQLite
QueueFila Python/Django Celery RabbitMQ, Beanstalkd, RedisCache Ruby/Rails ActiveSupport::CacheMemory, filesystem, MemcachedMemory, sistema de arquivos, Memcached
-Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. +Desenvolvedores as vezes vem uma grande vantagem em usar um serviço de apoio leve em seus ambientes, enquanto um serviço de apoio mais sério e robusto seria usado em produção. Por exemplo, usando SQLite localmente e PostgreSQL em produção; ou memória de processo local para caching em desenvolvimento e Memcached em produção. -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. +**O desenvolvedor doze-fatores resiste a tentação de usar diferentes serviços de apoio entre desenvolvimento e produção**, mesmo quando adaptadores teoricamente abstraem as diferenças dos serviços de apoio. Diferenças entre serviços de apoio significam que pequenas incompatibilidades aparecerão, causando código que funcionava e passava em desenvolvimento ou homologação, falhará em produção. Tais tipos de erros criam fricção que desincentivam deploy contínuo. O custo dessa fricção e do subsequente decaimento de deploy contínuo é extremamente alto quando considerado que vai acumular no tempo de vida da aplicação. -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. +Serviços locais leves são menos tentadores que já foram um dia. Serviços de apoio modernos tais como Memcached, PostgreSQL, e RabbitMQ não são difíceis de instalar e rodam graças a sistemas modernos de empacotamento tias como [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternativamente, ferramentas de provisionamento declarativo tais como [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/) combinado com ambientes virtuais leves como [Vagrant](http://vagrantup.com/) permitem desenvolvedores rodar ambientes locais que são bem próximos dos ambientes de produção. O custo de instalar e usar esses sistemas é baixo comparado ao benefício de ter a paridade entre desenv/produção e deploy contínuo. -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. +Adaptadores para diferentes serviços de apoio ainda são úteis, pois eles fazem a portabilidade para novos serviços de apoio relativamente tranquilas. Mas todos os deploys do app (ambientes de desenvolvimento, homologação, produção) devem usar o mesmo tipo e versão de cada serviço de apoio. From 8139b738011a0fe4d4ca7ce66c6d1c3622f99285 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Mon, 27 Jul 2015 11:44:13 -0300 Subject: [PATCH 168/472] Traduz LOGS. Closes #33 --- content/pt_br/logs.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/pt_br/logs.md b/content/pt_br/logs.md index ab2f4f829..37d95e2d1 100644 --- a/content/pt_br/logs.md +++ b/content/pt_br/logs.md @@ -1,16 +1,16 @@ ## XI. Logs -### Treat logs as event streams +### Trate logs como fluxos de eventos -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. +*Logs* provém visibilidade no comportamento de um app em execução. Em ambientes de servidor eles são comumente escritos num arquivo em disco (um "logfile"); mas este é apenas um formato de saída. -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +Logs são o [fluxo](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de eventos agregados e ordenados por tempo coletados dos fluxos de saída de todos os processos em execução e serviços de apoio. Logs na sua forma crua são tipicamente um formato de texto com um evento por linha (apesar que pilhas de exceção podem ocupar várias linhas). Logs não tem começos ou términos fixos, mas fluem continuamente enquanto o app estiver operante. -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +**Um app doze-fatores nunca se preocupa com o roteamento ou armazenagem do seu fluxo de saída.** Ele não deve tentar escrever ou gerir arquivos de logs. No lugar, cada processo em execução escreve seu próprio fluxo de evento, sem buffer, para o `stdout`. Durante o desenvolvimento local, o desenvolvedor verá este fluxo no plano de frente do seu terminal para observar o comportamento do app. -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. +Em deploys de homologação ou produção, cada fluxo dos processos serão capturados pelo ambiente de execução, colados com todos os demais fluxos do app, e direcionados para um ou mais destinos finais para visualização e arquivamento de longo prazo. Estes destinos de arquivamento não são visíveis ou configuráveis pelo app, e ao invés disso, são completamente geridos pelo ambiente de execução. Roteadores de log open source (tais como [Logplex](https://github.com/heroku/logplex) e [Fluent](https://github.com/fluent/fluentd)) estão disponíveis para este propósito. -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: +O fluxo de evento para um app pode ser direcionado para um arquivo, ou visto em tempo real via `tail` num terminal. Mais significativamente, o fluxo pode ser enviado para um sistema indexador e analisador tal como [Splunk](http://www.splunk.com/), ou um um sistema mais genérico de _data warehousing_ como o [Hadoop/Hive](http://hive.apache.org/). Estes sistemas permitem grande poder e flexibilidade para observar o comportamento de um app durante o tempo, incluindo: -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). +* Encontrando eventos específicos no passado. +* Gráficos em larga escala de tendências (como requisições por minuto) +* Notificações ativas de acordo com as heurísticas determinadas pelo usuário (como uma notificação quando a quantidade de erros por minuto exceder um certo limite). From be3a1e6028fa9ff3447c01a7c2663f25f184370b Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Wed, 11 Feb 2015 19:42:41 -0200 Subject: [PATCH 169/472] Translates build-release-run to pt-br. Closes #19 --- content/pt_br/build-release-run.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/content/pt_br/build-release-run.md b/content/pt_br/build-release-run.md index a7215b0a1..22c8402b6 100644 --- a/content/pt_br/build-release-run.md +++ b/content/pt_br/build-release-run.md @@ -1,19 +1,18 @@ -## V. Build, release, run -### Strictly separate build and run stages +## V. Construa, lance, execute +### Separe estritamente os estágios de construção e execução -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: +Uma [base de código](./codebase) é transformada num deploy (de não-desenvolvimento) através de três estágios: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. +* O *estágio de construção* é uma transformação que converte um repositório de código em um pacote executável conhecido como *construção*. Usando uma versão do código de um commit especificado pelo processo de desenvolvimento, o estágio de construção obtém e fornece [dependências](./dependencies) e compila binários e ativos. +* O *estágio de lançamento* pega a construção produzida pelo estágio de construção e a combina com a atual [configuração](./config) do deploy. O *lançamento* resultante contém tanto a construção quanto a configuração e está pronta para execução imediata no ambiente de execução. +* O *estágio de execução* roda o app no ambiente de execução, através do início de alguns dos [processos](./processes) do app com um determinado lançamento. -![Code becomes a build, which is combined with config to create a release.](/images/release.png) +![Código vira uma construção, que é combinada com a configuração para se criar um lançamento.](/images/release.png) -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. +**O app doze-fatores usa separação estrita entre os estágios de construção, lançamento e execução.** Por exemplo, é impossível alterar código em tempo de execução, já que não meios de se propagar tais mudanças de volta ao estágio de construção. -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. +Ferramentas para deploy tipicamente oferecem ferramentas de gestão de lançamento, mais notadamente a habilidade de se reverter à um lançamento prévio. Por exemplo, a ferramenta de deploy [Capistrano](https://github.com/capistrano/capistrano/wiki) armazena lançamentos em um subdiretório chamado `releases`, onde o lançamento atual é um link simbólico para o diretório da lançamento atual. Seu comando `rollback` torna fácil reverter para um lançamento prévio. -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. - -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. +Cada lançamento deve sempre ter um identificador de lançamento único, tal qual o timestamp do lançamento (como `2011-04-06-20:32:17`) ou um número incremental (como `v100`). Lançamentos são livro-razões onde apenas se acrescenta informações e um lançamento não pode ser alterada uma vez que é criada. Qualquer mudança deve gerar um novo lançamento. +Construções são iniciadas pelos desenvolvedores do app sempre que novos códigos entrem no deploy. A execução de um executável, todavia, pode acontecer automaticamente em casos como o reinício do servidor, ou um processo travado sendo reiniciado pelo gerenciador de processos. Assim, no estágio de execução deve haver quanto menos partes móveis quanto possível, já que problemas que previnem um app de rodar pode causá-lo a travar no meio da noite quando não há desenvolvedores por perto. O estágio de construção pode ser mais complexo, já que os erros estão sempre à vista do desenvolvedor que está cuidando do deploy. From ebe7d4b4539ae149747fb1fa655ce396b746841b Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Mon, 27 Jul 2015 12:48:16 -0300 Subject: [PATCH 170/472] Corrige palavra no TOC --- content/pt_br/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index 0f1026580..ce79b5c86 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -25,7 +25,7 @@ The Twelve Factors ## [VIII. Concorrência](./concurrency) ### Dimensione por um modelo de processo -## [IX. Disponibilidade](./disposability) +## [IX. Descartabilidade](./disposability) ### Maximizar a robustez com inicialização e desligamento rápido ## [X. Dev/prod semelhantes](./dev-prod-parity) From 41cdb8f86262e5477a8c1f93cd1d48ea7d0edb4b Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Mon, 27 Jul 2015 12:34:16 -0300 Subject: [PATCH 171/472] Traduz Disposability. Closes #31 --- content/pt_br/disposability.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/pt_br/disposability.md b/content/pt_br/disposability.md index 085f2d721..9df9a07da 100644 --- a/content/pt_br/disposability.md +++ b/content/pt_br/disposability.md @@ -1,14 +1,14 @@ -## IX. Disposability -### Maximize robustness with fast startup and graceful shutdown +## IX. Descartabilidade +### Maximize robustez com inicialização rápida e desligamento gracioso -**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. +**Os [processos](./processos) de um app doze-fatores são *descartáveis*, significando que podem ser iniciados ou parados a qualquer momento.** Isso facilita o escalonamento elástico, rápido deploy de [código](./codebase) ou mudanças de [configuração](./config), e robustez de deploys de produção. -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. +Processos devem empenhar-se em **minizar o tempo de inicialização**. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de [release](./build-release-run) e de escalonamento; e ele adiciona robustez, pois o o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário. -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. +Processos **desligam-se graciosamente quando recebem um sinal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** do seu gestor de processos. Para um processo web, desligamento gracioso é alcançado quando cessa de escutar à porta de serviço (consequentemente recusando quaisquer requisições novas), permitindo qualquer requisição em andamento terminar, e então desligando. Implícito neste modelo é que as requisições HTTP são curtas (não mais que alguns poucos segundos), ou no caso de um longo _polling_, o cliente deve ser capaz de transparentemente tentar se reconectar quando a conexão for perdida. -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](http://kr.github.com/beanstalkd/), 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). +Para um processo de trabalho (worker), desligamento gracioso é alcançado retornando a tarefa atual para fila de trabalho. Por exemplo, no [RabbitMQ](http://www.rabbitmq.com/) o trabalhador pode enviar um [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); no [Beanstalkd](http://kr.github.com/beanstalkd/), a tarefa é retornada para a fila automaticamente sempre que um trabalhador se desconecta. Sistemas baseados em trava como o [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) precisam se certificar de soltar a trava no registro da tarefa. Implícito neste modelo é que todas as tarefas são [reentrantes](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), o que tipicamente é atingindo envolvendo os resultados numa transação, ou tornando a operação [idempotente](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). +Processos também devem ser **robustos contra morte súbida**, no caso de uma falha de hardware. Ao passo que isso é muito menos comum que um desligamento via `SIGTERM`, isso ainda pode acontecer. Uma abordagem recomendada é usar um backend de filas robusto, como o Beanstalkd, que retorna tarefas à fila quando clientes desconectam ou esgotam o tempo de resposta. De qualquer forma, um app doze-fatores é arquitetado para lidar com terminações não esperadas e não graciosas. [Crash-only design](http://lwn.net/Articles/191059/) leva este conceito à sua [conclusão lógica](http://docs.couchdb.org/en/latest/intro/overview.html). From 3abf0461f1cd883c5545fe305a7314198097b057 Mon Sep 17 00:00:00 2001 From: George Moura Date: Mon, 27 Jul 2015 14:18:54 -0300 Subject: [PATCH 172/472] add title --- content/pt_br/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 870a56096..aecfbd301 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -1,5 +1,5 @@ -## XII. Admin processes -### Run admin/management tasks as one-off processes +## XII. Processsos de admin +### Rode tarefas de administração/gestão como processos pontuais 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: From 4e7732029c2292ef733095692f6a5801dd9064a2 Mon Sep 17 00:00:00 2001 From: George Moura Date: Mon, 27 Jul 2015 14:44:29 -0300 Subject: [PATCH 173/472] add p1 e p2 --- content/pt_br/admin-processes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index aecfbd301..b443bf247 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -1,8 +1,14 @@ ## XII. Processsos de admin ### Rode tarefas de administração/gestão como processos pontuais +O [processo de formação](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app (tais como manipulação de requisições web) como ela é executada. Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: + 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: +* Executando database migrations (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). +* Executando um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbritário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). +* Executando uma vez, scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). + * 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`). From f363b74ad3e29c9038d647e7defde8d389d80b6c Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Tue, 28 Jul 2015 15:59:08 -0300 Subject: [PATCH 174/472] Traduz twelve-factor para doze-fatores --- content/pt_br/concurrency.md | 8 ++++---- content/pt_br/config.md | 6 +++--- content/pt_br/dependencies.md | 7 +++---- content/pt_br/processes.md | 8 ++++---- content/pt_br/toc.md | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index e89efcc66..2e4a33492 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -5,10 +5,10 @@ Qualquer programa de computador, uma vez executado, está representado por um ou ![Escala é expressado como processos em execução, a diversidade da carga de trabalho é expressada como tipos de processo.](/images/process-types.png) -**Na aplicação twelve-factor, processos são cidadãos de primeira classe.** Processos na aplicação twelve-factor tomam fortes sinais do [modelo de processo unix para a execução de serviços daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. +**Na aplicação doze-fatores, processos são cidadãos de primeira classe.** Processos na aplicação doze-fatores, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. -Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. +Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. -O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação twelve-factor](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. +O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação doze-fatores](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. -Processos de uma app twelve-factor [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário. +Processos de uma app doze-fatores [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário. diff --git a/content/pt_br/config.md b/content/pt_br/config.md index 4dece4261..f2d18eb7e 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -7,7 +7,7 @@ A *configuração* de uma aplicação é tudo o que é provável variar entre [d * Credenciais para serviços externos como Amazon S3 ou Twitter * Valores por deploy como o nome canônico do host para o deploy -Aplicações as vezes armazenam as configurações no código como constantes. Isto é uma violação do twelve-factor, o que exige uma **estrita separação da configuração a partir do código**. Configuração varia substancialmente entre deploys, código não. +Aplicações as vezes armazenam as configurações no código como constantes. Isto é uma violação do doze-fatores, o que exige uma **estrita separação da configuração a partir do código**. Configuração varia substancialmente entre deploys, código não. A prova de fogo para saber se uma aplicação tem todas as configurações corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. @@ -15,8 +15,8 @@ Note que esta definição de "configuração" **não** inclui configuração int Outra abordagem para configuração é o uso de arquivos de configuração que não são versionados no controle de versão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são versionadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. -**A aplicação twelve-factor armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código. ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. +**A aplicação doze-fatores armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código. ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. -Em uma aplicação twelve-factor, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. +Em uma aplicação doze-fatores, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 9fd02afd2..4389df426 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -3,10 +3,9 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistemas de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou com escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). -**Uma aplicação twelve-factor nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. - -Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer twelve-factor. +**Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. +Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. -Aplicações Twelve-factor também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. +Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index b05eaf8b5..10c811a7d 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -5,11 +5,11 @@ A aplicação é executada em um ambiente de execução como um ou mais *process No caso mais simples, o código é um script autônomo, o ambiente de execução é o laptop local de um desenvolvedor com o runtime da linguagem instalado, e o processo é iniciado pela linha de comando (por exemplo, `python my_script`). Na outra extremidade do espectro, o deploy em produção de uma aplicação sofisticada pode utilizar vários [tipos de processos, instanciado em zero ou mais processos em andamento](./concurrency). -**Processos twelve-factor são stateless(não armazenam estado) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Quaisquer dados que precise persistir deve ser armazenado em um serviço de apoio stateful(que armazena o seu estado), tipicamente uma base de dados. +**Processos doze-fatores são stateless(não armazenam estado) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Quaisquer dados que precise persistir deve ser armazenado em um serviço de apoio stateful(que armazena o seu estado), tipicamente uma base de dados. -O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transação única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação twelve-factor nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em uma futura solicitação ou job -- com muitos processos de cada tipo rodando, as chances são altas de que uma futura solicitação será servida por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). +O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transação única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação doze-fatores nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em uma futura solicitação ou job -- com muitos processos de cada tipo rodando, as chances são altas de que uma futura solicitação será servida por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). -Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação twelve-factor prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. +Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação doze-fatores prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. -Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do twelve-factor e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). +Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index ce79b5c86..cffee5bc7 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -1,5 +1,5 @@ -The Twelve Factors -================== +Os Doze Fatores +=============== ## [I. Base de Código](./codebase) ### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys From edd811fa30658d2e27691d474e30b0b6d89d3263 Mon Sep 17 00:00:00 2001 From: George Moura Date: Tue, 28 Jul 2015 16:47:56 -0300 Subject: [PATCH 175/472] fix some words and add p3, p4 and p5 --- content/pt_br/admin-processes.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index b443bf247..50f22e68c 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -1,20 +1,14 @@ -## XII. Processsos de admin +## XII. Processos de administração ### Rode tarefas de administração/gestão como processos pontuais -O [processo de formação](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app (tais como manipulação de requisições web) como ela é executada. Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: +O [processo de formação](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app como ela é executada (tais como manipulação de requisições web). Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: -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: +* Executando migrações de base de dados (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). +* Executando um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbitrário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). +* Executando uma vez os scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). -* Executando database migrations (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). -* Executando um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbritário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). -* Executando uma vez, scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). +Processos de administração pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam contra uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado contra essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. -* 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`). +A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. -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. +Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL fora da caixa, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From d8afda660f91dcaef4bbaa568fbab543669edb81 Mon Sep 17 00:00:00 2001 From: George Moura Date: Tue, 28 Jul 2015 17:15:13 -0300 Subject: [PATCH 176/472] remove 'fora da caixa' to 'embutido' --- content/pt_br/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 50f22e68c..355168a0c 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -11,4 +11,4 @@ Processos de administração pontuais devem ser executados em um ambiente idênt A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. -Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL fora da caixa, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. +Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL embutidos, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From 7f7f0162a4edde84926467ada5559825960370f6 Mon Sep 17 00:00:00 2001 From: George Moura Date: Tue, 28 Jul 2015 17:18:44 -0300 Subject: [PATCH 177/472] @lfilho feito, removido o contra --- content/pt_br/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 355168a0c..8e604add9 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -7,7 +7,7 @@ O [processo de formação](./concurrency) é o conjunto de processos que são us * Executando um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbitrário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). * Executando uma vez os scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). -Processos de administração pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam contra uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado contra essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. +Processos de administração pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado com essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. From bb0a8e381756e0eb39494ad37141c477a90cb15f Mon Sep 17 00:00:00 2001 From: George Moura Date: Tue, 28 Jul 2015 17:20:22 -0300 Subject: [PATCH 178/472] feito, sorry! --- content/pt_br/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 8e604add9..4924ffd2d 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -11,4 +11,4 @@ Processos de administração pontuais devem ser executados em um ambiente idênt A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. -Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL embutidos, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. +Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From 172e57e9c131f286fcdc26ed0e690e4478bf1846 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Tue, 28 Jul 2015 17:43:54 -0300 Subject: [PATCH 179/472] Add portuguesse translators --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index e77ea5f58..a4116eb4d 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: https://github.com/mahnunchik, https://github.com/francescomalatesta, https://github.com/astralhpi, https://github.com/liangshan, https://github.com/orangain, https://github.com/Keirua, Clément Camin, Bob Marteen, https://github.com/dmathieu and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: https://github.com/mahnunchik, https://github.com/francescomalatesta, https://github.com/astralhpi, https://github.com/liangshan, https://github.com/orangain, https://github.com/Keirua, Clément Camin, Bob Marteen, https://github.com/dmathieu, https://github.com/fernandes, https://github.com/gwmoura, https://github.com/lfilho and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From 1ec1d77311408f09dd66631bdd20e6fb210e2f28 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Tue, 28 Jul 2015 17:51:33 -0300 Subject: [PATCH 180/472] Update links from upstream --- content/pt_br/config.md | 2 +- content/pt_br/processes.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index f2d18eb7e..2b4f861b9 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -19,4 +19,4 @@ Outra abordagem para configuração é o uso de arquivos de configuração que n Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. -Em uma aplicação doze-fatores, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independente de cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. +Em uma aplicação doze-fatores, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independentemente para cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index 10c811a7d..bdedceb0b 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -9,7 +9,7 @@ No caso mais simples, o código é um script autônomo, o ambiente de execução O espaço de memória ou sistema de arquivos do processo pode ser usado como um breve, cache de transação única. Por exemplo, o download de um arquivo grande, operando sobre ele, e armazenando os resultados da operação no banco de dados. A aplicação doze-fatores nunca assume que qualquer coisa cacheada na memória ou no disco estará disponível em uma futura solicitação ou job -- com muitos processos de cada tipo rodando, as chances são altas de que uma futura solicitação será servida por um processo diferente. Mesmo quando rodando em apenas um processo, um restart (desencadeado pelo deploy de um código, mudança de configuração, ou o ambiente de execução realocando o processo para uma localização física diferente) geralmente vai acabar com todo o estado local (por exemplo, memória e sistema de arquivos). -Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-assetpackager](http://code.google.com/p/django-assetpackager/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação doze-fatores prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html), do que em tempo de execução. +Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação doze-fatores prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), do que em tempo de execução. Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). From 5afb1925dae80bdb1448373fc5f6fd36647a9da0 Mon Sep 17 00:00:00 2001 From: Luiz Gonzaga dos Santos Filho Date: Tue, 28 Jul 2015 18:10:08 -0300 Subject: [PATCH 181/472] Link translators and editors --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index a4116eb4d..0086d72e6 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: https://github.com/mahnunchik, https://github.com/francescomalatesta, https://github.com/astralhpi, https://github.com/liangshan, https://github.com/orangain, https://github.com/Keirua, Clément Camin, Bob Marteen, https://github.com/dmathieu, https://github.com/fernandes, https://github.com/gwmoura, https://github.com/lfilho and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho) and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From f4dd53e5cd6545a81447aca491d799acd469cd1a Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 3 Aug 2015 14:32:26 +0100 Subject: [PATCH 182/472] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index a4116eb4d..0f5cbb7df 100644 --- a/Readme.md +++ b/Readme.md @@ -13,7 +13,7 @@ Development Production deploy ----------------- - heroku create -s cedar + heroku create git push heroku master heroku open From 77f38da3db3e6c33e77fa4ae11adc9e6cf40a31e Mon Sep 17 00:00:00 2001 From: Jean-Michel Feurprier Date: Tue, 11 Aug 2015 12:24:36 -0400 Subject: [PATCH 183/472] Fixed typos --- content/fr/intro.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/fr/intro.md b/content/fr/intro.md index 97ee31241..895c0b721 100644 --- a/content/fr/intro.md +++ b/content/fr/intro.md @@ -1,12 +1,12 @@ Introduction ============ -A l'époque actuelle, les logiciels sont régulièrement délivrés en tant que services : on les appelles 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 : +A 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 adapaté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 continue* pour une agilité maximum; -* et peuvent **grossir verticalement** sans changements significatifs dans les outils, l'architecture ou les pratiques de développement; +* 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ée, file, cache mémoire, etc.) +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.) From e145719415d5ac3c3f8729e9f4453dda493cccd2 Mon Sep 17 00:00:00 2001 From: Jean-Michel Feurprier Date: Tue, 11 Aug 2015 12:29:22 -0400 Subject: [PATCH 184/472] Fixed typos in codebase.md --- content/fr/codebase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/fr/codebase.md b/content/fr/codebase.md index 67842e1e8..14bfabe04 100644 --- a/content/fr/codebase.md +++ b/content/fr/codebase.md @@ -1,7 +1,7 @@ ## I. Base de code ### Une base de code suivie avec un système de contrôle de version, plusieurs déploiements -Une application 12 facteurs est toujours suivie dans un système de contrôle de version, tel que [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Une copie de la base de donnée de suivi des révisions est appelée *dépôt de code*, souvent raccourci en *dépôt*. Le terme anglais *code repository*, raccourci en *repository* et *repo* est également utilisé. +Une application 12 facteurs est toujours suivie dans un système de contrôle de version, tel que [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Une copie de la base de données de suivi des révisions est appelée *dépôt de code*, souvent raccourci en *dépôt*. Le terme anglais *code repository*, raccourci en *repository* et *repo* est également utilisé. Une *base de code* correspond à chaque dépôt (dans un système de contrôle de version centralisé tel que Subversion), ou tout ensemble de dépôts qui partage un commit racine (dans un système de contrôle de version décentralisé comme Git). @@ -10,9 +10,9 @@ Une *base de code* correspond à chaque dépôt (dans un système de contrôle d Il y a toujours un rapport direct entre la base de code et l'application : * S'il y a plusieurs bases de code, ce n'est pas une application, c'est un système distribué. Chaque composant du système distribué est une application, et chacun peut individuellement respecter la méthodologie 12 facteurs. -* Plusieurs applications qui partagent le même code est une violation des 12 facteurs. La solution dans ce cas est de factoriser le code partagé dans des librairies qui peuvent être intégrées via un [gestionnaire de dépendances](./dependencies). +* Plusieurs applications partageant le même code est une violation des 12 facteurs. La solution dans ce cas est de factoriser le code partagé dans des librairies qui peuvent être intégrées via un [gestionnaire de dépendances](./dependencies). Il y a seulement une base de code par application, mais il y aura plusieurs déploiements de l'application. Un *déploiement* est une instance en fonctionnement de l'application. C'est, par exemple, le site en production, ou bien un ou plusieurs sites de validation. En plus de cela, chaque développeur a une copie de l'application qui fonctionne dans son environnement local de développement, ce qui compte également comme un déploiement. -La base de code est la même à travers tous les déploiements, bien que différentes versions puisse être actives dans chaque déploiement. Par exemple, un développeur a des commits qui ne sont pas encore déployés dans l'environnement de validation. L'environnement de validation a des commits qui ne sont pas encore déployés en production. Par contre, ils partagent tous la même base de code, ce qui les identifie comme étant des déploiements différents d'une même application. +La base de code est la même à travers tous les déploiements, bien que différentes versions puissent être actives dans chaque déploiement. Par exemple, un développeur a des commits qui ne sont pas encore déployés dans l'environnement de validation. L'environnement de validation a des commits qui ne sont pas encore déployés en production. Par contre, ils partagent tous la même base de code, ce qui les identifie comme étant des déploiements différents d'une même application. From 7a95aa36f44cc22cf3dbc996221a2d4c21e74c9e Mon Sep 17 00:00:00 2001 From: Jean-Michel Feurprier Date: Wed, 12 Aug 2015 10:21:18 -0400 Subject: [PATCH 185/472] fixed typos --- content/fr/processes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/fr/processes.md b/content/fr/processes.md index cd7a0c78d..8ef21409f 100644 --- a/content/fr/processes.md +++ b/content/fr/processes.md @@ -3,14 +3,14 @@ L'application est exécutée dans l'environnement d'exécution comme un ou plusieurs *processus*. -Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiqué peut utiliser plusieurs [types de processus, instanciés dans 0 ou plus processus en fonctionnement](./concurrency). +Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiquée peut utiliser plusieurs [types de processus, instanciés dans 0 ou plus processus en fonctionnement](./concurrency). **Les processus 12 facteurs sont sans état et ne partagent [rien (en)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. -L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de donnes. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est à dire en mémoire et sur le disque). +L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de donnes. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est-à-dire en mémoire et sur le disque). Des outils de création de paquets de ressources (ou "asset packagers") (tel que [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) utilisent le système de fichier comme cache pour les ressources compilées. Une application 12 facteurs préfère faire cette compilation durant l'[étape d'assemblage](./build-release-run), comme avec le [pipeline des ressources de Rails](http://guides.rubyonrails.org/asset_pipeline.html), plutôt que durant l'exécution. -Certains systèmes web s'appuient sur des ["sessions persistantes" (en)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- c'est à dire, mettre en cache les données de session utilisateur dans le processus de l'application et attendre que les requêtes futures du même visiteur seront routées dans le même process. Les sessions persistantes sont une violation des 12 facteurs, qu'il ne faudrait jamais utiliser. +Certains systèmes web s'appuient sur des ["sessions persistantes" (en)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- c'est-à-dire, mettre en cache les données de session utilisateur dans le processus de l'application et attendre que les requêtes futures du même visiteur seront routées dans le même processus. Les sessions persistantes sont une violation des 12 facteurs, qu'il ne faudrait jamais utiliser. Les états de session sont de bons candidats pour un datastore qui offre des dates d'expiration, comme [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). From ef1186cfeebacccdd93c0d94ae05244b2cd481ed Mon Sep 17 00:00:00 2001 From: Pavel Karateev Date: Tue, 25 Aug 2015 17:43:08 +0300 Subject: [PATCH 186/472] Typos (Ru) --- content/ru/admin-processes.md | 4 ++-- content/ru/backing-services.md | 2 +- content/ru/build-release-run.md | 2 +- content/ru/codebase.md | 2 +- content/ru/concurrency.md | 6 +++--- content/ru/config.md | 6 +++--- content/ru/dev-prod-parity.md | 4 ++-- content/ru/disposability.md | 4 ++-- content/ru/toc.md | 6 +++--- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md index 7a53f2dc3..a9326747b 100644 --- a/content/ru/admin-processes.md +++ b/content/ru/admin-processes.md @@ -1,7 +1,7 @@ ## XII. Задачи администрирования -### Выполнйте задачи администратрирования/управления с помошью разовых процессов +### Выполняйте задачи администрирования/управления с помощью разовых процессов -[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам переодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: +[Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам периодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: * Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). * Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 21e544866..19341fa74 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -3,7 +3,7 @@ *Сторонняя служба*-- это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Например, хранилища данных (например, [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например, [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например, [Postfix](http://www.postfix.org/)) и кэширующие системы (например, [Memcached](http://memcached.org/)). -Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (напрмер [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). +Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (например, [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). **Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развертывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. diff --git a/content/ru/build-release-run.md b/content/ru/build-release-run.md index dace1677a..0bdfd2de7 100644 --- a/content/ru/build-release-run.md +++ b/content/ru/build-release-run.md @@ -3,7 +3,7 @@ [Кодовая база](./codebase) трансформируется в развёртывание (не учитывая развёртывание для разработки) за три этапа: -* *Этап сборки* -- это трансформация, которая преобразует репозиторий кода в исполняемый пакет, называемый *сборка*. Используя версию кода по указанному процессом развёртывания комиту, этап сборки загружает сторонние [зависимости](./dependencies) и компилирует двоичные файлы и ресурсы (assets). +* *Этап сборки* -- это трансформация, которая преобразует репозиторий кода в исполняемый пакет, называемый *сборка*. Используя версию кода по указанному процессом развёртывания коммиту, этап сборки загружает сторонние [зависимости](./dependencies) и компилирует двоичные файлы и ресурсы (assets). * *Этап релиза* принимает сборку, полученную на этапе сборки, и объединяет её с текущей [конфигурацией](./config) развёртывания. Полученный *релиз* содержит сборку и конфигурацию и готов к немедленному запуску в среде выполнения. * *Этап выполнения* (также известный как "runtime") запускает приложение в среде выполнения путём запуска некоторого набора [процессов](./processes) приложения из определённого релиза. diff --git a/content/ru/codebase.md b/content/ru/codebase.md index 7a46cd21e..439820d8a 100644 --- a/content/ru/codebase.md +++ b/content/ru/codebase.md @@ -12,6 +12,6 @@ * Если есть несколько кодовых баз, то это не приложение — это распределенная система. Каждый компонент в распределенной системе является приложением и каждый компонент может индивидуально соответствовать двенадцати факторам. * Факт того, что несколько приложений совместно используют тот же самый код, является нарушением двенадцати факторов. Решением в данной ситуации является выделение общего кода в библиотеки, которые могут быть подключены через [менеджер зависимостей](./dependencies). -Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того каждый разработчик имеет копию приложения, запущеного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). +Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того каждый разработчик имеет копию приложения, запущенного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). Кодовая база обязана быть единой для всех развёртываний, однако разные версии одной кодовой базы могут выполняться в каждом из развертываний. Например разработчик может иметь некоторые изменения которые еще не добавлены в промежуточное развёртывание; промежуточное развёртывание может иметь некоторые изменения, которые еще не добавлены в рабочее развёртывание. Однако, все эти развёртывания используют одну и ту же кодовую базу, таким образом можно их идентифицировать как разные развертывания одного и того же приложения. diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index abd11488b..3a6dd88ac 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Параллелизм -### Масштабируйте приложение с помошью процессов +### Масштабируйте приложение с помощью процессов Любая компьютерная программа после запуска представляет собой один или несколько работающих процессов. Исторически веб-приложения принимали различные формы выполнения процессов. К примеру, PHP-процессы выполнятся как дочерние процессы Apache и запускаются по требованию в необходимом для обслуживания поступивших запросов количестве. Java-процессы используют противоположный подход, JVM представляет собой один монолитный мета-процесс, который резервирует большой объем системных ресурсов (процессор и память) при запуске и управляет параллельностью внутри себя с помощью нитей исполнения (threads). В обоих случаях запущенные процессы лишь минимально видны для разработчика приложения. ![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) -**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. +**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. -Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутсвие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. +Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого они должны полагаться на менеджер процессов операционной системы (например, [Upstart](http://upstart.ubuntu.com/), распределенный менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. diff --git a/content/ru/config.md b/content/ru/config.md index 17048d617..2a413ad94 100644 --- a/content/ru/config.md +++ b/content/ru/config.md @@ -13,10 +13,10 @@ Обратите внимание, что это определение "конфигурации" **не** включает внутренние конфигурации приложения, например такие как '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. Это огромное улучшение перед использованием констант, которые сохраняются в коде, но по-прежнему и у этого метода есть недостатки: легко по ошибке сохранить конфигурационный файл в репозиторий; существует тенденция когда конфигурационные файлы разбросаны в разных местах и в разных форматах, из за этого становится трудно просматривать и управлять всеми настройками в одном месте. Кроме того форматы этих файлов, как правило, специфичны для конкретного языка или фрэймворка. +Другим подходом к конфигурации является использование конфигурационных файлов, которые не сохраняются в систему контроля версия, например 'config/database.yml' в Rails. Это огромное улучшение перед использованием констант, которые сохраняются в коде, но по-прежнему и у этого метода есть недостатки: легко по ошибке сохранить конфигурационный файл в репозиторий; существует тенденция когда конфигурационные файлы разбросаны в разных местах и в разных форматах, из за этого становится трудно просматривать и управлять всеми настройками в одном месте. Кроме того форматы этих файлов, как правило, специфичны для конкретного языка или фреймворка. -**Приложение двенадцати факторов хранит конфигурацию в *переменных окружения*** (часто сокращается до *env vars* или *env*). Переменные окружения легко изменить между развертываниями, не изменяя код; в отличие от файлов конфигурации, менее вероятно случайно сохранить их в репозитоий кода; и в отличие от пользовательских конфигурационных файлов или других механизмов конфигурации, таких как Java System Properties, они являются независимым от языка и операционной системы стандартом. +**Приложение двенадцати факторов хранит конфигурацию в *переменных окружения*** (часто сокращается до *env vars* или *env*). Переменные окружения легко изменить между развертываниями, не изменяя код; в отличие от файлов конфигурации, менее вероятно случайно сохранить их в репозиторий кода; и в отличие от пользовательских конфигурационных файлов или других механизмов конфигурации, таких как Java System Properties, они являются независимым от языка и операционной системы стандартом. -Другим подходом к управлению конфигурациями является группировка. Иногда приложения группируют конфигурации в именованные группы (часто называемые "окружениями") названые по названию конкретного развертывания, например как `development`, `test` и `production` окружения в Rails. Этот метод не является достаточно масштабируемым: чем больше различных развертываий приложения создается, тем больше новых имён окружений необходимо, например `staging` и `qa`. При дальнейшем росте проекта, разработчики могут добавлять свои собственные специальные окружения, такие как `joes-staging`, в результате происходит комбинаторный взрыв конфигураций, который делает управление развертываниями приложения очень хрупким. +Другим подходом к управлению конфигурациями является группировка. Иногда приложения группируют конфигурации в именованные группы (часто называемые "окружениями") названые по названию конкретного развертывания, например как `development`, `test` и `production` окружения в Rails. Этот метод не является достаточно масштабируемым: чем больше различных развертываний приложения создается, тем больше новых имён окружений необходимо, например `staging` и `qa`. При дальнейшем росте проекта, разработчики могут добавлять свои собственные специальные окружения, такие как `joes-staging`, в результате происходит комбинаторный взрыв конфигураций, который делает управление развертываниями приложения очень хрупким. В приложении двенадцати факторов переменные окружения являются не связанными между собой средствами управления, где каждая переменная окружения полностью независима от других. Они никогда не группируются вместе в "окружения", а вместо этого управляются независимо для каждого развертывания. Эта модель которая масштабируется постепенно вместе с естественным появлением большего количества развёртываний приложения за время его жизни. diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index cf9310bd4..fdd594f03 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -67,10 +67,10 @@ -Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьезные и надежные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кеширования при разработке и Memcached в рабочем окружении. +Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьезные и надежные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кэширования при разработке и Memcached в рабочем окружении. **Разработчик приложения двенадцати факторов должен сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. -Установка локальных сервисов стала менее непреодолимой задачей, чем она когда-то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, тиким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. +Установка локальных сервисов стала менее непреодолимой задачей, чем она когда-то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, таким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. Адаптеры для различных сторонних сервисов по-прежнему полезны, потому что они позволяют портировать приложение для использования новых сторонних сервисов относительно безболезненно. Но все развёртывания приложения (окружение разработчика, промежуточное и рабочее развёртывание) должны использовать тот же тип и ту же версию каждого из сторонних сервисов. diff --git a/content/ru/disposability.md b/content/ru/disposability.md index ebf82d80d..80af68412 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -1,7 +1,7 @@ ## IX. Утилизируемость (Disposability) -### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы +### Максимизируйте надежность с помощью быстрого запуска и корректного завершение работы -**[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановилены любой в момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. +**[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановлены в любой момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. Процессы должны стараться **минимизировать время запуска**. В идеале процесс должен затратить всего несколько секунд от момента времени, когда выполнена команда запуска, и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет большую гибкость для [релиза](./build-release-run) и масштабирования. Кроме того, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. diff --git a/content/ru/toc.md b/content/ru/toc.md index 752433217..f0eef2db8 100644 --- a/content/ru/toc.md +++ b/content/ru/toc.md @@ -23,10 +23,10 @@ ### Экспортируйте сервисы через привязку портов ## [VIII. Параллелизм](./concurrency) -### Масштабируйте приложение с помошью процессов +### Масштабируйте приложение с помощью процессов ## [IX. Утилизируемость (Disposability)](./disposability) -### Максимизируйте надежность с помошью быстрого запуска и корректного завершение работы +### Максимизируйте надежность с помощью быстрого запуска и корректного завершение работы ## [X. Паритет разработки/работы приложения](./dev-prod-parity) ### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими @@ -35,4 +35,4 @@ ### Рассматривайте журнал как поток событий ## [XII. Задачи администрирования](./admin-processes) -### Выполнйте задачи администратрирования/управления с помошью разовых процессов +### Выполняйте задачи администрирования/управления с помощью разовых процессов From ab5824227c9131e92747dcd375989dd4ab08adf7 Mon Sep 17 00:00:00 2001 From: Alex Wochna Date: Wed, 26 Aug 2015 13:30:00 -0700 Subject: [PATCH 187/472] Change text colors to ensure a contrast ratio of over 7 to meet WCAG 2.0 AAA requirements for accessibility. --- public/css/screen.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/css/screen.css b/public/css/screen.css index a86d871c0..0fcc2431e 100644 --- a/public/css/screen.css +++ b/public/css/screen.css @@ -89,7 +89,7 @@ section.concrete h2 a:hover { color: #337; } section.concrete h3 { - color: #555; + color: #333; font-weight: normal; } @@ -100,7 +100,7 @@ section#factor h2 { section#factor h3 { font-size: 17pt; font-weight: normal; - color: #999; + color: #555; margin-bottom: 16pt; } @@ -144,7 +144,7 @@ td, th { } footer { - color: #444; + color: #999; font-size: 10pt; background: #000; padding-top: 24pt; @@ -155,7 +155,7 @@ footer { } footer a { - color: #444; + color: #999; } article img { From 72541c3f38775f4ebeb25304ffa26d3a5ef7b05c Mon Sep 17 00:00:00 2001 From: Dyego Cantu Date: Thu, 1 Oct 2015 21:20:10 -0300 Subject: [PATCH 188/472] ideais --- content/pt_br/background.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/background.md b/content/pt_br/background.md index 7591723a2..0b6d12bdc 100644 --- a/content/pt_br/background.md +++ b/content/pt_br/background.md @@ -3,6 +3,6 @@ Experiência Os contribuidores deste documento estão diretamente envolvidos no desenvolvimento e implantação de centenas de aplicações, e indiretamente testemunhando o desenvolvimento, operação e escalada de centenas de milhares de aplicações através de seu trabalho na plataforma [Heroku](http://www.heroku.com/). -Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangulação de práticas ideias ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) +Este documento sintetiza toda nossa experiência e observação em uma variedade de aplicações que operam como software-como-serviço. Isto é a triangulação de práticas ideais ao desenvolvimento de software, com uma atenção particular a respeito das dinâmicas de crescimento orgânico de uma aplicação ao longo do tempo, a dinâmica de colaboração entre desenvolvedores trabalhando em uma base de código, e evitando os [custos de erosão de software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) -Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatorando](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file +Nossa motivação é aumentar a consciência de alguns problemas sistêmicos que temos visto no desenvolvimento de aplicações modernas, prover um vocabulário comum para discussão destes, e oferecer um amplo conjunto de soluções conceituais para esses problemas com a terminologia que os acompanha. O formato é inspirado nos livros de Martin Fowler *[Padrões de Arquitetura de Aplicações Enterprise](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refatorando](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 6dcaaf8cdfe309c79694aec8ffbf46b3d0bf953c Mon Sep 17 00:00:00 2001 From: Dyego Cantu Date: Thu, 1 Oct 2015 21:38:10 -0300 Subject: [PATCH 189/472] sistema --- content/pt_br/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 4389df426..1f176a35a 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -1,7 +1,7 @@ ## II. Dependências ### Declare e isole explicitamente as dependências -A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistemas de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou com escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). +A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o [CPAN](http://www.cpan.org/) para Perl ou [Rubygems](http://rubygems.org/) para Ruby. Bibliotecas instaladas por meio de um sistema de pacotes podem ser instaladas em todo o sistema (conhecidas como "site packages") ou com escopo dentro do diretório contendo a aplicação (conhecidas como "vendoring" ou "building"). **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. From 82d66050b968eedb3613597787523b739fd4ea1f Mon Sep 17 00:00:00 2001 From: Dyego Cantu Date: Fri, 2 Oct 2015 00:57:25 -0300 Subject: [PATCH 190/472] =?UTF-8?q?implanta=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index b40bf31ae..b009f76d6 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -7,7 +7,7 @@ Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvol * **A lacuna de pessoal:** Desenvolvedores escrevem código, engenheiros de operação fazem o deploy dele. * **A lacuna de ferramentas:** Desenvolvedores podem estar usando um conjunto como Nginx, SQLite, e OS X, enquanto o app em produção usa Apache, MySQL, e Linux. -**O App doze-fatores é projetado para [integração contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: +**O App doze-fatores é projetado para [implatação contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: * Diminua a lacuna de tempo: um desenvolvedor pode escrever código e ter o deploy feito em horas ou até mesmo minutos depois. * Diminua a lacuna de pessoal: desenvolvedores que escrevem código estão proximamente envolvidos em realizar o deploy e acompanhar seu comportamento em produção. From 46197310c1ea7560fc0e734d09b0dd88a2df869e Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 20 Oct 2015 22:28:08 +0200 Subject: [PATCH 191/472] Add es.yml locales file for spanish language. --- locales/es.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/es.yml diff --git a/locales/es.yml b/locales/es.yml new file mode 100644 index 000000000..cfb55fb96 --- /dev/null +++ b/locales/es.yml @@ -0,0 +1,7 @@ +es: + # Name of language listed in locales menu + language: Español (es) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: (Traducción de la versión original en Inglés) From 72d38c1c993261dc2608026944498269bd913add Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 20 Oct 2015 22:29:37 +0200 Subject: [PATCH 192/472] Add intro for spanish translation. --- content/es/intro.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/es/intro.md diff --git a/content/es/intro.md b/content/es/intro.md new file mode 100644 index 000000000..89cb9d1f5 --- /dev/null +++ b/content/es/intro.md @@ -0,0 +1,12 @@ +Introducción +============ + +En la época actual, el software se distribuye comunmente como un servicio: se le llama *web apps*, o *software as a service* (SaaS). "The twelve-factor app" es una metodología para construir aplicaciones SaaS que: + +* Usan formatos **declarativos** para la automatización de la configuración, para minimizar el tiempo y el coste para los nuevos desarrolladores que se unan al proyecto; +* Tienen un **contrato claro** con el sistema operativo sobre el que trabaja, ofreciendo la **máxima portabilidad** entre los entornos de ejecución; +* Son apropiadas para **desplegarse** en modernas **plataformas en la nube**, obviando la necesidad de servidores y administración de sistemas; +* **Minimiza la divergencia** entre desarrollo y producción, posibilitando el **despliegue continuo** para conseguir la máxima agilidad; +* Y puede **escalar** sin cambios significativos para herramientas, arquitectura o practicas de desarrollo. + +"The twelve-factor methodology" puede ser aplicado a aplicaciones escritas en cualquier lenguaje de programación, y cualquier combinación de servicios de soporte (bases de datos, colas, memoria cache, etc). From 12f33c05e7326115481bdf102ed2d33daed41c6e Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 20 Oct 2015 22:30:13 +0200 Subject: [PATCH 193/472] Add background for Spanish translation --- content/es/background.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 content/es/background.md diff --git a/content/es/background.md b/content/es/background.md new file mode 100644 index 000000000..e917ee7b0 --- /dev/null +++ b/content/es/background.md @@ -0,0 +1,8 @@ +Contexto +======== + +Los colaboradores de este documento han estado involucrados directamente en el desarrollo y despliegue de cientos de aplicaciones, y han sido testigos indirectos del desarrollo, las operaciones y el escalado de cientos de miles de aplicaciones mediante nuestro trabajo en la plataforma [Heroku](http://www.heroku.com/). + +Este documento sintetiza toda nuestra experiencia y observaciones en una amplia variedad de aplicaciones SaaS. Es la triangulación entre practicas ideales para el desarrollo de aplicaciones, prestando especial atención a las dinámicas del crecimiento natural de una aplicación a lo largo del tiempo, las dinámicas de colaboración entre desarrolladores que trabajan en el código base de las aplicaciones y [evitando el coste de la entropía del software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Nuestra motivación es elevar la concienciación de algunos problemas sistémicos que hemos visto en el desarrollo de las aplicaciones modernas, para aportar un vocabulario común que sirva para discutir estos problemas, y ofrecer un conjunto de soluciones conceptualmente robustas para esos problemas acompañados de su correspondiente terminología. El formato esta inspirado en los libros de Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* y *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 768d6497e2b84785dda368c5755208b45f334325 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Wed, 21 Oct 2015 21:57:07 +0200 Subject: [PATCH 194/472] Add codebase to Spanish translation --- content/es/codebase.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 content/es/codebase.md diff --git a/content/es/codebase.md b/content/es/codebase.md new file mode 100644 index 000000000..d0c7a8b84 --- /dev/null +++ b/content/es/codebase.md @@ -0,0 +1,17 @@ +## I. Base de código (Codebase) +### Una base de código sobre el que hacer control de seguimiento, muchos despliegues + +Una "twelve-factor app" se encuentra siempre en un sistema de control de versiones, tales como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). A una copia de la base de datos de seguimiento de actualización se le conoce como un *repositorio de código*, a menudo abreviado como *repo de código* o simplemente *repo*. + +Una *base de código* es cualquier repositorio (en un sistema de control de versiones centralizado como Subversion), o cualquier conjunto de repositorios que comparten un commit raíz (en un sistema de control de versiones descentralizado como Git). + +![Una base de código se aplica a muchos despliegues](/images/codebase-deploys.png) + +Siempre hay una correlación uno a uno entre la base de código y la aplicación: + +* Si hay muchas bases de código, no es una aplicación -- es un sistema distribuido. Cada componente en un sistema distribuido es una aplicación, y cada uno, individualmente, puede cumplir los requisitos de una "twelve-factor app". +* Multiples aplicaciones que comparten el mismo código es considerado como una violación de "twelve factor". La solución en este caso es separar el código compartido en librerías que pueden estar incluidas mediante un [gestor de dependencias](./dependencies). + +Hay una sola base de código por aplicación, pero habrá muchos despliegues de la aplicación. Un *despliegue* es una instancia de la aplicación que está corriendo . Esto es normalmente un sitio en producción, y uno o más sitios de pruebas. Además, cada desarrollador tiene una copia de la aplicación corriendo en su entorno de desarrollo local, cada uno de los cuales es considerado también como un despliegue. + +La base de código es el mismo en todos los despliegues, aun que pueden ser diferentes versiones en cada despliegue. Por ejemplo, un desarrollador tiene algunos commits sin desplegar en pruebas; pruebas tiene algunos commits que no están desplegados en producción. Pero todos ellos comparten la misma base de código, de este modo todos son identificables como diferentes despliegues de la misma aplicación. From 3a7e043c5d58252e179a6fb8617ff48dca2c0d24 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Wed, 21 Oct 2015 22:48:29 +0200 Subject: [PATCH 195/472] Add dependencies to Spanish translation --- content/es/dependencies.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/es/dependencies.md diff --git a/content/es/dependencies.md b/content/es/dependencies.md new file mode 100644 index 000000000..5a94b117b --- /dev/null +++ b/content/es/dependencies.md @@ -0,0 +1,12 @@ +## II. Dependencias +### Declarar y aislar explicitamente las dependencias + +La mayor parte de los lenguajes de programación ofrecen un sistema de paquetería para distribuir sus librerías de soporte, tales como [CPAN](http://www.cpan.org/) para Perl o [Rubygems](http://rubygems.org/) para Ruby. Las librerías instaladas a través de los sistemas de paquetería pueden ser instaladas en el sistema (conocido como "site packages") o limitado al directorio que contiene la aplicación (conocido como "vendoring" o "bundling"). + +**Una "twelve-factor app" nunca depende de la existencia explícita de paquetes instalados en el sistema.** Declara todas las dependencias, completamente y exactamente, mediante un manifiesto de *declaración de dependencias*. Además, usa una herramienta de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implicitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita es aplicada uniformemente tanto a producción como a desarrollo. + +Por ejemplo, [Gem Bundler](http://gembundler.com/) para Ruby dispone del formato `Gemfile` manifest para su declaración de dependencias y `bundle exec` para su aislamiento de dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de dependencias, y el enlace estático proporciona el aislamiento de dependencias. No importa que conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntos -- solo uno o el otro no es suficiente para satisfacer las condiciones de "twelve-factor". + +Uno de los beneficios de la declaración de dependencias explícita es que simplifica la configuración para los desarrolladores nuevos de la aplicación. El nuevo desarrollador puede probar la base de código de la aplicación en su maquina de desarrollo, requiriendo solo tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para correr el código de la aplicación con un *mandato para construir* determinado. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. + +Las "Twelve-factor apps" tampoco dependen de la existencia de ninguna herramienta en el sistema. Por ejemplo, ejecutar mandatos como ImageMagick o `curl`. Mientras estas herramientas pueden existir en muchos o incluso en la mayoría de los sistemas, no hay garantía de que vayan a existir en todos los sistemas donde la aplicación pueda ser ejecutada en el futuro, o si la versión encontrada en un futuro sistema será compatible con la aplicación. Si la aplicación necesita ejecutar una herramienta del sistema, esa herramienta debería estar incluida dentro de la aplicación. From 868bf0c1ba943fea7e89ee108dc0ad892ace37d4 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 22 Oct 2015 20:52:57 +0200 Subject: [PATCH 196/472] Add config to Spanish translation --- content/es/config.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 content/es/config.md diff --git a/content/es/config.md b/content/es/config.md new file mode 100644 index 000000000..82c114cc5 --- /dev/null +++ b/content/es/config.md @@ -0,0 +1,22 @@ +## III. Configuración +### Almacenar la configuración en el entorno + +Una configuración de una aplicación es todo lo que puede variar entre [despliegues](./codebase) (entorno de pruebas, producción, desarrollo, etc). Lo que incluye: + +* Recursos que manejan la base de datos, Memcached, y otros [backing services](./backing-services) +* Credenciales para servicios externos tales como Amazon S3 o Twitter +* Valores de despliegue como por ejemplo el nombre canónico del equipo para el despliegue + +Las aplicaciones a veces almacenan configuraciones como constantes en el código. Lo cual conduce a una violación de la metodología "twelve-factor", que requiere una **estricta separación de la configuración y el código**. La configuración varía sustancialmente en cada despliegue, el código no. + +La prueba definitiva para saber si una aplicación tiene toda su configuración correctamente separada del código es comprobar que la base de código puede ser código abierto en cualquier momento, sin comprometer las credenciales. + +Hay que resaltar que la definición de "configuración" **no** incluye las configuraciones internas de la aplicación, tales como `config/routes.rb` en Rails, o como [se conectan los módulos de código](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) en [Spring](http://spring.io/). Este tipo de configuraciones no varían entre despliegues, y por eso están mejor en el código. + +Otra estrategia de la configuración es el uso de ficheros de configuración que no se guardan en el control de versiones, como ocurre con el `config/database.yml` de Rails. Lo cual supone una gran mejora con respecto a las constantes que se guardan en el repositorio de código, pero todavía tiene debilidades: es fácil guardar un fichero de configuración en el repo por error; se tiende a desperdigar los ficheros de configuración en diferentes sitios y con distintos formatos, siendo más difícil la tarea de ver y gestionar toda la configuración en un solo sitio. Además, esos formatos tienden a ser específicos del lenguaje o del framework. + +**Las aplicaciones "twelve-factor" almacenan la configuración en *variables de entorno*** (a menudo acortadas como *env vars* o *env*). Las variables de entorno se intercambian fácilmente entre despliegues sin modificar nada en el código; a diferencia de los ficheros de configuración, hay una pequeña posibilidad de que se guarden en el repositorio de código accidentalmente; y a diferencia de los ficheros de configuración personalizados, u otros mecanismos de configuración como los System Properties de Java, son un estándar independiente+ del lenguaje y del sistema operativo. + +Otro aspecto de la gestión de la configuración es el agrupamiento. A veces las aplicaciones agrupan las configuraciones en grupos identificados (a menudo llamados "entornos" o "environments") identificando después despliegues específicos, como ocurre en Rails con los entornos `development`, `test`, y `production`. Este método no escala de manera limpia: según se van creando despliegues de la aplicación, se van necesitando nuevos entornos, tales como `staging` o `qa`. Según va creciendo el proyecto, los desarrolladores van añadiendo sus propios entornos especiales como `joes-staging`, resultando en una explosión combinatoria de configuraciones que hacen la gestión de despliegues de la aplicación muy frágil. + +En una aplicación "twelve-factor", las variables de entorno son controles granulares, cada una de ellas completamente ortogonales a las otras. Nunca se agrupan juntas como "entornos", pero en su lugar se gestionan independientemente para cada despliegue. Este es un modelo que escala con fluidez según la aplicación se extiende, naturalmente, en más despliegues a lo largo de su vida. From 93795e7ecff39b9380b0a4b049ed0bfa713dc805 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 22 Oct 2015 23:37:18 +0200 Subject: [PATCH 197/472] Add backing-services to Spanish translation --- content/es/backing-services.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/es/backing-services.md diff --git a/content/es/backing-services.md b/content/es/backing-services.md new file mode 100644 index 000000000..75e14e4ac --- /dev/null +++ b/content/es/backing-services.md @@ -0,0 +1,14 @@ +## IV. Servicios de respaldo +### Tratar los servicios de respaldo como recursos enganchables + +Un *servicio de respaldo* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento normal. Como ejemplos podemos encontrar almacenes de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), servicios SMTP para email saliente (como [Postfix](http://www.postfix.org/)), y sistemas de cache (como [Memcached](http://memcached.org/)). + +Los servicios de respaldo, como las bases de datos, están gestionados tradicionalmente por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, la aplicación también puede tener servicios proporcionados y gestionados por terceros. Ejemplos de ésto son los servicios SMTP (como [Postmark](http://postmarkapp.com/)), servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios de consumo accesibles mediante APIs (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). + +**El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos enganchados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local podría ser cambiado por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. + +Cada servicio de respaldo distinto es un *recurso*. Por ejemplo, una base de datos MySQL es un recurso; dos bases de datos MySQL (usadas para "sharding" en la capa de aplicación) les convierte en dos recursos distintos. Una aplicación "twelve factor" trata esas bases de datos como *recursos enganchados*, lo que evidencia su bajo acoplamiento al despliegue al que se unen. + +Un despliegue en producción vinculado a cuatro servicios de respaldo. + +Los recursos se pueden enganchar y desenganchar a voluntad. Por ejemplo, si la base de datos funciona mal debido a un problema en el hardware, el administrador de la aplicación puede cambiar a un nuevo servidor de bases de datos que haya sido restaurado de un backup reciente. La base de datos actual en producción se puede desenganchar, y enganchar la nueva base de datos -- todo ésto sin ningún cambio en el código. From 2c64db944464f814ae3f145d02127920535d86d8 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 23 Oct 2015 20:45:06 +0200 Subject: [PATCH 198/472] Add build-release-run to Spanish translation --- content/es/build-release-run.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 content/es/build-release-run.md diff --git a/content/es/build-release-run.md b/content/es/build-release-run.md new file mode 100644 index 000000000..74f7e950e --- /dev/null +++ b/content/es/build-release-run.md @@ -0,0 +1,18 @@ +## V. Construir, distribuir, ejecutar +### Separar rigurosamente la fase de construcción de la fase de ejecución + +La [base de código](./codebase) se transforma en un despliegue (que no es de desarrollo) mediante tres fases: + +* La *fase de construcción* es una transformación que convierte un repositorio de código en un paquete ejecutable conocido como *construcción* (build). Usando una versión del código de un commit específico por el proceso de despliegue, la fase de construcción trae todas las [dependencias](./dependencies) y compila los binarios y las herramientas. +* En la *fase de distribución* se coje la construcción creada en la fase de construcción y se combina con la [configuración](./config) del despliegue actual. La *distribución* resultante contiene tanto la construcción como la configuración y está lista para ejecutar inmediatamente en el entorno de ejecución. +* La *fase de ejecución* (también conocida como "runtime") ejecuta la aplicación en el entorno de ejecución, lanzando un conjunto de [procesos](./processes) de la aplicación contra una distribución seleccionada. + +![El código se convierte en una construcción, que se combina con la configuración para crear una distribución.](/images/release.png) + +**Las aplicaciones "twelve-factor" hacen una separación rigurosa entre las fases de construcción, de distribución y de ejecución.** Por ejemplo, es imposible hacer cambios en el código en la fase de ejecución, porque no hay una manera de propagar dichos cambios de vuelta a la fase de construcción. + +Las herramientas de despliegue ofrecen normalmente herramientas de gestión de distribuciones (releases), especialmente la habilidad de volver a una versión anteriormente distribuida. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. + +Cada distribución siempre debería tener un identificador único de distribución, como por ejemplo la marca de tiempo (timestamp) de la distribución (`2011-04-06-20:32:17`) o un número incremental (como `v100`). Las distribuciones son como los libros de contabilidad al que solo se le pueden agregar registros y no puede ser modificada una vez es creada. Cualquier cambio debe crear una nueva distribución. + +Las construcciones son iniciados por los desarrolladores de la aplicación cuando el nuevo código se despliega. La fase de ejecución, en cambio, puede suceder automáticamente por ejemplo cuando se reinicia un servidor, o cuando un proceso termina inesperadamente siendo reiniciado por el gestor de procesos. Por tanto, la fase de ejecución debería mantenerse lo más estático como sea posible, ya que evita que una aplicación en ejecución pueda causar una interrupción en mitad de la noche cuando no hay desarrolladores a mano. La fase de construcción puede ser más compleja, ya que los errores están siempre en la mente de un desarrollador que está dirigiendo el despliegue. From 5139fc996ffea0ac8efff1e7f38b331342fbb0dd Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 23 Oct 2015 20:45:27 +0200 Subject: [PATCH 199/472] Review backing-services --- content/es/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/backing-services.md b/content/es/backing-services.md index 75e14e4ac..f5f4efc9f 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -3,7 +3,7 @@ Un *servicio de respaldo* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento normal. Como ejemplos podemos encontrar almacenes de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), servicios SMTP para email saliente (como [Postfix](http://www.postfix.org/)), y sistemas de cache (como [Memcached](http://memcached.org/)). -Los servicios de respaldo, como las bases de datos, están gestionados tradicionalmente por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, la aplicación también puede tener servicios proporcionados y gestionados por terceros. Ejemplos de ésto son los servicios SMTP (como [Postmark](http://postmarkapp.com/)), servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios de consumo accesibles mediante APIs (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). +Los servicios de respaldo, como las bases de datos, se gestionan tradicionalmente por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden tener servicios proporcionados y gestionados por terceros. Ejemplos de ésto son los servicios SMTP (como [Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios de consumo accesibles mediante APIs (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). **El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos enganchados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local podría ser cambiado por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. From cbd53cb6f3f6f0d2abdc47c985bd0d673c4990ad Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Wed, 28 Oct 2015 00:59:14 +0100 Subject: [PATCH 200/472] Add processes to Spanish translation --- content/es/processes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/es/processes.md diff --git a/content/es/processes.md b/content/es/processes.md new file mode 100644 index 000000000..2589ee5d7 --- /dev/null +++ b/content/es/processes.md @@ -0,0 +1,14 @@ +## VI. Procesos +### Ejecutar la aplicación como uno o más procesos sin estado + +La aplicación se ejecuta en entornos de ejecución como uno o más *procesos*. + +El caso más sencillo se daría cuando el código es un script independiente, el entorno de ejecución es un portátil de un desarrollador, el compilador o interprete correspondiente del lenguaje está instalado, y el proceso se lanza mediante la linea de mandatos (por ejemplo, `python my_script.py`). El otro extremo sería un despliegue en producción de una aplicación compleja que puede usar muchos [tipos de procesos, instanciados en cero o más procesos en ejecución](./concurrency). + +**Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier dato que necesite persistencia debe ser almacenado en un [servicio de respaldo](./backing-services) con estado, que suele ser una base de datos. + +El espacio de memoria o el sistema de ficheros de un proceso se puede usar como una cache temporal de un solo uso. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca dan por sentado que cualquier cosa cacheada en memoria o en el disco estará disponible en el futuro en una petición o en un proceso -- con muchos procesos de cada tipo corriendo, existe una alta probabilidad de que se sirva una petición por otro proceso en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (activado por un despliegue del código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). + +Los empaquetadores de activos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" se prefiere hacer esta compilación durante la [fase de construcción](./build-release-run), como el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), en lugar de en tiempo de ejecución. + +Algunos sistemas webs dependen de ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- esto es, cacheando la información de la sesión de usuario en la memoria del proceso de la aplicación y esperando peticiones futuras del mismo visitante para redirigirle al mismo proceso. Las sesiones sticky son una violación de "twelve-factor" y nunca deverían usarse o depender de ellas. Los datos del estado de la sesion es un buen candidato para un almacen de información que ofrece mecanismos de tiempo de expiración, como [Memcached](http://memcached.org/) o [Redis](http://redis.io/). From 7edd7737a52bb8d21f0239982021e2f86c91e580 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 29 Oct 2015 21:28:24 +0100 Subject: [PATCH 201/472] Add port-binding to Spanish translation --- content/es/port-binding.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/es/port-binding.md diff --git a/content/es/port-binding.md b/content/es/port-binding.md new file mode 100644 index 000000000..872add64d --- /dev/null +++ b/content/es/port-binding.md @@ -0,0 +1,14 @@ +## VII. Asignación de puertos +### Publicar servicios mediante asignación de puertos + +Las aplicaciones web a menudo se ejecutan mediante contenedores web. Por ejemplo, las aplicaciones PHP se pueden ejecutar como módulos del [HTTPD de Apache](http://httpd.apache.org/), y las aplicaciones Java en [Tomcat](http://tomcat.apache.org/). + +**Las aplicaciones "twelve factor" son completamente auto-contenidas** y no dependen de un servidor web en ejecución para crear un servicio web público. Una aplicación web **usa HTTP como un servicio al que se le asigna un puerto**, y escucha las peticiones que recibe por dicho puerto. + +En un entorno local de desarrollo, el desarrollador usa una URL del servicio como `http://localhost:5000/` para acceder al servicio que ofrece una aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una ruta pública se redirija hacia el proceso web que tiene asignado en su puerto correspondiente. + +Normalmente se implementa usando una [declaracion de dependencias](./dependencies) para incluir librerías en las aplicaciones web, como en [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Esto ocurre completamente en el *espacio del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga a un puerto a servir peticiones. + +HTTP no es el único servicio que usa la asignación de puertos. Lo cierto es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigne un puerto y que espere peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). + +También es cierto que la aproximación de asignación de puertos ofrece la posibilidad de que una aplicación puede llegar a ser un [servicio de respaldo](./backing-services) para otra aplicación, usando la URL de la aplicación de respaldo como un recurso declarado en la [configuración](./config) de la aplicación consumidora. From cfdc4ec714d01218e5410de6d4fcf24eda0a7d16 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 29 Oct 2015 22:54:54 +0100 Subject: [PATCH 202/472] Add concurrency to Spanish translation --- content/es/concurrency.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/es/concurrency.md diff --git a/content/es/concurrency.md b/content/es/concurrency.md new file mode 100644 index 000000000..6d078a75a --- /dev/null +++ b/content/es/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrencia +### Escalar mediante el modelo de procesos + +Cualquier programa de ordenador, una vez en ejecución, se representa en memoria por uno o más procesos. Las aplicaciones web usan diferentes formas de ejecución de procesos. Por ejemplo, los procesos PHP se ejecutan como procesos pesados, hijos del proceso Apache, que se iniciando cuando el volumen de peticiones lo requiere. Los procesos Java siguen una aproximación distinta, la Máquina Virtual de Java (JVM) proporciona una gran cantidad de procesos que reservan un gran volumen de recursos del sistema (CPU y memoria) al inicio, gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución pasan practicamente inadvertidos para los desarrolladores de la aplicación. + +![La extensión se ve representada por los procesos en ejecución, la diversidad de carga de trabajo se ve representada por los distintos tipos de procesos.](/images/process-types.png) + +**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" toman ejemplo de [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede planificar su aplicación para manejar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso pesado y las tareas con mucha carga de trabajo se pueden procesar con procesos ligeros (threads). + +Esto no limita a los procesos a gestionar su propia división interna, mediante threads en la ejecución de la máquina virtual o el modelo asíncrono o por eventos de herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Pero una maquina virtual individual solo puede crecer hasta cierto tamaño, así que la aplicación debe ser capaz de dividirse en multiples procesos que se ejecuten en múltiples máquinas físicas. + +El modelo de procesos deja ver todo su potencial cuando llega la hora de escalar. La [naturaleza share-nothing, divisible horizontalmente de los procesos de las aplicaciones "twelve-factor"](./processes) se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *process formation*. + +Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) o escribir ficheros de tipo PID. En su lugar, se debe confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [el historial](./logs), responder a procesos que terminan inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. From a1bf7cc7b86bebf57d31e78eccd0e0e205bba3be Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 29 Oct 2015 22:59:10 +0100 Subject: [PATCH 203/472] Add who to Spanish translation --- content/es/who.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 content/es/who.md diff --git a/content/es/who.md b/content/es/who.md new file mode 100644 index 000000000..a6391a916 --- /dev/null +++ b/content/es/who.md @@ -0,0 +1,4 @@ +¿Quién debería leer este documento? +=================================== + +Cualquier desarrollador que construya aplicaciones y las ejecute como un servicio. Ingenieros de operaciones que desplieguen y gestionen dichas aplicaciones. From c3684b1d990be3e9dc697a3d99a974f6351161ab Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 6 Nov 2015 22:54:05 +0100 Subject: [PATCH 204/472] Add disposability to Spanish translation. --- content/es/disposability.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 content/es/disposability.md diff --git a/content/es/disposability.md b/content/es/disposability.md new file mode 100644 index 000000000..947016f5d --- /dev/null +++ b/content/es/disposability.md @@ -0,0 +1,12 @@ +## IX. Disponibilidad +### Hacer el sistema más robusto mediante inicios rápidos y finalizaciones seguras + +**Los [procesos](./processes) de las aplicaciones "twelve-factor" son *deshechables*, lo que significa que pueden iniciarse o finalizarse en el momento que sea necesario.** Esto permite un escalado rápido y flexible, un despliegue rápido del [código](./codebase) y de los cambios de las [configuraciones](./config), y despliegues más robustos en producción. + +Los procesos deberían luchar por **minimizar el tiempo de inicio**. En el mejor de los casos, un proceso necesita unos pocos segundos desde que se ejecuta el mandato hasta que se inicia y está preparado para recibir peticiones o trabajos. Mejorar el tiempo de inicio proporciona una mayor agilidad para el proceso de [distribución](./build-release-run) y escalado; y lo hace más robusto, porque el gestor de procesos puede mover procesos más fácilmente entre máquinas físicas con garantías. + +Los procesos **paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implicitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos), y en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. + +Para un trabajador (o "worker") finalizar de manera segura se consigue devolviendo el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implicitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). + +Los procesos deberían ser **robustos contra paradas inesperadas**, como en el caso de un fallo a nivel hardware. Aunque es un caso más raro que una parada mediante la señal `SIGTERM`, es posible que ocurra. Lo recomendable es usar un sistema de colas robusto, como puede ser Beanstalkd, que devuelve los trabajos a su cola cuando los clientes se desconectan o expira su tiempo de espera ("timeout"). En cualquier caso, una aplicación "twelve-factor" es una arquitectura que trata finalizaciones inesperadas y peligrosas. El [diseño Crash-only](http://lwn.net/Articles/191059/) lleva este concepto a su [conclusión lógica](http://docs.couchdb.org/en/latest/intro/overview.html). From 8391b817b806bf30594e68237ea52ec1ae2c3f99 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Sat, 7 Nov 2015 08:54:30 +0100 Subject: [PATCH 205/472] Add dev-prod-parity to Spanish translation --- content/es/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 content/es/dev-prod-parity.md diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md new file mode 100644 index 000000000..952a4a560 --- /dev/null +++ b/content/es/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Paridad entre desarrollo y producción +### Mantener desarrollo, preproducción y producción tan parecidos como sea posible + +Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo (donde un desarrollador puede editar en vivo en un [despliegue](./codebase) local de la aplicación) y producción (un despliegue en el que la aplicación está en ejecución disponible para los usuarios). Estas diferencias se pueden clasificar en tres tipos: + +* **Diferencias de tiempo**: Un desarrollador puede estar trabajando en un código durante días, semanas o incluso meses antes de que llegue a producción. +* **Diferencias de personal**: Los desarrolladores escriben el código y los ingenieros de operaciones lo despliegan. +* **Diferencias de herramientas**: Los desarrolladores pueden usar una pila como Nginx, SQLite y OS X, mientras que en producción se usa Apache, MySQL y Linux. + +** Las aplicaciones "twelve-factor" están diseñadas para hacer [despliegues continuos](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) que reducen las diferencias entre los entornos de desarrollo y producción.** Teniendo en cuenta las tres diferencias descritas anteriormente: + +* Reducir las diferencias de tiempo: Un desarrollador puede escribir código y tenerlo desplegado en tan solo unas horas o incluso, minutos más tarde. +* Reducir las diferencias de personal: Los desarrolladores que escriben el código estás muy involucrados en el despliegue y observan su comportamiento en producción. +* Reducir las diferencias de herramientas: tratar de hacer que desarrollo y producción sean tan parecidos como sea posible. + +Resumiendo lo anterior en una tabla: + + + + + + + + + + + + + + + + + + + + + + +
Aplicaciones tradicionalesAplicaciones "twelve-factor"
Tiempo entre desplieguesSemanasHoras
Desarrolladores vs Ingenieros de operacionesDiferentes personasMismas personas
Entorno de desarrollo vs entorno de producciónDivergentesLo más parecidos posibles
+ +Los [servicios de respaldo](./backing-services), como la base de datos de la aplicación, el sistema de colas, o la cache, es donde la igualdad en los entornos de desarrollo y producción es importante. Muchos lenguajes ofrecen librerías en las que se simplifica el acceso a los servicios de respaldo, incluidos *adaptadores* para diferentes tipos de servicios. Se pueden observar algunos ejemplos en la siguiente tabla. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TipoLenguajeLibreríaAdaptador
Base de datosRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
ColasPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemoria, sistema de ficheros, Memcached
+ +Los desarrolladores a veces caen en la tentación de usar servicios de respaldo ligeros en sus entornos locales, mientras que en producción se usan los más serios y robustos. Por ejemplo, usando SQLite localmente y PostgreSQL en producción; o memoria local para la cache en desarrollo y Memcached en producción. + +**El desarrollador "twelve-factor" resiste sus deseos de usar diferentes servicios de respaldo en desarrollo y producción**, incluso cuando los adaptadores teoricamente abstractos están lejos de cualquier diferencia en servicios de respaldo. Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que salen de la nada, causando que el código que funciona y pasa los test en desarrollo o en preproducción, fallen en producción. Este tipo de errores provocan desacuerdos que desincentivan el despliegue continuo. El coste de estos desacuerdos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se se hace balance del total del tiempo de vida de una aplicación. + +Los servicios ligeros locales son menos atractivos que antes. Los servicios de respaldo modernos como Memcached, PostgreSQL, y RabbitMQ no son dificiles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinados con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas son bajos comparados con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. + +Los adaptadores de servicios de respaldo todavía son de gran utilidad, porque hacen que cambiar de servicios de respaldo sea relativamente poco doloroso. No obstante, todos los despliegues de una aplicación (entornos de desarrollo, preproducción y producción) deberían usar el mismo tipo y version de cada uno de los servicios de respaldo. From ba676d80191cd0bd082867aafae12b28145c9a58 Mon Sep 17 00:00:00 2001 From: Martin Ruopp Date: Sat, 7 Nov 2015 18:16:59 +0100 Subject: [PATCH 206/472] added german translation --- content/de/admin-processes.md | 14 ++++++ content/de/background.md | 8 ++++ content/de/backing-services.md | 14 ++++++ content/de/build-release-run.md | 20 +++++++++ content/de/codebase.md | 18 ++++++++ content/de/concurrency.md | 14 ++++++ content/de/config.md | 23 ++++++++++ content/de/dependencies.md | 12 ++++++ content/de/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/de/disposability.md | 12 ++++++ content/de/intro.md | 12 ++++++ content/de/logs.md | 16 +++++++ content/de/port-binding.md | 14 ++++++ content/de/processes.md | 14 ++++++ content/de/toc.md | 38 +++++++++++++++++ content/de/who.md | 4 ++ locales/de.yml | 7 +++ 17 files changed, 316 insertions(+) create mode 100644 content/de/admin-processes.md create mode 100644 content/de/background.md create mode 100644 content/de/backing-services.md create mode 100644 content/de/build-release-run.md create mode 100644 content/de/codebase.md create mode 100644 content/de/concurrency.md create mode 100644 content/de/config.md create mode 100644 content/de/dependencies.md create mode 100644 content/de/dev-prod-parity.md create mode 100644 content/de/disposability.md create mode 100644 content/de/intro.md create mode 100644 content/de/logs.md create mode 100644 content/de/port-binding.md create mode 100644 content/de/processes.md create mode 100644 content/de/toc.md create mode 100644 content/de/who.md create mode 100644 locales/de.yml diff --git a/content/de/admin-processes.md b/content/de/admin-processes.md new file mode 100644 index 000000000..709adf1a2 --- /dev/null +++ b/content/de/admin-processes.md @@ -0,0 +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: + +* 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`). + +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. + +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 diff --git a/content/de/background.md b/content/de/background.md new file mode 100644 index 000000000..b2184d896 --- /dev/null +++ b/content/de/background.md @@ -0,0 +1,8 @@ +Hintergrund +========== + +Die Mitwirkenden an diesem Dokument waren direkt beteiligt an der Entwicklung und dem Deployment von hunderten von Apps und wurden Zeugen bei der Entwicklung, beim Betrieb und der Skalierung von hunderttausenden von Apps im Rahmen unserer Arbeit an der [Heroku](http://www.heroku.com/)-Plattform. + +Dieses Dokument ist eine Synthese all unserer Erfahrungen und der Beobachtungen einer großen Bandbreite von Software-As-A-Service Apps. Es ist eine Bestimmung der idealen Praktiken bei der App-Entwicklung mit besonderem Augenmerk auf die Dynamik des organischen Wachstums einer App über die Zeit, die Dynamik der Zusammenarbeit zwischen den Entwicklern die an einer Codebase zusammenarbeiten und der [Vermeidung der Kosten von Software-Erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Unsere Motivation ist, das Bewusstsein zu schärfen für systembedingte Probleme in der aktuellen Applikationsentwicklung, ein gemeinsames Vokabular zur Diskussion dieser Probleme zu liefern und ein Lösungsportfolio zu diesen Problemen mit einer zugehörigen Terminologie anzubieten. Das Format ist angelehnt an Martin Fowlers Bücher *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* und *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. diff --git a/content/de/backing-services.md b/content/de/backing-services.md new file mode 100644 index 000000000..ca1b735b5 --- /dev/null +++ b/content/de/backing-services.md @@ -0,0 +1,14 @@ +## IV. Unterstützende Dienste +### Unterstützende Dienste als angehängte Ressourcen behandeln + +Ein *unterstützender Dienst* ist jeder Dienst, den die App über das Netzwerk im Rahmen ihrer normalen Arbeit konsumiert. Beispiele sind Datenspeicher (wie [MySQL](http://dev.mysql.com/) oder [CouchDB](http://couchdb.apache.org/)), Messaging/Queueing-Systeme (wie [RabbitMQ](http://www.rabbitmq.com/) oder [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP-Dienste für das Senden von Mail (wie [Postfix](http://www.postfix.org/)), und Cache-Systeme (wie [Memcached](http://memcached.org/)). + +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. + +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. + +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. diff --git a/content/de/build-release-run.md b/content/de/build-release-run.md new file mode 100644 index 000000000..ca94f9e79 --- /dev/null +++ b/content/de/build-release-run.md @@ -0,0 +1,20 @@ +## V. Build, release, run +### Build- und Run-Phase strikt trennen + +Eine [Codebase](./codebase) durch drei Phasen in einen (Nicht-Entwicklungs)-Deploy transformiert: + +* 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. +![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. + +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. + +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 new file mode 100644 index 000000000..6e4037826 --- /dev/null +++ b/content/de/codebase.md @@ -0,0 +1,18 @@ +## I. Codebase +### Eine im Versionsmanagementsystem verwaltete Codebase, viele Deployments + +Eine Zwölf-Faktor-App wird immer in einem Versionsmanagementsystem verwaltet, wie zum Beispiel [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) oder [Subversion](http://subversion.apache.org/). Eine Kopie der Versionsdatenbank wird *Code Repository* genannt, kurz *Code Repo* oder auch nur *Repo*. + +Eine *Codebase* ist jedes einzelne Repo (in einem zentralisierten Versionsmanagementsystem wie Subversion) oder jede Menge von Repos, die einen ursprünglichen Commit teilen (in dezentralisierten Versionsmanagementsystemen wie git). + +![Eine Codebase bildet sich in viele Deploys ab.](/images/codebase-deploys.png) + +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. + +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 new file mode 100644 index 000000000..f92441b1e --- /dev/null +++ b/content/de/concurrency.md @@ -0,0 +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. + +![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](http://adam.heroku.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. + +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. + +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. + +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. \ No newline at end of file diff --git a/content/de/config.md b/content/de/config.md new file mode 100644 index 000000000..3f0850ac7 --- /dev/null +++ b/content/de/config.md @@ -0,0 +1,23 @@ +## III. Konfiguration +### Die Konfiguration in Umgebungsvariablen ablegen + +Die *Konfiguration* einer App ist alles, was sich wahrscheinlich zwischen den [Deploys](./codebase) ändern wird (Staging, Produktion, Entwicklungsumgebungen, usw.). Dies umfasst: + +* Resource-Handles für Datenbanken, Memcached und andere [unterstützende Dienste](./backing-services) +* 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. + +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. + +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 of Sprach- oder Plattform-spezifisch. + +**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. + +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 new file mode 100644 index 000000000..460b8419d --- /dev/null +++ b/content/de/dependencies.md @@ -0,0 +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"). + +**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 [Gem Bundler](http://gembundler.com/) 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`. + +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. \ No newline at end of file diff --git a/content/de/dev-prod-parity.md b/content/de/dev-prod-parity.md new file mode 100644 index 000000000..a672c3ec7 --- /dev/null +++ b/content/de/dev-prod-parity.md @@ -0,0 +1,76 @@ +##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://www.avc.com/a_vc/2011/02/continuous-deployment.html) 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 AppZwölf-Faktor-App
Zeit zwischen DeploymentsWochenStunden
Code-Autoren und Code-DeployerAndere MenschenDieselben Menschen
Entwicklungs- und Produktions-UmgebungUnterschiedlichSo ä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. + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArtSpracheBibliothekAdapter
DatenbankRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheSpeicher, 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 Diensts benutzen. diff --git a/content/de/disposability.md b/content/de/disposability.md new file mode 100644 index 000000000..ac596b739 --- /dev/null +++ b/content/de/disposability.md @@ -0,0 +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. + +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 **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. + +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/intro.md b/content/de/intro.md new file mode 100644 index 000000000..8319637cd --- /dev/null +++ b/content/de/intro.md @@ -0,0 +1,12 @@ +Einführung +============ + +Heute wird Software oft als Dienst geliefert - auch *Web App* oder *Software-As-A-Service* genannt. Die Zwölf-Faktoren-App ist eine Methode um Software-As-A-Service Apps zu bauen die: + +* **deklarative** Formate benutzen für die Automatisierung der Konfiguration, um Zeit und Kosten für neue Entwickler im Projekt zu minimieren; +* einen **sauberen Vertrag** mit dem zugrundeliegenden Betriebssystem haben, **maximale Portierbarkeit** zwischen Ausführungsumgebungen bieten; +* sich für das **Deployment** auf modernen **Cloud-Plattformen** eignen, die Notwendigkeit von Servern und Serveradministration vermeiden; +* die **Abweichung minimieren** zwischen Entwicklung und Produktion, um **Continuous Deployment** für maximale Agilität ermöglichen; +* und **skalieren** können ohne wesentliche Änderungen im Tooling, in der Architektur oder in den Entwicklungsverfahren. + +Die Zwölf-Faktoren-Methode kann auf Apps angewendet werden, die in einer beliebigen Programmiersprache geschrieben sind, und die eine beliebige Kombination von unterstützenden Diensten benutzen (Datenbank, Queue, Cache, ...) diff --git a/content/de/logs.md b/content/de/logs.md new file mode 100644 index 000000000..c31658ed1 --- /dev/null +++ b/content/de/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Logs als Strom von Ereignissen behandeln + +*Logs* machen das Verhalten einer laufenden App sichtbar. In Server-basierten Umgebungen werden sie üblicherweise in eine Datei auf der Platte geschrieben (eine Logdatei) - das ist aber nur ein Ausgabeformat. + +Logs sind der [Stream](http://adam.heroku.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. + +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: + +* 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). \ No newline at end of file diff --git a/content/de/port-binding.md b/content/de/port-binding.md new file mode 100644 index 000000000..221d3efbf --- /dev/null +++ b/content/de/port-binding.md @@ -0,0 +1,14 @@ +## 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/). + +**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. + +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. + +Ü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. + +HTTP ist nicht der einzige Dienst, der durch Portbindung exportiert werden kann. Fast jede Server-Software kann betrieben werden, indem ein Prozess an einen Port gebunden wird und auf ankommende Requests wartet. Einige Beispiele sind [ejabberd](http://www.ejabberd.im/) (spricht [XMPP](http://xmpp.org/)) und [Redis](http://redis.io/) (spricht das [Redis-Protokoll](http://redis.io/topics/protocol)). + +Es sei auch erwähnt, dass durch Portbindung eine App ein [unterstützender Dienst](./backing-services) für eine andere App werden kann, indem die URL der unterstützenden App der konsumierenden App als Resource-Handle zur Verfügung gestellt wird. diff --git a/content/de/processes.md b/content/de/processes.md new file mode 100644 index 000000000..4775819d2 --- /dev/null +++ b/content/de/processes.md @@ -0,0 +1,14 @@ +## VI. Prozesse +### Die App als einen oder mehrere Prozesse ausführen + +Die App wird als ein oder mehrere *Prozesse* ausgeführt. + +Im einfachsten Fall ist der Code ein Stand-alone-Skript, die Ausführungsumgebung ist der lokale Laptop eines Entwicklers mit einer installierten Laufzeitumgebung einer Sprache, und der Prozess wird von der Kommandozeile gestartet (zum Beispiel `python my_script.py`). Am anderen Ende des Spektrums kann eine hochentwickelte App viele [Prozesstypen benutzen, die in keinen oder mehreren Prozessen laufen](./concurrency). + +**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. + +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. + +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 diff --git a/content/de/toc.md b/content/de/toc.md new file mode 100644 index 000000000..94e8a1f55 --- /dev/null +++ b/content/de/toc.md @@ -0,0 +1,38 @@ +Die zwölf Faktoren +================== + +## [I. Codebase](./codebase) +### Eine im Versionsmanagementsystem verwaltete Codebase, viele Deployments + +## [II. Abhängigkeiten](./dependencies) +### Abhängigkeiten explizit deklarieren und isolieren + +## [III. Konfiguration](./config) +### Die Konfiguration in Umgebungsvariablen ablegen + +## [IV. Unterstützende Dienste](./backing-services) +### Unterstützende Dienste als angehängte Ressourcen behandeln + +## [V. Build, release, run](./build-release-run) +### Build- und Run-Phase strikt trennen + +## [VI. Prozesse](./processes) +### Die App als einen oder mehrere Prozesse ausführen + +## [VII. Bindung an Ports](./port-binding) +### Dienste durch das Binden von Ports exportieren + +## [VIII. Nebenläufigkeit](./concurrency) +### Mit dem Prozess-Modell skalieren + +## [IX. Einweggebrauch](./disposability) +### Robuster mit schnellem Start und problemlosen Stopp + +## [X. Dev-Prod-Vergleichbarkeit ](./dev-prod-parity) +### Entwicklung, Staging und Produktion so ähnlich wie möglich halten + +## [XI. Logs](./logs) +### Logs als Strom von Ereignissen behandeln + +## [XII. Admin-Prozesse](./admin-processes) +### Admin/Management-Aufgaben als einmalige Vorgänge behandeln diff --git a/content/de/who.md b/content/de/who.md new file mode 100644 index 000000000..7302cb950 --- /dev/null +++ b/content/de/who.md @@ -0,0 +1,4 @@ +We sollte dieses Dokument lesen? +============================== + +Jeder Entwickler der Apps baut, die als Dienst laufen. Administratoren, die solche Apps managen oder deployen. diff --git a/locales/de.yml b/locales/de.yml new file mode 100644 index 000000000..5400a948a --- /dev/null +++ b/locales/de.yml @@ -0,0 +1,7 @@ +fr: + # Name of language listed in locales menu + language: "Deutsch (de)" + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Dies ist eine Übersetzung." From 176457aa10d10587dd0b1110e1ee57731e827709 Mon Sep 17 00:00:00 2001 From: Martin Ruopp Date: Sat, 7 Nov 2015 18:19:05 +0100 Subject: [PATCH 207/472] corrected locale fr -> de --- locales/de.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/de.yml b/locales/de.yml index 5400a948a..18557d8b9 100644 --- a/locales/de.yml +++ b/locales/de.yml @@ -1,4 +1,4 @@ -fr: +de: # Name of language listed in locales menu language: "Deutsch (de)" From d35a81797a01aa0b10e84db72ef430842e8ad3b6 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 17 Nov 2015 23:34:17 +0100 Subject: [PATCH 208/472] Add toc to Spanish translation --- content/es/toc.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 content/es/toc.md diff --git a/content/es/toc.md b/content/es/toc.md new file mode 100644 index 000000000..6a169dc06 --- /dev/null +++ b/content/es/toc.md @@ -0,0 +1,39 @@ +Twelve Factors +============== + +## [I. Repositorio](./codebase) +### Un repositorio para hacer el seguimiento del control de versiones, multiples despliegues + +## [II. Dependencias](./dependencies) +### Dependencias declaradas explicitamente y aisladas + +## [III. Configuraciones](./config) +### Almacenar la configuración en el entorno + +## [IV. Servicios de respaldo](./backing-services) +### Tratar a los servicios de respaldo como piezas intercambiables + +## [V. Construir, desplegar, ejecutar](./build-release-run) +### Las fases de construcción y ejecución totalmente separadas + +## [VI. Procesos](./processes) +### Ejecutar la aplicación como uno o más procesos sin estado + +## [VII. Asignación de puertos](./port-binding) +### Publicar servicios mediante asignación de puertos + +## [VIII. Concurrencia](./concurrency) +### Escalar mediante el modelo de procesos + +## [IX. Disponibilidad](./disposability) +### Maximizar la solidez con inicios rápidos y finalizaciones seguras + +## [X. Paridad en desarrollo y producción](./dev-prod-parity) +### Mantener desarrollo, preproducción y producción tan parecidos como sea posible + +## [XI. Historiales](./logs) +### Tratar los historiales como flujos de eventos + +## [XII. Administración de procesos](./admin-processes) +### Ejecutar tareas de administración/gestión como procesos +Run admin/management tasks as one-off processes From ffd1a8431059e00f3ac5fdbb8350dcd52791757b Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 17 Nov 2015 23:34:33 +0100 Subject: [PATCH 209/472] Add logs to Spanish translation --- content/es/logs.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 content/es/logs.md diff --git a/content/es/logs.md b/content/es/logs.md new file mode 100644 index 000000000..4e9c58174 --- /dev/null +++ b/content/es/logs.md @@ -0,0 +1,18 @@ +## XI. Historiales +### Tratar los historiales como un flujo de eventos + +Los *historiales* proporcionan visibilidad al comportamiento de la ejecución de la aplicación. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico"); pero este es solo un posible formato de salida. + +Un historial es un resumen de un [flujos](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/), eventos capturados y ordenados según su momento de ejecución del flujo de salida de todos los procesos en ejecución y los servicios de respaldo. + + time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). From 61a927c43d2a0ed4541525caff452bec74b142d6 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 17 Nov 2015 23:34:52 +0100 Subject: [PATCH 210/472] Add admin-processes to Spanish translation --- content/es/admin-processes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/es/admin-processes.md diff --git a/content/es/admin-processes.md b/content/es/admin-processes.md new file mode 100644 index 000000000..eb3312348 --- /dev/null +++ b/content/es/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Procesos de administración +### Ejecutar las tareas de gestión/administración como procesos de un solo uso + +El [juego de procesos](./concurrency) es un conjunto de procesos que se usan para hacer las tareas habituales de la aplicación (como procesar las peticiones web). Por separado, a menudo los desarrolladores desean ejecutar procesos de administración o mantenimiento de un solo uso, como: + +* Ejecutar migraciones de bases de datos (e.g. `manage.py migrate` en Django, `rake db:migrate` en Rails). +* Ejecutar una consola (conocidas también como [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) para ejecutar código arbitrario o inspeccionar los modelos de la aplicación en una base de datos con datos reales. La mayoría de los lenguajes proporcionan un interprete de tipo REPL si se ejecuta el mismo mandato sin ningún argumento (e.g. `python` o `perl`) y en algunos casos tienen un mandato distinto (e.g. `irb` en Ruby, `rails console` en Rails). +* Ejecutar scripts de un solo uso incluidos en el repositorio de la aplicación (e.g. `php scripts/fix_bad_records.php`). + +Los procesos de administración únicos deberían ejecutarse en un entorno idéntico al que se usa normalmente en [procesos de larga duración](./processes) de la aplicación. Estos procesos se ejecutan en una [distribución](./build-release-run) concreta, usando la misma [base de código](./codebase) y la misma [configuración](./config), que cualquier proceso que ejecuta esa distribución. El código de administración debe ser enviado con el código de la aplicación para evitar problemas de sincronización. + +Se deberían usar las mismas técnicas de [aislamiento de dependencias](./dependencies) en todos los tipos de procesos. Por ejemplo, si el proceso web Ruby usa el mandato `bundle exec thin start`, entonces una migración de la base de datos debería usar `bundle exec rake db:migrate`. De la misma manera, un programa Python que usa Virtualenv debería usar `bin/python` para ejecutar tanto el servidor web Tornado como cualquier proceso de administración `manage.py`. + +"Twelve-factor" recomienda encarecidamente lenguajes que proporcionan una consola del tipo REPL, ya que facilitan ejecutar scripts de un solo uso. En un despliegue local, los desarrolladores invocarán procesos de administración de un solo uso con un mandato directo en la consola dentro del directorio de la aplicación. En un despliegue de producción, los desarrolladores pueden usar ssh u otro mecanismo de ejecución de mandatos remoto proporcionado por el entorno de ejecución del despliegue para ejecutar dicho proceso. From c911035532833405dc2c8fc0cfe82b0057cad103 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Sun, 22 Nov 2015 23:46:32 +0100 Subject: [PATCH 211/472] First review for concurrency --- content/es/concurrency.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/es/concurrency.md b/content/es/concurrency.md index 6d078a75a..3771f8a1c 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Concurrencia ### Escalar mediante el modelo de procesos -Cualquier programa de ordenador, una vez en ejecución, se representa en memoria por uno o más procesos. Las aplicaciones web usan diferentes formas de ejecución de procesos. Por ejemplo, los procesos PHP se ejecutan como procesos pesados, hijos del proceso Apache, que se iniciando cuando el volumen de peticiones lo requiere. Los procesos Java siguen una aproximación distinta, la Máquina Virtual de Java (JVM) proporciona una gran cantidad de procesos que reservan un gran volumen de recursos del sistema (CPU y memoria) al inicio, gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución pasan practicamente inadvertidos para los desarrolladores de la aplicación. +Cualquier programa de ordenador, cuando se ejecuta, se encuentra representado en memoria por uno o más procesos. Las aplicaciones web se ejecutan de diferentes maneras si nos fijamos en el modelo de procesos que usan. Por ejemplo, los procesos PHP se ejecutan como procesos pesados (o simplemente procesos), hijos del proceso Apache, que se inician cuando es necesario debido a la cantidad de peticiones. Los procesos Java funcionan de forma distinta, la Máquina Virtual de Java (JVM) proporciona un conjunto de procesos que reservan una gran cantidad de recursos del sistema (CPU y memoria) al inicio, gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución son prácticamente transparentes para los desarrolladores de la aplicación. -![La extensión se ve representada por los procesos en ejecución, la diversidad de carga de trabajo se ve representada por los distintos tipos de procesos.](/images/process-types.png) +![La escalabilidad está representada por el número de procesos en ejecución, mientras que la diversidad de carga de trabajo lo está por los tipos de procesos.](/images/process-types.png) -**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" toman ejemplo de [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede planificar su aplicación para manejar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso pesado y las tareas con mucha carga de trabajo se pueden procesar con procesos ligeros (threads). +**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede planificar su aplicación para manejar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. -Esto no limita a los procesos a gestionar su propia división interna, mediante threads en la ejecución de la máquina virtual o el modelo asíncrono o por eventos de herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Pero una maquina virtual individual solo puede crecer hasta cierto tamaño, así que la aplicación debe ser capaz de dividirse en multiples procesos que se ejecuten en múltiples máquinas físicas. +Esto no exime a los procesos de gestionar su propia división interna, mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual individual tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. -El modelo de procesos deja ver todo su potencial cuando llega la hora de escalar. La [naturaleza share-nothing, divisible horizontalmente de los procesos de las aplicaciones "twelve-factor"](./processes) se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *process formation*. +El modelo de procesos demuestra todo su potencial cuando llega el momento de escalar. La [naturaleza "share-nothing", divide horizontalmente los procesos de las aplicaciones "twelve-factor"](./processes) y se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *juego de procesos*. -Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) o escribir ficheros de tipo PID. En su lugar, se debe confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [el historial](./logs), responder a procesos que terminan inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. +Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) o escribir ficheros de tipo PID. En su lugar, se debería confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [los historiales](./logs), responder a procesos que terminen inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. From 3c20f4e82cc4f5e137f3d80bcf720dc21963623d Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Sun, 22 Nov 2015 23:46:48 +0100 Subject: [PATCH 212/472] First review for processes --- content/es/processes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/es/processes.md b/content/es/processes.md index 2589ee5d7..2c349e82d 100644 --- a/content/es/processes.md +++ b/content/es/processes.md @@ -3,12 +3,12 @@ La aplicación se ejecuta en entornos de ejecución como uno o más *procesos*. -El caso más sencillo se daría cuando el código es un script independiente, el entorno de ejecución es un portátil de un desarrollador, el compilador o interprete correspondiente del lenguaje está instalado, y el proceso se lanza mediante la linea de mandatos (por ejemplo, `python my_script.py`). El otro extremo sería un despliegue en producción de una aplicación compleja que puede usar muchos [tipos de procesos, instanciados en cero o más procesos en ejecución](./concurrency). +En el caso más sencillo podemos considerar que el código es un script independiente, el entorno de ejecución es un portátil de un desarrollador, el compilador o interprete correspondiente del lenguaje está instalado, y el proceso se lanza mediante la linea de mandatos (por ejemplo, `python my_script.py`). En el otro extremo podemos encontrar el caso de un despliegue en producción de una aplicación compleja que puede usar muchos [tipos de procesos, instanciados en cero o más procesos en ejecución](./concurrency). -**Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier dato que necesite persistencia debe ser almacenado en un [servicio de respaldo](./backing-services) con estado, que suele ser una base de datos. +**Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier dato que necesite persistencia debe ser almacenado en un [servicio externo](./backing-services) con estado, que suele ser una base de datos. -El espacio de memoria o el sistema de ficheros de un proceso se puede usar como una cache temporal de un solo uso. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca dan por sentado que cualquier cosa cacheada en memoria o en el disco estará disponible en el futuro en una petición o en un proceso -- con muchos procesos de cada tipo corriendo, existe una alta probabilidad de que se sirva una petición por otro proceso en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (activado por un despliegue del código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). +El espacio de memoria o el sistema de ficheros de un proceso se puede usar como una cache temporal de un solo uso. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca presuponen que cualquier cosa cacheada en memoria o en el disco estará disponible en el futuro al realizar una petición o en un proceso -- con muchos procesos de cada tipo corriendo, existe una alta probabilidad de que se sirva una petición por otro proceso distinto en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (activado por un despliegue del código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). -Los empaquetadores de activos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" se prefiere hacer esta compilación durante la [fase de construcción](./build-release-run), como el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), en lugar de en tiempo de ejecución. +Los compresores de estáticos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" es preferible realizar esta compilación durante la [fase de construcción](./build-release-run), como con el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), en lugar de en tiempo de ejecución. Algunos sistemas webs dependen de ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- esto es, cacheando la información de la sesión de usuario en la memoria del proceso de la aplicación y esperando peticiones futuras del mismo visitante para redirigirle al mismo proceso. Las sesiones sticky son una violación de "twelve-factor" y nunca deverían usarse o depender de ellas. Los datos del estado de la sesion es un buen candidato para un almacen de información que ofrece mecanismos de tiempo de expiración, como [Memcached](http://memcached.org/) o [Redis](http://redis.io/). From 33e9e6c2803e45f281e2edeba49601d6d3e2e766 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 26 Nov 2015 00:03:18 +0100 Subject: [PATCH 213/472] First review for intro --- content/es/intro.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/es/intro.md b/content/es/intro.md index 89cb9d1f5..4d18d31d2 100644 --- a/content/es/intro.md +++ b/content/es/intro.md @@ -1,12 +1,12 @@ Introducción ============ -En la época actual, el software se distribuye comunmente como un servicio: se le llama *web apps*, o *software as a service* (SaaS). "The twelve-factor app" es una metodología para construir aplicaciones SaaS que: +En estos tiempos, el software se está distribuyendo como un servicio: se le denomina *web apps*, o *software as a service* (SaaS). "The twelve-factor app" es una metodología para construir aplicaciones SaaS que: -* Usan formatos **declarativos** para la automatización de la configuración, para minimizar el tiempo y el coste para los nuevos desarrolladores que se unan al proyecto; -* Tienen un **contrato claro** con el sistema operativo sobre el que trabaja, ofreciendo la **máxima portabilidad** entre los entornos de ejecución; +* Usan formatos **declarativos** para la automatización de la configuración, para minimizar el tiempo y el coste que supone que nuevos desarrolladores se unan al proyecto; +* Tienen un **contrato claro** con el sistema operativo sobre el que trabajan, ofreciendo la **máxima portabilidad** entre los diferentes entornos de ejecución; * Son apropiadas para **desplegarse** en modernas **plataformas en la nube**, obviando la necesidad de servidores y administración de sistemas; -* **Minimiza la divergencia** entre desarrollo y producción, posibilitando el **despliegue continuo** para conseguir la máxima agilidad; -* Y puede **escalar** sin cambios significativos para herramientas, arquitectura o practicas de desarrollo. +* **Minimizan las diferencias** entre los entornos de desarrollo y producción, posibilitando un **despliegue continuo** para conseguir la máxima agilidad; +* Y pueden **escalar** sin cambios significativos para las herramientas, la arquitectura o las prácticas de desarrollo. -"The twelve-factor methodology" puede ser aplicado a aplicaciones escritas en cualquier lenguaje de programación, y cualquier combinación de servicios de soporte (bases de datos, colas, memoria cache, etc). +La metodología "twelve-factor" puede ser aplicada a aplicaciones escritas en cualquier lenguaje de programación, y cualquier combinación de 'backing services' (bases de datos, colas, memoria cache, etc). From 2859d8c9cb17f5ad9146fd1e820d73dede0d6642 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 26 Nov 2015 00:03:50 +0100 Subject: [PATCH 214/472] First review for background --- content/es/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/background.md b/content/es/background.md index e917ee7b0..ff9934f31 100644 --- a/content/es/background.md +++ b/content/es/background.md @@ -5,4 +5,4 @@ Los colaboradores de este documento han estado involucrados directamente en el d Este documento sintetiza toda nuestra experiencia y observaciones en una amplia variedad de aplicaciones SaaS. Es la triangulación entre practicas ideales para el desarrollo de aplicaciones, prestando especial atención a las dinámicas del crecimiento natural de una aplicación a lo largo del tiempo, las dinámicas de colaboración entre desarrolladores que trabajan en el código base de las aplicaciones y [evitando el coste de la entropía del software](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). -Nuestra motivación es elevar la concienciación de algunos problemas sistémicos que hemos visto en el desarrollo de las aplicaciones modernas, para aportar un vocabulario común que sirva para discutir estos problemas, y ofrecer un conjunto de soluciones conceptualmente robustas para esos problemas acompañados de su correspondiente terminología. El formato esta inspirado en los libros de Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* y *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +Nuestra motivación es mejorar la concienciación sobre algunos problemas sistémicos que hemos observado en el desarrollo de las aplicaciones modernas, aportar un vocabulario común que sirva para discutir sobre estos problemas, y ofrecer un conjunto de soluciones conceptualmente robustas para esos problemas acompañados de su correspondiente terminología. El formato está inspirado en los libros de Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* y *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 0528cfa7c53f8cfe69aac25a3a2643b71a59891e Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 26 Nov 2015 00:04:11 +0100 Subject: [PATCH 215/472] First review for codebase --- content/es/codebase.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/es/codebase.md b/content/es/codebase.md index d0c7a8b84..4f9c841e5 100644 --- a/content/es/codebase.md +++ b/content/es/codebase.md @@ -1,17 +1,17 @@ -## I. Base de código (Codebase) -### Una base de código sobre el que hacer control de seguimiento, muchos despliegues +## I. Código base (Codebase) +### Un código base sobre el que hacer el control de versiones y multiples despliegues -Una "twelve-factor app" se encuentra siempre en un sistema de control de versiones, tales como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). A una copia de la base de datos de seguimiento de actualización se le conoce como un *repositorio de código*, a menudo abreviado como *repo de código* o simplemente *repo*. +Una aplicación "twelve-factor" se gestiona siempre con un sistema de control de versiones, como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). A la copia de la base de datos de seguimiento de versiones se le conoce como un *repositorio de código*, a menudo abreviado como *repo de código* o simplemente *repo*. -Una *base de código* es cualquier repositorio (en un sistema de control de versiones centralizado como Subversion), o cualquier conjunto de repositorios que comparten un commit raíz (en un sistema de control de versiones descentralizado como Git). +El *código base* es cualquier repositorio (en un sistema de control de versiones centralizado como Subversion), o cualquier conjunto de repositorios que comparten un commit raíz (en un sistema de control de versiones descentralizado como Git). -![Una base de código se aplica a muchos despliegues](/images/codebase-deploys.png) +![El código base se usa en muchos despliegues](/images/codebase-deploys.png) -Siempre hay una correlación uno a uno entre la base de código y la aplicación: +Siempre hay una relación uno a uno entre el código base y la aplicación: -* Si hay muchas bases de código, no es una aplicación -- es un sistema distribuido. Cada componente en un sistema distribuido es una aplicación, y cada uno, individualmente, puede cumplir los requisitos de una "twelve-factor app". -* Multiples aplicaciones que comparten el mismo código es considerado como una violación de "twelve factor". La solución en este caso es separar el código compartido en librerías que pueden estar incluidas mediante un [gestor de dependencias](./dependencies). +* Si hay multiples códigos base, no es una aplicación -- es un sistema distribuido. Cada componente en un sistema distribuido es una aplicación, y cada uno, individualmente, puede cumplir los requisitos de una aplicación "twelve-factor". +* Multiples aplicaciones que comparten el mismo código se considera como una violación de la metodología "twelve factor". La solución en este caso es separar el código compartido en librerías que pueden estar enlazadas mediante un [gestor de dependencias](./dependencies). -Hay una sola base de código por aplicación, pero habrá muchos despliegues de la aplicación. Un *despliegue* es una instancia de la aplicación que está corriendo . Esto es normalmente un sitio en producción, y uno o más sitios de pruebas. Además, cada desarrollador tiene una copia de la aplicación corriendo en su entorno de desarrollo local, cada uno de los cuales es considerado también como un despliegue. +Existe solo un código base por aplicación, pero habrá muchos despliegues de la aplicación. Un *despliegue* es una instancia de la aplicación que está en ejecución. Ésto, normalmente, es un sitio en producción, y uno o más sitios de pruebas. Además, cada desarrollador tiene una copia de la aplicación ejecutandose en su entorno de desarrollo propio, cada uno de los cuales se considera también como un despliegue. -La base de código es el mismo en todos los despliegues, aun que pueden ser diferentes versiones en cada despliegue. Por ejemplo, un desarrollador tiene algunos commits sin desplegar en pruebas; pruebas tiene algunos commits que no están desplegados en producción. Pero todos ellos comparten la misma base de código, de este modo todos son identificables como diferentes despliegues de la misma aplicación. +El código base es el mismo en todos los despliegues, aun que pueden ser diferentes versiones en cada despliegue. Por ejemplo, un desarrollador tiene algunos commits sin desplegar en preproducción; preproducción tiene algunos commits que no están desplegados en producción. Pero todos ellos comparten el mismo código base, de este modo todos son identificables como diferentes despliegues de la misma aplicación. From 876c758ff479557be57269d635bc910eb6edcfa0 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 26 Nov 2015 00:04:25 +0100 Subject: [PATCH 216/472] First review for dependencies --- content/es/dependencies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/es/dependencies.md b/content/es/dependencies.md index 5a94b117b..f173f237c 100644 --- a/content/es/dependencies.md +++ b/content/es/dependencies.md @@ -1,12 +1,12 @@ ## II. Dependencias -### Declarar y aislar explicitamente las dependencias +### Declarar y aislar explícitamente las dependencias -La mayor parte de los lenguajes de programación ofrecen un sistema de paquetería para distribuir sus librerías de soporte, tales como [CPAN](http://www.cpan.org/) para Perl o [Rubygems](http://rubygems.org/) para Ruby. Las librerías instaladas a través de los sistemas de paquetería pueden ser instaladas en el sistema (conocido como "site packages") o limitado al directorio que contiene la aplicación (conocido como "vendoring" o "bundling"). +La mayoría de los lenguajes de programación tienen un sistema de gestión de paquetes para distribuir sus librerías, como [CPAN](http://www.cpan.org/) en Perl o [Rubygems](http://rubygems.org/) en Ruby. Las librerías instaladas a través de estos sistemas, se pueden instalar en el sistema (también conocido como "site packages") o limitarse al directorio que contiene la aplicación (también conocido como "vendoring" o "bundling"). -**Una "twelve-factor app" nunca depende de la existencia explícita de paquetes instalados en el sistema.** Declara todas las dependencias, completamente y exactamente, mediante un manifiesto de *declaración de dependencias*. Además, usa una herramienta de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implicitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita es aplicada uniformemente tanto a producción como a desarrollo. +**Una aplicación "twelve-factor" no depende nunca de la existencia explícita de paquetes instalados en el sistema.** Declara todas sus dependencias, completamente y explícitamente, mediante un manifiesto de *declaración de dependencias*. Además, usa herramientas de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implícitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita se aplica de la misma manera tanto en producción como en desarrollo. -Por ejemplo, [Gem Bundler](http://gembundler.com/) para Ruby dispone del formato `Gemfile` manifest para su declaración de dependencias y `bundle exec` para su aislamiento de dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de dependencias, y el enlace estático proporciona el aislamiento de dependencias. No importa que conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntos -- solo uno o el otro no es suficiente para satisfacer las condiciones de "twelve-factor". +Por ejemplo, el [Gem Bundler](http://gembundler.com/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa que conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". -Uno de los beneficios de la declaración de dependencias explícita es que simplifica la configuración para los desarrolladores nuevos de la aplicación. El nuevo desarrollador puede probar la base de código de la aplicación en su maquina de desarrollo, requiriendo solo tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para correr el código de la aplicación con un *mandato para construir* determinado. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. +Uno de los beneficios de la declaración explícita de dependencias es que simplifica la configuración para los nuevos desarrolladores de la aplicación. Un nuevo desarrollador puede probar el código base de la aplicación en su máquina de desarrollo, con tan solo tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para ejecutar el código de la aplicación con un *mandato para construir*. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. -Las "Twelve-factor apps" tampoco dependen de la existencia de ninguna herramienta en el sistema. Por ejemplo, ejecutar mandatos como ImageMagick o `curl`. Mientras estas herramientas pueden existir en muchos o incluso en la mayoría de los sistemas, no hay garantía de que vayan a existir en todos los sistemas donde la aplicación pueda ser ejecutada en el futuro, o si la versión encontrada en un futuro sistema será compatible con la aplicación. Si la aplicación necesita ejecutar una herramienta del sistema, esa herramienta debería estar incluida dentro de la aplicación. +Las aplicaciones "Twelve-factor" tampoco dependen de la existencia de ninguna herramienta en el sistema. Por ejemplo, ejecutar mandatos como `ImageMagick` o `curl`. Aunque estas herramientas pueden existir en muchos, o incluso en la mayoría de los sistemas, no existen garantías de que vayan a existir en todos los sistemas donde la aplicación pueda ser ejecutada en un futuro, o si las versiones futuras de un sistema serán compatibles con la aplicación. Si la aplicación necesita ejecutar una herramienta del sistema, dicha herramienta debería estar incluida dentro de la aplicación. From 9e8af62c8b389a5e157b2b22f05552061d52433c Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 27 Nov 2015 00:21:01 +0100 Subject: [PATCH 217/472] First review for config --- content/es/config.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/es/config.md b/content/es/config.md index 82c114cc5..db16931fa 100644 --- a/content/es/config.md +++ b/content/es/config.md @@ -1,22 +1,22 @@ ## III. Configuración -### Almacenar la configuración en el entorno +### Guardar la configuración en el entorno -Una configuración de una aplicación es todo lo que puede variar entre [despliegues](./codebase) (entorno de pruebas, producción, desarrollo, etc). Lo que incluye: +La configuración de una aplicación es todo lo que puede variar entre [despliegues](./codebase) (entornos de preproducción, producción, desarrollo, etc). Lo que incluye: -* Recursos que manejan la base de datos, Memcached, y otros [backing services](./backing-services) +* Recursos que manejan la base de datos, Memcached, y otros ["backing services"](./backing-services) * Credenciales para servicios externos tales como Amazon S3 o Twitter * Valores de despliegue como por ejemplo el nombre canónico del equipo para el despliegue -Las aplicaciones a veces almacenan configuraciones como constantes en el código. Lo cual conduce a una violación de la metodología "twelve-factor", que requiere una **estricta separación de la configuración y el código**. La configuración varía sustancialmente en cada despliegue, el código no. +A veces las aplicaciones guardan configuraciones como constantes en el código. Lo cual conduce a una violación de la metodología "twelve-factor", que requiere una **estricta separación de la configuración y el código**. La configuración varía sustancialmente en cada despliegue, el código no. -La prueba definitiva para saber si una aplicación tiene toda su configuración correctamente separada del código es comprobar que la base de código puede ser código abierto en cualquier momento, sin comprometer las credenciales. +La prueba de fuego para saber si una aplicación tiene toda su configuración correctamente separada del código es comprobar que el código base puede convertirse en código abierto en cualquier momento, sin comprometer las credenciales. -Hay que resaltar que la definición de "configuración" **no** incluye las configuraciones internas de la aplicación, tales como `config/routes.rb` en Rails, o como [se conectan los módulos de código](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) en [Spring](http://spring.io/). Este tipo de configuraciones no varían entre despliegues, y por eso están mejor en el código. +Hay que resaltar que la definición de "configuración" **no** incluye las configuraciones internas de la aplicación, como `config/routes.rb` en Rails, o como [se conectan los módulos](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) en [Spring](http://spring.io/). Este tipo de configuraciones no varían entre despliegues, y es por eso que están mejor en el código. -Otra estrategia de la configuración es el uso de ficheros de configuración que no se guardan en el control de versiones, como ocurre con el `config/database.yml` de Rails. Lo cual supone una gran mejora con respecto a las constantes que se guardan en el repositorio de código, pero todavía tiene debilidades: es fácil guardar un fichero de configuración en el repo por error; se tiende a desperdigar los ficheros de configuración en diferentes sitios y con distintos formatos, siendo más difícil la tarea de ver y gestionar toda la configuración en un solo sitio. Además, esos formatos tienden a ser específicos del lenguaje o del framework. +Otra estrategia de configuración es el uso de ficheros de configuración que no se guardan en el control de versiones, como ocurre con el `config/database.yml` de Rails. Lo que supone una gran mejora con respecto a las constantes que se guardan en el repositorio, aunque todavía tiene ciertas debilidades: es fácil guardar un fichero de configuración en el repo por error; se tiende a desperdigar los ficheros de configuración en diferentes sitios y con distintos formatos, siendo más difícil la tarea de ver y gestionar toda la configuración en un solo sitio. Además, el formato tiende a ser específico del lenguaje o del framework. -**Las aplicaciones "twelve-factor" almacenan la configuración en *variables de entorno*** (a menudo acortadas como *env vars* o *env*). Las variables de entorno se intercambian fácilmente entre despliegues sin modificar nada en el código; a diferencia de los ficheros de configuración, hay una pequeña posibilidad de que se guarden en el repositorio de código accidentalmente; y a diferencia de los ficheros de configuración personalizados, u otros mecanismos de configuración como los System Properties de Java, son un estándar independiente+ del lenguaje y del sistema operativo. +**Las aplicaciones "twelve-factor" almacenan la configuración en *variables de entorno*** (a menudo acortadas como *env vars* o *env*). Las variables de entorno se intercambian fácilmente entre despliegues sin modificar nada en el código; a diferencia de los ficheros de configuración, hay una pequeña posibilidad de que se guarden en el repositorio de código accidentalmente; y a diferencia de los ficheros de configuración personalizados u otros mecanismos de configuración, como los System Properties de Java, son un estándar independiente del lenguaje y del sistema operativo. -Otro aspecto de la gestión de la configuración es el agrupamiento. A veces las aplicaciones agrupan las configuraciones en grupos identificados (a menudo llamados "entornos" o "environments") identificando después despliegues específicos, como ocurre en Rails con los entornos `development`, `test`, y `production`. Este método no escala de manera limpia: según se van creando despliegues de la aplicación, se van necesitando nuevos entornos, tales como `staging` o `qa`. Según va creciendo el proyecto, los desarrolladores van añadiendo sus propios entornos especiales como `joes-staging`, resultando en una explosión combinatoria de configuraciones que hacen la gestión de despliegues de la aplicación muy frágil. +Otro aspecto de la gestión de la configuración es la clasificación. A veces, las aplicaciones clasifican las configuraciones en grupos identificados (a menudo llamados "entornos" o "environments") identificando después despliegues específicos, como ocurre en Rails con los entornos `development`, `test`, y `production`. Este método no escala de una manera limpia: según se van creando despliegues de la aplicación, se van necesitando nuevos entornos, tales como `staging` o `qa`. Según va creciendo el proyecto, los desarrolladores van añadiendo sus propios entornos especiales como `joes-staging`, resultando en una explosión de combinaciones de configuraciones que hacen muy frágil la gestión de despliegues de la aplicación. -En una aplicación "twelve-factor", las variables de entorno son controles granulares, cada una de ellas completamente ortogonales a las otras. Nunca se agrupan juntas como "entornos", pero en su lugar se gestionan independientemente para cada despliegue. Este es un modelo que escala con fluidez según la aplicación se extiende, naturalmente, en más despliegues a lo largo de su vida. +En una aplicación "twelve-factor", las variables de entorno son controles granulares, cada una de ellas completamente ortogonales a las otras. Nunca se agrupan juntas como "entornos", pero en su lugar se gestionan independientemente para cada despliegue. Este es un modelo que escala con facilidad según la aplicación se amplía, naturalmente, en más despliegues a lo largo de su vida. From ae155826e76ab42ec8ef7ab33b32b99ae1e0f3c0 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 27 Nov 2015 00:21:20 +0100 Subject: [PATCH 218/472] First review for backing services --- content/es/backing-services.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/es/backing-services.md b/content/es/backing-services.md index f5f4efc9f..64337a81b 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -1,14 +1,14 @@ -## IV. Servicios de respaldo -### Tratar los servicios de respaldo como recursos enganchables +## IV. Backing services +### Tratar los "backing services" como recursos conectables -Un *servicio de respaldo* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento normal. Como ejemplos podemos encontrar almacenes de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), servicios SMTP para email saliente (como [Postfix](http://www.postfix.org/)), y sistemas de cache (como [Memcached](http://memcached.org/)). +Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). -Los servicios de respaldo, como las bases de datos, se gestionan tradicionalmente por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden tener servicios proporcionados y gestionados por terceros. Ejemplos de ésto son los servicios SMTP (como [Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios de consumo accesibles mediante APIs (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). +Los "backing services", como las bases de datos, son gestionados, tradicionalmente, por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros. Como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). -**El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos enganchados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local podría ser cambiado por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. +**El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos conectados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local se podría cambiar por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. -Cada servicio de respaldo distinto es un *recurso*. Por ejemplo, una base de datos MySQL es un recurso; dos bases de datos MySQL (usadas para "sharding" en la capa de aplicación) les convierte en dos recursos distintos. Una aplicación "twelve factor" trata esas bases de datos como *recursos enganchados*, lo que evidencia su bajo acoplamiento al despliegue al que se unen. +Cada "backing service" distinto es un *recurso*. Por ejemplo, una base de datos MySQL es un recurso; dos bases de datos MySQL (usadas para "sharding" en la capa de aplicación) les convierte en dos recursos distintos. Una aplicación "twelve factor" trata esas bases de datos como *recursos conectados*, lo que demuestra su bajo acoplamiento al despliegue al que se unen. -Un despliegue en producción vinculado a cuatro servicios de respaldo. +Un despliegue en producción conectado a cuatro servicios de respaldo. -Los recursos se pueden enganchar y desenganchar a voluntad. Por ejemplo, si la base de datos funciona mal debido a un problema en el hardware, el administrador de la aplicación puede cambiar a un nuevo servidor de bases de datos que haya sido restaurado de un backup reciente. La base de datos actual en producción se puede desenganchar, y enganchar la nueva base de datos -- todo ésto sin ningún cambio en el código. +Los recursos se pueden conectar y desconectar a voluntad. Por ejemplo, si la base de datos funciona mal debido a un problema en el hardware, el administrador de la aplicación puede cambiar a un nuevo servidor de bases de datos que haya sido restaurado de un backup reciente. La base de datos actual de producción se puede desconectar, y conectar una nueva base de datos -- sin tener que cambiar nada en el código. From 9686deec0ba0c2598a1f8e974c6b153d81860420 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 27 Nov 2015 00:21:38 +0100 Subject: [PATCH 219/472] First review for build-release-run --- content/es/build-release-run.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/es/build-release-run.md b/content/es/build-release-run.md index 74f7e950e..1511eef65 100644 --- a/content/es/build-release-run.md +++ b/content/es/build-release-run.md @@ -1,18 +1,18 @@ ## V. Construir, distribuir, ejecutar -### Separar rigurosamente la fase de construcción de la fase de ejecución +### Separar completamente la etapa de construcción de la etapa de ejecución -La [base de código](./codebase) se transforma en un despliegue (que no es de desarrollo) mediante tres fases: +El [código base](./codebase) se transforma en un despliegue (que no es de desarrollo) al completar las siguientes tres etapas: -* La *fase de construcción* es una transformación que convierte un repositorio de código en un paquete ejecutable conocido como *construcción* (build). Usando una versión del código de un commit específico por el proceso de despliegue, la fase de construcción trae todas las [dependencias](./dependencies) y compila los binarios y las herramientas. -* En la *fase de distribución* se coje la construcción creada en la fase de construcción y se combina con la [configuración](./config) del despliegue actual. La *distribución* resultante contiene tanto la construcción como la configuración y está lista para ejecutar inmediatamente en el entorno de ejecución. -* La *fase de ejecución* (también conocida como "runtime") ejecuta la aplicación en el entorno de ejecución, lanzando un conjunto de [procesos](./processes) de la aplicación contra una distribución seleccionada. +* La *etapa de construcción* es una transformación que convierte un repositorio de código en un paquete ejecutable llamado *construcción* (una "build"). En la etapa de construcción se traen todas las [dependencias](./dependencies) y se compilan los binarios y las herramientas usando una versión concreta del código correspondiente a un commit especificado por el proceso de despliegue. +* En la *fase de distribución* se usa la construcción creada en la fase de construcción y se combina con la [configuración](./config) del despliegue actual. Por tanto, la *distribución* resultante contiene tanto la construcción como la configuración y está lista para ejecutar inmediatamente en el entorno de ejecución. +* La *fase de ejecución* (también conocida como "runtime") ejecuta la aplicación en el entorno de ejecución, lanzando un conjunto de [procesos](./processes) de una distribución concreta de la aplicación. ![El código se convierte en una construcción, que se combina con la configuración para crear una distribución.](/images/release.png) -**Las aplicaciones "twelve-factor" hacen una separación rigurosa entre las fases de construcción, de distribución y de ejecución.** Por ejemplo, es imposible hacer cambios en el código en la fase de ejecución, porque no hay una manera de propagar dichos cambios de vuelta a la fase de construcción. +**Las aplicaciones "twelve-factor" hacen una separación completa de las fases de construcción, de distribución y de ejecución.** Por ejemplo, es imposible hacer cambios en el código en la fase de ejecución, porque no hay una manera de propagar dichos cambios a la fase de construcción. -Las herramientas de despliegue ofrecen normalmente herramientas de gestión de distribuciones (releases), especialmente la habilidad de volver a una versión anteriormente distribuida. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. +Las herramientas de despliegue ofrecen, normalmente, herramientas de gestión de distribuciones (releases), es especialmente útil la habilidad de volver a una versión anteriormente distribuida. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. -Cada distribución siempre debería tener un identificador único de distribución, como por ejemplo la marca de tiempo (timestamp) de la distribución (`2011-04-06-20:32:17`) o un número incremental (como `v100`). Las distribuciones son como los libros de contabilidad al que solo se le pueden agregar registros y no puede ser modificada una vez es creada. Cualquier cambio debe crear una nueva distribución. +Cada distribución debería tener siempre un identificador único de distribución, como por ejemplo una marca de tiempo (timestamp) de la distribución (`2011-04-06-20:32:17`) o un número incremental (como `v100`). Las distribuciones son como un libro de contabilidad, al que solo se le pueden agregar registros y no pueden ser modificados una vez son creados. Cualquier cambio debe crear una nueva distribución. -Las construcciones son iniciados por los desarrolladores de la aplicación cuando el nuevo código se despliega. La fase de ejecución, en cambio, puede suceder automáticamente por ejemplo cuando se reinicia un servidor, o cuando un proceso termina inesperadamente siendo reiniciado por el gestor de procesos. Por tanto, la fase de ejecución debería mantenerse lo más estático como sea posible, ya que evita que una aplicación en ejecución pueda causar una interrupción en mitad de la noche cuando no hay desarrolladores a mano. La fase de construcción puede ser más compleja, ya que los errores están siempre en la mente de un desarrollador que está dirigiendo el despliegue. +Las construcciones son iniciadas por los desarrolladores de la aplicación cuando se despliega nuevo código. La fase de ejecución, en cambio, puede suceder automáticamente, por ejemplo, cuando se reinicia un servidor, o cuando un proceso termina inesperadamente siendo reiniciado por el gestor de procesos. Por tanto, la fase de ejecución debería mantenerse lo más estática que sea posible, ya que evita que una aplicación en ejecución pueda causar una interrupción inesperada, en mitad de la noche, cuando no hay desarrolladores a mano. La fase de construcción puede ser más compleja, ya que los errores siempre están en la mente de un desarrollador que dirige un despliegue. From f9b5ff73d6bb188368a871505c7422665fa91eeb Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 00:05:19 +0100 Subject: [PATCH 220/472] First review for processes --- content/es/processes.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/es/processes.md b/content/es/processes.md index 2c349e82d..40ef34e8f 100644 --- a/content/es/processes.md +++ b/content/es/processes.md @@ -1,14 +1,14 @@ ## VI. Procesos ### Ejecutar la aplicación como uno o más procesos sin estado -La aplicación se ejecuta en entornos de ejecución como uno o más *procesos*. +La aplicación se ejecuta como uno o más *procesos* en el entorno de ejecución. -En el caso más sencillo podemos considerar que el código es un script independiente, el entorno de ejecución es un portátil de un desarrollador, el compilador o interprete correspondiente del lenguaje está instalado, y el proceso se lanza mediante la linea de mandatos (por ejemplo, `python my_script.py`). En el otro extremo podemos encontrar el caso de un despliegue en producción de una aplicación compleja que puede usar muchos [tipos de procesos, instanciados en cero o más procesos en ejecución](./concurrency). +El caso más sencillo que podemos plantear es que el código es un script independiente, el entorno de ejecución es un portátil de un desarrollador, el compilador o interprete correspondiente del lenguaje está instalado, y el proceso se lanza mediante la linea de mandatos (por ejemplo, `python my_script.py`). Por otro lado podemos encontrar el caso de un despliegue en producción de una aplicación compleja que puede usar muchos [tipos de procesos, instanciados como cero o más procesos en ejecución](./concurrency). -**Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier dato que necesite persistencia debe ser almacenado en un [servicio externo](./backing-services) con estado, que suele ser una base de datos. +**Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier información que necesite persistencia se debe almacenar en un ['backing service'](./backing-services) con estado, habitualmente una base de datos. -El espacio de memoria o el sistema de ficheros de un proceso se puede usar como una cache temporal de un solo uso. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca presuponen que cualquier cosa cacheada en memoria o en el disco estará disponible en el futuro al realizar una petición o en un proceso -- con muchos procesos de cada tipo corriendo, existe una alta probabilidad de que se sirva una petición por otro proceso distinto en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (activado por un despliegue del código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). +Tanto el espacio de memoria de un proceso como el sistema de ficheros se pueden usar como si fueran una cache temporal para hacer transacciones. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca dan por hecho que cualquier cosa cacheada en memoria o en el disco vaya a estar disponible al realizar una petición al ejecutar diferentes procesos. Con muchos procesos de cada tipo ejecutandose al mismo tiempo, existe una gran probabilidad de que otro proceso distinto sirva una petición en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (provocado por el despliegue de código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). -Los compresores de estáticos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" es preferible realizar esta compilación durante la [fase de construcción](./build-release-run), como con el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), en lugar de en tiempo de ejecución. +Los compresores de estáticos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" es preferible realizar esta compilación durante la [fase de construcción](./build-release-run), como con el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), que en tiempo de ejecución. -Algunos sistemas webs dependen de ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- esto es, cacheando la información de la sesión de usuario en la memoria del proceso de la aplicación y esperando peticiones futuras del mismo visitante para redirigirle al mismo proceso. Las sesiones sticky son una violación de "twelve-factor" y nunca deverían usarse o depender de ellas. Los datos del estado de la sesion es un buen candidato para un almacen de información que ofrece mecanismos de tiempo de expiración, como [Memcached](http://memcached.org/) o [Redis](http://redis.io/). +Algunos sistemas webs dependen de ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence), esto quiere decir que cachean la información de la sesión de usuario en la memoria del proceso de la aplicación y esperan peticiones futuras del mismo visitante para redirigirle al mismo proceso. Las "sticky sessions" son una violación de "twelve-factor" y no deberían usarse nunca ni depender de ellas. La información del estado de la sesión es un candidato perfecto para almacenes de información que ofrecen mecanismos de tiempo de expiración, como [Memcached](http://memcached.org/) o [Redis](http://redis.io/). From a5579879ea47c9617655ca8d785ca84862a9e203 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 21:59:12 +0100 Subject: [PATCH 221/472] First review for port-binding --- content/es/port-binding.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/es/port-binding.md b/content/es/port-binding.md index 872add64d..d90ea9ba2 100644 --- a/content/es/port-binding.md +++ b/content/es/port-binding.md @@ -1,14 +1,14 @@ ## VII. Asignación de puertos ### Publicar servicios mediante asignación de puertos -Las aplicaciones web a menudo se ejecutan mediante contenedores web. Por ejemplo, las aplicaciones PHP se pueden ejecutar como módulos del [HTTPD de Apache](http://httpd.apache.org/), y las aplicaciones Java en [Tomcat](http://tomcat.apache.org/). +A menudo, las aplicaciones web, se ejecutan mediante contenedores web. Por ejemplo, las aplicaciones de PHP se suelen ejecutar como módulos del [HTTPD de Apache](http://httpd.apache.org/), y las aplicaciones Java en [Tomcat](http://tomcat.apache.org/). **Las aplicaciones "twelve factor" son completamente auto-contenidas** y no dependen de un servidor web en ejecución para crear un servicio web público. Una aplicación web **usa HTTP como un servicio al que se le asigna un puerto**, y escucha las peticiones que recibe por dicho puerto. -En un entorno local de desarrollo, el desarrollador usa una URL del servicio como `http://localhost:5000/` para acceder al servicio que ofrece una aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una ruta pública se redirija hacia el proceso web que tiene asignado en su puerto correspondiente. +En los entornos de desarrollo, los desarrolladores usan una URL del servicio (por ejemplo `http://localhost:5000/`), para acceder al servicio que ofrece la aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una dirección pública se redirijan hacia el proceso web que tiene asignado su puerto correspondiente. -Normalmente se implementa usando una [declaracion de dependencias](./dependencies) para incluir librerías en las aplicaciones web, como en [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Esto ocurre completamente en el *espacio del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga a un puerto a servir peticiones. +Ésto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Ésto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. -HTTP no es el único servicio que usa la asignación de puertos. Lo cierto es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigne un puerto y que espere peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). +HTTP no es el único servicio que usa asignación de puertos. La verdad, es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigna un puerto y queda a la espera de peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). -También es cierto que la aproximación de asignación de puertos ofrece la posibilidad de que una aplicación puede llegar a ser un [servicio de respaldo](./backing-services) para otra aplicación, usando la URL de la aplicación de respaldo como un recurso declarado en la [configuración](./config) de la aplicación consumidora. +También es cierto que la aproximación de asignación de puertos ofrece la posibilidad de que una aplicación pueda llegar a ser un ["backing service"](./backing-services) para otra aplicación, usando la URL de la aplicación correspondiente como un recurso declarado en la [configuración](./config) de la aplicación que consume este "backing service". From afeb05de5be4bc9a7c1349ce8317b5dd8fa529a4 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 22:27:07 +0100 Subject: [PATCH 222/472] Firs review for concurrency --- content/es/concurrency.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/es/concurrency.md b/content/es/concurrency.md index 3771f8a1c..d1b020371 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Concurrencia ### Escalar mediante el modelo de procesos -Cualquier programa de ordenador, cuando se ejecuta, se encuentra representado en memoria por uno o más procesos. Las aplicaciones web se ejecutan de diferentes maneras si nos fijamos en el modelo de procesos que usan. Por ejemplo, los procesos PHP se ejecutan como procesos pesados (o simplemente procesos), hijos del proceso Apache, que se inician cuando es necesario debido a la cantidad de peticiones. Los procesos Java funcionan de forma distinta, la Máquina Virtual de Java (JVM) proporciona un conjunto de procesos que reservan una gran cantidad de recursos del sistema (CPU y memoria) al inicio, gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución son prácticamente transparentes para los desarrolladores de la aplicación. +Todo programa de ordenador, al ejecutarse, se encuentra representado en memoria por uno o más procesos. Las aplicaciones web se pueden ejecutar de diferentes formas desde el punto de vista del modelo de procesos que usan. Por ejemplo, los procesos PHP se ejecutan como procesos pesados (o simplemente procesos), hijos del proceso Apache, estos procesos se crean bajo demanda debido a la cantidad de peticiones cuando es necesario. Los procesos Java funcionan de forma distinta, la Máquina Virtual de Java (JVM) proporciona un conjunto de procesos que reservan al principio una gran cantidad de recursos del sistema (CPU y memoria), gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución son prácticamente transparentes para los desarrolladores de la aplicación. ![La escalabilidad está representada por el número de procesos en ejecución, mientras que la diversidad de carga de trabajo lo está por los tipos de procesos.](/images/process-types.png) -**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede planificar su aplicación para manejar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. +**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede distribuir la ejecución de su aplicación para gestionar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. -Esto no exime a los procesos de gestionar su propia división interna, mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual individual tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. +Esto no exime a los procesos de gestionar su propia división interna mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual aislada tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. -El modelo de procesos demuestra todo su potencial cuando llega el momento de escalar. La [naturaleza "share-nothing", divide horizontalmente los procesos de las aplicaciones "twelve-factor"](./processes) y se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *juego de procesos*. +El modelo de procesos muestra todo su potencial cuando llega el momento de escalar. La [naturaleza "share-nothing", divide horizontalmente los procesos de las aplicaciones "twelve-factor"](./processes) y se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *juego de procesos*. -Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) o escribir ficheros de tipo PID. En su lugar, se debería confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [los historiales](./logs), responder a procesos que terminen inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. +Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) ni escribir ficheros de tipo PID. En su lugar, se debería confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [los historiales](./logs), responder a procesos que terminen inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. From cb552ccaaa9b22b078309b7a6541b89b028c87e8 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 22:27:24 +0100 Subject: [PATCH 223/472] First review for disposability --- content/es/disposability.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/es/disposability.md b/content/es/disposability.md index 947016f5d..ea276ae50 100644 --- a/content/es/disposability.md +++ b/content/es/disposability.md @@ -1,12 +1,12 @@ ## IX. Disponibilidad -### Hacer el sistema más robusto mediante inicios rápidos y finalizaciones seguras +### Hacer el sistema más robusto intentando conseguir inicios rápidos y finalizaciones seguras -**Los [procesos](./processes) de las aplicaciones "twelve-factor" son *deshechables*, lo que significa que pueden iniciarse o finalizarse en el momento que sea necesario.** Esto permite un escalado rápido y flexible, un despliegue rápido del [código](./codebase) y de los cambios de las [configuraciones](./config), y despliegues más robustos en producción. +**Los [procesos](./processes) de las aplicaciones "twelve-factor" están *disponibles*, lo que significa que pueden iniciarse o finalizarse en el momento que sea necesario.** Esto permite un escalado rápido y flexible, un despliegue rápido del [código](./codebase) y de los cambios de las [configuraciones](./config), y despliegues más robustos en producción. -Los procesos deberían luchar por **minimizar el tiempo de inicio**. En el mejor de los casos, un proceso necesita unos pocos segundos desde que se ejecuta el mandato hasta que se inicia y está preparado para recibir peticiones o trabajos. Mejorar el tiempo de inicio proporciona una mayor agilidad para el proceso de [distribución](./build-release-run) y escalado; y lo hace más robusto, porque el gestor de procesos puede mover procesos más fácilmente entre máquinas físicas con garantías. +Los procesos deberían intentar conseguir **minimizar el tiempo de arranque**. En el mejor de los casos, un proceso necesita unos pocos segundos desde que se ejecuta el mandato hasta que arranca y está preparado para recibir peticiones o trabajos. Mejorar el tiempo de arranque proporciona mayor agilidad en el proceso de [distribución](./build-release-run) y escalado; y lo hace más robusto, porque el gestor de procesos puede mover procesos de forma segura entre máquinas físicas más fácilmente. -Los procesos **paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implicitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos), y en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. +Los procesos **se paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implícitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos), y en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. -Para un trabajador (o "worker") finalizar de manera segura se consigue devolviendo el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implicitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). +Para un trabajador (o "worker") finalizar de manera segura se consigue devolviendo el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implícitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). -Los procesos deberían ser **robustos contra paradas inesperadas**, como en el caso de un fallo a nivel hardware. Aunque es un caso más raro que una parada mediante la señal `SIGTERM`, es posible que ocurra. Lo recomendable es usar un sistema de colas robusto, como puede ser Beanstalkd, que devuelve los trabajos a su cola cuando los clientes se desconectan o expira su tiempo de espera ("timeout"). En cualquier caso, una aplicación "twelve-factor" es una arquitectura que trata finalizaciones inesperadas y peligrosas. El [diseño Crash-only](http://lwn.net/Articles/191059/) lleva este concepto a su [conclusión lógica](http://docs.couchdb.org/en/latest/intro/overview.html). +Los procesos deberían estar **preparados contra finalizaciones inesperadas**, como en el caso de un fallo a nivel hardware. Aunque es un caso más raro que una finalización mediante la señal `SIGTERM`, se puede dar el caso. Lo recomendable es usar un sistema de colas robusto, como Beanstalkd, que devuelve los trabajos a su cola cuando los clientes se desconectan o expira su tiempo de espera ("timeout"). En cualquier caso, una aplicación "twelve-factor" es una arquitectura que trata finalizaciones inesperadas y peligrosas. El [diseño Crash-only](http://lwn.net/Articles/191059/) lleva este concepto a su [conclusión lógica](http://docs.couchdb.org/en/latest/intro/overview.html). From f857bc57a5e122c656fe74b4e9d7a4738f0a6564 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 22:40:47 +0100 Subject: [PATCH 224/472] First review for dev-prod-parity --- content/es/dev-prod-parity.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md index 952a4a560..c6bb9fc82 100644 --- a/content/es/dev-prod-parity.md +++ b/content/es/dev-prod-parity.md @@ -1,7 +1,7 @@ -## X. Paridad entre desarrollo y producción +## X. Igualdad entre desarrollo y producción ### Mantener desarrollo, preproducción y producción tan parecidos como sea posible -Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo (donde un desarrollador puede editar en vivo en un [despliegue](./codebase) local de la aplicación) y producción (un despliegue en el que la aplicación está en ejecución disponible para los usuarios). Estas diferencias se pueden clasificar en tres tipos: +Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo (donde un desarrollador puede editar en vivo en un [despliegue](./codebase) local de la aplicación) y producción (un despliegue en el que la aplicación está en ejecución disponible para que lo usen los usuarios). Estas diferencias se pueden clasificar en tres tipos: * **Diferencias de tiempo**: Un desarrollador puede estar trabajando en un código durante días, semanas o incluso meses antes de que llegue a producción. * **Diferencias de personal**: Los desarrolladores escriben el código y los ingenieros de operaciones lo despliegan. @@ -10,7 +10,7 @@ Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo ** Las aplicaciones "twelve-factor" están diseñadas para hacer [despliegues continuos](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) que reducen las diferencias entre los entornos de desarrollo y producción.** Teniendo en cuenta las tres diferencias descritas anteriormente: * Reducir las diferencias de tiempo: Un desarrollador puede escribir código y tenerlo desplegado en tan solo unas horas o incluso, minutos más tarde. -* Reducir las diferencias de personal: Los desarrolladores que escriben el código estás muy involucrados en el despliegue y observan su comportamiento en producción. +* Reducir las diferencias de personal: Los desarrolladores que escriben el código están muy involucrados en el despliegue y observan su comportamiento en producción. * Reducir las diferencias de herramientas: tratar de hacer que desarrollo y producción sean tan parecidos como sea posible. Resumiendo lo anterior en una tabla: @@ -38,7 +38,7 @@ Resumiendo lo anterior en una tabla: -Los [servicios de respaldo](./backing-services), como la base de datos de la aplicación, el sistema de colas, o la cache, es donde la igualdad en los entornos de desarrollo y producción es importante. Muchos lenguajes ofrecen librerías en las que se simplifica el acceso a los servicios de respaldo, incluidos *adaptadores* para diferentes tipos de servicios. Se pueden observar algunos ejemplos en la siguiente tabla. +Los ["backing services"](./backing-services), como la base de datos de la aplicación, el sistema de colas, o la cache, es donde la igualdad en los entornos de desarrollo y producción es importante. Muchos lenguajes ofrecen librerías en las que se simplifica el acceso a los servicios de respaldo, incluidos *adaptadores* para diferentes tipos de servicios. Se pueden observar algunos ejemplos en la siguiente tabla. @@ -67,10 +67,10 @@ Los [servicios de respaldo](./backing-services), como la base de datos de la apl
-Los desarrolladores a veces caen en la tentación de usar servicios de respaldo ligeros en sus entornos locales, mientras que en producción se usan los más serios y robustos. Por ejemplo, usando SQLite localmente y PostgreSQL en producción; o memoria local para la cache en desarrollo y Memcached en producción. +Los desarrolladores, a veces, caen en la tentación de usar "backing services" ligeros en sus entornos de desarrollo, mientras que en producción se usan los más serios y robustos. Por ejemplo, se usa SQLite en desarrollo y PostgreSQL en producción; o memoria local para la cache en desarrollo y Memcached en producción. -**El desarrollador "twelve-factor" resiste sus deseos de usar diferentes servicios de respaldo en desarrollo y producción**, incluso cuando los adaptadores teoricamente abstractos están lejos de cualquier diferencia en servicios de respaldo. Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que salen de la nada, causando que el código que funciona y pasa los test en desarrollo o en preproducción, fallen en producción. Este tipo de errores provocan desacuerdos que desincentivan el despliegue continuo. El coste de estos desacuerdos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se se hace balance del total del tiempo de vida de una aplicación. +**Un desarrollador "twelve-factor" no cae en la tentación de usar diferentes "backing services" en desarrollo y producción**, incluso cuando los adaptadores teóricamente abstractos están lejos de cualquier diferencia en "backing services". Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que surgen de la nada, causando que el código que funciona y pasa los test en desarrollo o en preproducción, fallen en producción. Este tipo de errores provocan conflictos que desincentivan la filosofía del despliegue continuo. El coste de estos conflictos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se hace balance del total de tiempo de vida de una aplicación. -Los servicios ligeros locales son menos atractivos que antes. Los servicios de respaldo modernos como Memcached, PostgreSQL, y RabbitMQ no son dificiles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinados con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas son bajos comparados con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. +Los servicios ligeros locales son menos atractivos que antes. Los "backing services" modernos como Memcached, PostgreSQL, y RabbitMQ no son dificiles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinados con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas son bajos comparados con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. -Los adaptadores de servicios de respaldo todavía son de gran utilidad, porque hacen que cambiar de servicios de respaldo sea relativamente poco doloroso. No obstante, todos los despliegues de una aplicación (entornos de desarrollo, preproducción y producción) deberían usar el mismo tipo y version de cada uno de los servicios de respaldo. +Los adaptadores de los "backing services" todavía son de gran utilidad, porque hacen que cambiar de unos a otros sea un trámite relativamente poco doloroso. No obstante, todos los despliegues de una aplicación (en entornos de desarrollo, preproducción y producción) deberían usar el mismo tipo y versión de cada uno de los "backing services". From 1d2b74929a388b901e5aa7768be16662fdc7688f Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Tue, 1 Dec 2015 22:46:46 +0100 Subject: [PATCH 225/472] Minor fix in backing-services --- content/es/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/backing-services.md b/content/es/backing-services.md index 64337a81b..7c3375881 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -1,5 +1,5 @@ ## IV. Backing services -### Tratar los "backing services" como recursos conectables +### Tratar a los "backing services" como recursos conectables Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). From 9d37d1766f56b8e6f897433b2f8a8b9fecf44fc0 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 3 Dec 2015 00:10:01 +0100 Subject: [PATCH 226/472] First review for logs --- content/es/logs.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/content/es/logs.md b/content/es/logs.md index 4e9c58174..9338c2bcf 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -3,16 +3,14 @@ Los *historiales* proporcionan visibilidad al comportamiento de la ejecución de la aplicación. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico"); pero este es solo un posible formato de salida. -Un historial es un resumen de un [flujos](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/), eventos capturados y ordenados según su momento de ejecución del flujo de salida de todos los procesos en ejecución y los servicios de respaldo. +Los historiales son la [transmisión](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de un conjunto de eventos ordenados y capturados de la salida de todos los procesos en ejecución y de los "backing services". En bruto, los historiales suelen estar en formato texto y tienen un evento por linea (aunque las trazas de excepciones suelen estar en varias lineas). Los historiales no tienen un principio y un final fijo, sino que fluyen continuamente mientras la aplicación está en funcionamiento. - time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +**Una aplicación "twelve-factor" nunca se preocupa del direccionamiento o el almacenamiento de sus transmisiones de salida.** No debería intentar escribir o gestionar ficheros de historial. En su lugar, cada proceso en ejecución escribe sus eventos a la `salida estándar` (o `stdout`). Durante el desarrollo, los desarrolladores verán el flujo en su terminal para observar el comportamiento de la aplicación. -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +En despliegues de preproducción y producción, cada transmision de proceso será capturado por el entorno de ejecución, siendo capturados junto con todos los otros flujos de la aplicación, y redirigido a uno o más destinos finales para ser revisados y archivados. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales, (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd) se usan con este objetivo. -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. +Las transmisiones de eventos para una aplicación pueden ser redirigidos a un fichero u observados en tiempo real mediante un "tail" en un terminal. Most significantly, la transmision se puede enviar a un sistema de analisis e indexado como [Splunk](http://www.splunk.com/), o a un sistema de almacenamiendo de datos de proposito general como [Hadoop/Hive](http://hive.apache.org/). Estos sistemas se tienen en cuenta por el gran poder y la flexibilidad para inspeccionar el comportamiento de la aplicación a lo largo del tiempo, incluyendo: -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: - -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). +* Encontrar eventos específicos del pasado. +* Gráficas de tendencia a gran escala (como las peticiones por minuto). +* Activación de alertas de acuerdo con heurísticas definidas por el usuario (como una alerta cuando la cantidad de errores por minuto sobrepasa un cierto limite). From 6bd104065a84ff0651f22ef1fd0569c62ffb28f7 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 3 Dec 2015 00:12:44 +0100 Subject: [PATCH 227/472] First review for toc --- content/es/toc.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/content/es/toc.md b/content/es/toc.md index 6a169dc06..969a24381 100644 --- a/content/es/toc.md +++ b/content/es/toc.md @@ -1,20 +1,20 @@ Twelve Factors ============== -## [I. Repositorio](./codebase) -### Un repositorio para hacer el seguimiento del control de versiones, multiples despliegues +## [I. Código base (Codebase)](./codebase) +### Un código base sobre el que hacer el control de versiones y multiples despliegues ## [II. Dependencias](./dependencies) -### Dependencias declaradas explicitamente y aisladas +### Declarar y aislar explícitamente las dependencias ## [III. Configuraciones](./config) -### Almacenar la configuración en el entorno +### Guardar la configuración en el entorno -## [IV. Servicios de respaldo](./backing-services) -### Tratar a los servicios de respaldo como piezas intercambiables +## [IV. Backing services](./backing-services) +### Tratar a los "backing services" como recursos conectables ## [V. Construir, desplegar, ejecutar](./build-release-run) -### Las fases de construcción y ejecución totalmente separadas +### Separar completamente la etapa de construcción de la etapa de ejecución ## [VI. Procesos](./processes) ### Ejecutar la aplicación como uno o más procesos sin estado @@ -26,14 +26,13 @@ Twelve Factors ### Escalar mediante el modelo de procesos ## [IX. Disponibilidad](./disposability) -### Maximizar la solidez con inicios rápidos y finalizaciones seguras +### Hacer el sistema más robusto intentando conseguir inicios rápidos y finalizaciones seguras ## [X. Paridad en desarrollo y producción](./dev-prod-parity) ### Mantener desarrollo, preproducción y producción tan parecidos como sea posible ## [XI. Historiales](./logs) -### Tratar los historiales como flujos de eventos +### Tratar los historiales como una transmisión de eventos ## [XII. Administración de procesos](./admin-processes) -### Ejecutar tareas de administración/gestión como procesos -Run admin/management tasks as one-off processes +### Ejecutar las tareas de gestión/administración como procesos de un solo uso From a4eae15ea5b3a7ba8597be2eb748727b3024630a Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Thu, 3 Dec 2015 00:16:11 +0100 Subject: [PATCH 228/472] Update logs subtitle for Spanish translation --- content/es/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/logs.md b/content/es/logs.md index 9338c2bcf..1dbf5b399 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -1,5 +1,5 @@ ## XI. Historiales -### Tratar los historiales como un flujo de eventos +### Tratar los historiales como una transmisión de eventos Los *historiales* proporcionan visibilidad al comportamiento de la ejecución de la aplicación. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico"); pero este es solo un posible formato de salida. From 274522025da7132e3ca5592cdde6f0a2af8f872f Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 4 Dec 2015 18:51:32 +0100 Subject: [PATCH 229/472] First review for admin-processes --- content/es/admin-processes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/es/admin-processes.md b/content/es/admin-processes.md index eb3312348..f834394c6 100644 --- a/content/es/admin-processes.md +++ b/content/es/admin-processes.md @@ -1,14 +1,14 @@ ## XII. Procesos de administración -### Ejecutar las tareas de gestión/administración como procesos de un solo uso +### Ejecutar las tareas de gestión/administración como procesos que solo se ejecutan una vez -El [juego de procesos](./concurrency) es un conjunto de procesos que se usan para hacer las tareas habituales de la aplicación (como procesar las peticiones web). Por separado, a menudo los desarrolladores desean ejecutar procesos de administración o mantenimiento de un solo uso, como: +El [juego de procesos](./concurrency) es el conjunto de procesos que se usa para hacer las tareas habituales de la aplicación (como procesar las peticiones web). Por otro lado, es frecuente que los desarrolladores quieran ejecutar procesos de administración o mantenimiento una sola vez, como por ejemplo: -* Ejecutar migraciones de bases de datos (e.g. `manage.py migrate` en Django, `rake db:migrate` en Rails). -* Ejecutar una consola (conocidas también como [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) para ejecutar código arbitrario o inspeccionar los modelos de la aplicación en una base de datos con datos reales. La mayoría de los lenguajes proporcionan un interprete de tipo REPL si se ejecuta el mismo mandato sin ningún argumento (e.g. `python` o `perl`) y en algunos casos tienen un mandato distinto (e.g. `irb` en Ruby, `rails console` en Rails). -* Ejecutar scripts de un solo uso incluidos en el repositorio de la aplicación (e.g. `php scripts/fix_bad_records.php`). +* Ejecutar migraciones de las bases de datos (e.g. `manage.py migrate` de Django, `rake db:migrate` de Rails). +* Ejecutar una consola (también conocidas como [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) para ejecutar código arbitrario o inspeccionar los modelos de la aplicación en una base de datos con datos reales. La mayoría de los lenguajes proporcionan un interprete del tipo REPL si se ejecuta el mismo mandato sin ningún argumento (e.g. `python` o `perl`) pero en algunos casos tienen un mandato distinto (e.g. `irb` en Ruby, `rails console` en Rails). +* Ejecutar scripts incluidos en el repositorio de la aplicación (e.g. `php scripts/fix_bad_records.php`). -Los procesos de administración únicos deberían ejecutarse en un entorno idéntico al que se usa normalmente en [procesos de larga duración](./processes) de la aplicación. Estos procesos se ejecutan en una [distribución](./build-release-run) concreta, usando la misma [base de código](./codebase) y la misma [configuración](./config), que cualquier proceso que ejecuta esa distribución. El código de administración debe ser enviado con el código de la aplicación para evitar problemas de sincronización. +Los procesos de este tipo deberían ejecutarse en un entorno idéntico al que se usa normalmente en los [procesos](./processes) habituales de la aplicación. Estos procesos se ejecutan en una [distribución](./build-release-run) concreta, usando el mismo [código base](./codebase) y la misma [configuración](./config), que cualquier otro proceso que ejecuta esa distribución. El código de administración se debe enviar con el código de la aplicación para evitar problemas de sincronización. -Se deberían usar las mismas técnicas de [aislamiento de dependencias](./dependencies) en todos los tipos de procesos. Por ejemplo, si el proceso web Ruby usa el mandato `bundle exec thin start`, entonces una migración de la base de datos debería usar `bundle exec rake db:migrate`. De la misma manera, un programa Python que usa Virtualenv debería usar `bin/python` para ejecutar tanto el servidor web Tornado como cualquier proceso de administración `manage.py`. +Se deberían usar las mismas técnicas de [aislamiento de dependencias](./dependencies) en todos los tipos de procesos. Por ejemplo, si un proceso web Ruby usa el mandato `bundle exec thin start`, entonces una migración de la base de datos debería usar `bundle exec rake db:migrate`. De la misma manera, un programa Python que usa Virtualenv debería usar `bin/python` para ejecutar tanto el servidor web Tornado como cualquier proceso de administración `manage.py`. -"Twelve-factor" recomienda encarecidamente lenguajes que proporcionan una consola del tipo REPL, ya que facilitan ejecutar scripts de un solo uso. En un despliegue local, los desarrolladores invocarán procesos de administración de un solo uso con un mandato directo en la consola dentro del directorio de la aplicación. En un despliegue de producción, los desarrolladores pueden usar ssh u otro mecanismo de ejecución de mandatos remoto proporcionado por el entorno de ejecución del despliegue para ejecutar dicho proceso. +"Twelve-factor" recomienda encarecidamente lenguajes que proporcionan una consola del tipo REPL, ya que facilitan las tareas relacionadas con la ejecución de scripts que solo han de usarse una vez. En un despliegue local, se invocarán los procesos de administración con un mandato directo en la consola dentro del directorio de la aplicación. En un despliegue de producción, se puede usar ssh u otro mecanismo de ejecución de mandatos remoto proporcionado por el entorno de ejecución del despliegue para ejecutar dichos procesos. From cd9b3d9f344d5f7edbcc91472526bc7d5236e353 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Fri, 4 Dec 2015 18:52:07 +0100 Subject: [PATCH 230/472] Update toc accordingly to admin-processes changes. --- content/es/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/toc.md b/content/es/toc.md index 969a24381..3fa758b62 100644 --- a/content/es/toc.md +++ b/content/es/toc.md @@ -35,4 +35,4 @@ Twelve Factors ### Tratar los historiales como una transmisión de eventos ## [XII. Administración de procesos](./admin-processes) -### Ejecutar las tareas de gestión/administración como procesos de un solo uso +### Ejecutar las tareas de gestión/administración como procesos que solo se ejecutan una vez From 8a0912b0603f710bd919636ca273f294695db092 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 20:57:58 +0100 Subject: [PATCH 231/472] Second review for codebase. --- content/es/codebase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/codebase.md b/content/es/codebase.md index 4f9c841e5..e0d6ec784 100644 --- a/content/es/codebase.md +++ b/content/es/codebase.md @@ -10,8 +10,8 @@ El *código base* es cualquier repositorio (en un sistema de control de versione Siempre hay una relación uno a uno entre el código base y la aplicación: * Si hay multiples códigos base, no es una aplicación -- es un sistema distribuido. Cada componente en un sistema distribuido es una aplicación, y cada uno, individualmente, puede cumplir los requisitos de una aplicación "twelve-factor". -* Multiples aplicaciones que comparten el mismo código se considera como una violación de la metodología "twelve factor". La solución en este caso es separar el código compartido en librerías que pueden estar enlazadas mediante un [gestor de dependencias](./dependencies). +* Compartir código en varias aplicaciones se considera una violación de la metodología "twelve factor". La solución en este caso es separar el código compartido en librerías que pueden estar enlazadas mediante un [gestor de dependencias](./dependencies). -Existe solo un código base por aplicación, pero habrá muchos despliegues de la aplicación. Un *despliegue* es una instancia de la aplicación que está en ejecución. Ésto, normalmente, es un sitio en producción, y uno o más sitios de pruebas. Además, cada desarrollador tiene una copia de la aplicación ejecutandose en su entorno de desarrollo propio, cada uno de los cuales se considera también como un despliegue. +El código base de la aplicación es único, sin embargo, puede haber tantos despliegues de la aplicación como sean necesarios. Un *despliegue* es una instancia de la aplicación que está en ejecución. Normalmente, se ejecuta en un entorno de producción, y uno o varios entornos de pruebas. Además, cada desarrollador tiene una instancia en su propio entorno de desarrollo, los cuales se consideran también como despliegues. -El código base es el mismo en todos los despliegues, aun que pueden ser diferentes versiones en cada despliegue. Por ejemplo, un desarrollador tiene algunos commits sin desplegar en preproducción; preproducción tiene algunos commits que no están desplegados en producción. Pero todos ellos comparten el mismo código base, de este modo todos son identificables como diferentes despliegues de la misma aplicación. +El código base es el mismo en todos los despliegues, aunque pueden ser diferentes versiones en cada despliegue. Por ejemplo, un desarrollador tiene algunos commits sin desplegar en preproducción; preproducción tiene algunos commits que no están desplegados en producción. Pero todos ellos comparten el mismo código base, de este modo todos son identificables como diferentes despliegues de la misma aplicación. From cfb1592a2df9f0a03e12c261dde473bb30b9b263 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 20:58:39 +0100 Subject: [PATCH 232/472] Second review for dependencies. --- content/es/dependencies.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/es/dependencies.md b/content/es/dependencies.md index f173f237c..b6435da0c 100644 --- a/content/es/dependencies.md +++ b/content/es/dependencies.md @@ -1,12 +1,12 @@ ## II. Dependencias ### Declarar y aislar explícitamente las dependencias -La mayoría de los lenguajes de programación tienen un sistema de gestión de paquetes para distribuir sus librerías, como [CPAN](http://www.cpan.org/) en Perl o [Rubygems](http://rubygems.org/) en Ruby. Las librerías instaladas a través de estos sistemas, se pueden instalar en el sistema (también conocido como "site packages") o limitarse al directorio que contiene la aplicación (también conocido como "vendoring" o "bundling"). +La mayoría de los lenguajes de programación tienen un sistema de gestión de paquetes para distribuir sus librerías, como [CPAN](http://www.cpan.org/) en Perl o [Rubygems](http://rubygems.org/) en Ruby. Las librerías instaladas a través de estos sistemas se pueden instalar en el sistema (también conocido como "site packages") o limitarse al directorio que contiene la aplicación (también conocido como "vendoring" o "bundling"). **Una aplicación "twelve-factor" no depende nunca de la existencia explícita de paquetes instalados en el sistema.** Declara todas sus dependencias, completamente y explícitamente, mediante un manifiesto de *declaración de dependencias*. Además, usa herramientas de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implícitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita se aplica de la misma manera tanto en producción como en desarrollo. -Por ejemplo, el [Gem Bundler](http://gembundler.com/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa que conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". +Por ejemplo, la [gema Bundler](http://gembundler.com/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa qué conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". -Uno de los beneficios de la declaración explícita de dependencias es que simplifica la configuración para los nuevos desarrolladores de la aplicación. Un nuevo desarrollador puede probar el código base de la aplicación en su máquina de desarrollo, con tan solo tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para ejecutar el código de la aplicación con un *mandato para construir*. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. +Uno de los beneficios de la declaración explícita de dependencias es que simplifica la configuración para los nuevos desarrolladores de la aplicación. Cualquier desarrollador que se incorpore al equipo debe poder probar el código base de la aplicación en su máquina de desarrollo. Tan solo debe tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para ejecutar el código de la aplicación con un *mandato para construir*. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. -Las aplicaciones "Twelve-factor" tampoco dependen de la existencia de ninguna herramienta en el sistema. Por ejemplo, ejecutar mandatos como `ImageMagick` o `curl`. Aunque estas herramientas pueden existir en muchos, o incluso en la mayoría de los sistemas, no existen garantías de que vayan a existir en todos los sistemas donde la aplicación pueda ser ejecutada en un futuro, o si las versiones futuras de un sistema serán compatibles con la aplicación. Si la aplicación necesita ejecutar una herramienta del sistema, dicha herramienta debería estar incluida dentro de la aplicación. +Las aplicaciones "Twelve-factor" tampoco dependen de la existencia de ninguna herramienta en el sistema. Por ejemplo, ejecutar mandatos como `ImageMagick` o `curl`. Aunque estas herramientas pueden existir en muchos, o incluso en la mayoría de los sistemas, no existen garantías de que vayan a existir en todos los sistemas donde la aplicación pueda ser ejecutada en un futuro, ni de que las versiones futuras de un sistema vayan a ser compatibles con la aplicación. Si la aplicación necesita ejecutar una herramienta del sistema, dicha herramienta debería estar incluida dentro de la aplicación. From efaca0cd95b130a2e293b8e78c2bc4f28ea0048b Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 20:59:18 +0100 Subject: [PATCH 233/472] Second review for config. --- content/es/config.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/es/config.md b/content/es/config.md index db16931fa..9849720b3 100644 --- a/content/es/config.md +++ b/content/es/config.md @@ -1,21 +1,21 @@ ## III. Configuración ### Guardar la configuración en el entorno -La configuración de una aplicación es todo lo que puede variar entre [despliegues](./codebase) (entornos de preproducción, producción, desarrollo, etc). Lo que incluye: +La configuración de una aplicación es todo lo que puede variar entre [despliegues](./codebase) (entornos de preproducción, producción, desarrollo, etc), lo cual incluye: * Recursos que manejan la base de datos, Memcached, y otros ["backing services"](./backing-services) * Credenciales para servicios externos tales como Amazon S3 o Twitter * Valores de despliegue como por ejemplo el nombre canónico del equipo para el despliegue -A veces las aplicaciones guardan configuraciones como constantes en el código. Lo cual conduce a una violación de la metodología "twelve-factor", que requiere una **estricta separación de la configuración y el código**. La configuración varía sustancialmente en cada despliegue, el código no. +A veces las aplicaciones guardan configuraciones como constantes en el código, lo que conduce a una violación de la metodología "twelve-factor", que requiere una **estricta separación de la configuración y el código**. La configuración varía sustancialmente en cada despliegue, el código no. La prueba de fuego para saber si una aplicación tiene toda su configuración correctamente separada del código es comprobar que el código base puede convertirse en código abierto en cualquier momento, sin comprometer las credenciales. Hay que resaltar que la definición de "configuración" **no** incluye las configuraciones internas de la aplicación, como `config/routes.rb` en Rails, o como [se conectan los módulos](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) en [Spring](http://spring.io/). Este tipo de configuraciones no varían entre despliegues, y es por eso que están mejor en el código. -Otra estrategia de configuración es el uso de ficheros de configuración que no se guardan en el control de versiones, como ocurre con el `config/database.yml` de Rails. Lo que supone una gran mejora con respecto a las constantes que se guardan en el repositorio, aunque todavía tiene ciertas debilidades: es fácil guardar un fichero de configuración en el repo por error; se tiende a desperdigar los ficheros de configuración en diferentes sitios y con distintos formatos, siendo más difícil la tarea de ver y gestionar toda la configuración en un solo sitio. Además, el formato tiende a ser específico del lenguaje o del framework. +Otra estrategia de configuración es el uso de ficheros de configuración que no se guardan en el control de versiones, como ocurre con el `config/database.yml` de Rails. Esto supone una gran mejora con respecto a las constantes que se guardan en el repositorio, aunque todavía tiene ciertas debilidades: es fácil guardar un fichero de configuración en el repo por error; se tiende a desperdigar los ficheros de configuración en diferentes sitios y con distintos formatos, siendo más difícil la tarea de ver y gestionar toda la configuración en un solo sitio. Además, el formato tiende a ser específico del lenguaje o del framework. -**Las aplicaciones "twelve-factor" almacenan la configuración en *variables de entorno*** (a menudo acortadas como *env vars* o *env*). Las variables de entorno se intercambian fácilmente entre despliegues sin modificar nada en el código; a diferencia de los ficheros de configuración, hay una pequeña posibilidad de que se guarden en el repositorio de código accidentalmente; y a diferencia de los ficheros de configuración personalizados u otros mecanismos de configuración, como los System Properties de Java, son un estándar independiente del lenguaje y del sistema operativo. +**Las aplicaciones "twelve-factor" almacenan la configuración en *variables de entorno*** (abreviadas normalmente como *env vars* o *env*). Las variables de entorno se modifican fácilmente entre despliegues sin realizar cambios en el código; a diferencia de los ficheros de configuración, en los que existe una pequeña posibilidad de que se guarden en el repositorio de código accidentalmente; y a diferencia de los ficheros de configuración personalizados u otros mecanismos de configuración, como los System Properties de Java, son un estándar independiente del lenguaje y del sistema operativo. Otro aspecto de la gestión de la configuración es la clasificación. A veces, las aplicaciones clasifican las configuraciones en grupos identificados (a menudo llamados "entornos" o "environments") identificando después despliegues específicos, como ocurre en Rails con los entornos `development`, `test`, y `production`. Este método no escala de una manera limpia: según se van creando despliegues de la aplicación, se van necesitando nuevos entornos, tales como `staging` o `qa`. Según va creciendo el proyecto, los desarrolladores van añadiendo sus propios entornos especiales como `joes-staging`, resultando en una explosión de combinaciones de configuraciones que hacen muy frágil la gestión de despliegues de la aplicación. From 1e63658ca49a563b977fb79ee9a4a6017a499acf Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:00:05 +0100 Subject: [PATCH 234/472] Second review for backing-services --- content/es/backing-services.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/backing-services.md b/content/es/backing-services.md index 7c3375881..c707b9ed1 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -3,12 +3,12 @@ Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). -Los "backing services", como las bases de datos, son gestionados, tradicionalmente, por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros. Como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). +Tradicionalmente, los "backing services" (como las bases de datos) han sido gestionadas por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros, como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). **El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos conectados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local se podría cambiar por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. Cada "backing service" distinto es un *recurso*. Por ejemplo, una base de datos MySQL es un recurso; dos bases de datos MySQL (usadas para "sharding" en la capa de aplicación) les convierte en dos recursos distintos. Una aplicación "twelve factor" trata esas bases de datos como *recursos conectados*, lo que demuestra su bajo acoplamiento al despliegue al que se unen. -Un despliegue en producción conectado a cuatro servicios de respaldo. +Un despliegue en producción conectado a cuatro backing services. -Los recursos se pueden conectar y desconectar a voluntad. Por ejemplo, si la base de datos funciona mal debido a un problema en el hardware, el administrador de la aplicación puede cambiar a un nuevo servidor de bases de datos que haya sido restaurado de un backup reciente. La base de datos actual de producción se puede desconectar, y conectar una nueva base de datos -- sin tener que cambiar nada en el código. +Los recursos se pueden conectar y desconectar a voluntad. Por ejemplo, si la base de datos funciona mal debido a un problema en el hardware, el administrador de la aplicación puede cambiar a un nuevo servidor de bases de datos que haya sido restaurado de un backup reciente. La base de datos actual de producción se puede desconectar, y conectar una nueva base de datos sin tener que cambiar nada en el código. From 701437010afeec05c9699b233e00bdab7e7a2cff Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:00:37 +0100 Subject: [PATCH 235/472] Second review for build-release-run --- content/es/build-release-run.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/build-release-run.md b/content/es/build-release-run.md index 1511eef65..e64310b15 100644 --- a/content/es/build-release-run.md +++ b/content/es/build-release-run.md @@ -4,15 +4,15 @@ El [código base](./codebase) se transforma en un despliegue (que no es de desarrollo) al completar las siguientes tres etapas: * La *etapa de construcción* es una transformación que convierte un repositorio de código en un paquete ejecutable llamado *construcción* (una "build"). En la etapa de construcción se traen todas las [dependencias](./dependencies) y se compilan los binarios y las herramientas usando una versión concreta del código correspondiente a un commit especificado por el proceso de despliegue. -* En la *fase de distribución* se usa la construcción creada en la fase de construcción y se combina con la [configuración](./config) del despliegue actual. Por tanto, la *distribución* resultante contiene tanto la construcción como la configuración y está lista para ejecutar inmediatamente en el entorno de ejecución. +* En la *fase de distribución* se usa la construcción creada en la fase de construcción y se combina con la [configuración](./config) del despliegue actual. Por tanto, la *distribución* resultante contiene tanto la construcción como la configuración y está lista para ejecutarse inmediatamente en el entorno de ejecución. * La *fase de ejecución* (también conocida como "runtime") ejecuta la aplicación en el entorno de ejecución, lanzando un conjunto de [procesos](./processes) de una distribución concreta de la aplicación. ![El código se convierte en una construcción, que se combina con la configuración para crear una distribución.](/images/release.png) **Las aplicaciones "twelve-factor" hacen una separación completa de las fases de construcción, de distribución y de ejecución.** Por ejemplo, es imposible hacer cambios en el código en la fase de ejecución, porque no hay una manera de propagar dichos cambios a la fase de construcción. -Las herramientas de despliegue ofrecen, normalmente, herramientas de gestión de distribuciones (releases), es especialmente útil la habilidad de volver a una versión anteriormente distribuida. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. +Las herramientas de despliegue ofrecen, normalmente, herramientas de gestión de distribuciones (releases). La capacidad de volver a una versuón anterior es especialmente útil. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. Cada distribución debería tener siempre un identificador único de distribución, como por ejemplo una marca de tiempo (timestamp) de la distribución (`2011-04-06-20:32:17`) o un número incremental (como `v100`). Las distribuciones son como un libro de contabilidad, al que solo se le pueden agregar registros y no pueden ser modificados una vez son creados. Cualquier cambio debe crear una nueva distribución. -Las construcciones son iniciadas por los desarrolladores de la aplicación cuando se despliega nuevo código. La fase de ejecución, en cambio, puede suceder automáticamente, por ejemplo, cuando se reinicia un servidor, o cuando un proceso termina inesperadamente siendo reiniciado por el gestor de procesos. Por tanto, la fase de ejecución debería mantenerse lo más estática que sea posible, ya que evita que una aplicación en ejecución pueda causar una interrupción inesperada, en mitad de la noche, cuando no hay desarrolladores a mano. La fase de construcción puede ser más compleja, ya que los errores siempre están en la mente de un desarrollador que dirige un despliegue. +Cada vez que un desarrollador despliega código nuevo se crea una construcción nueva de la aplicación. La fase de ejecución, en cambio, puede suceder automáticamente, por ejemplo, cuando se reinicia un servidor, o cuando un proceso termina inesperadamente siendo reiniciado por el gestor de procesos. Por tanto, la fase de ejecución debería mantenerse lo más estática posible, ya que evita que una aplicación en ejecución pueda causar una interrupción inesperada, en mitad de la noche, cuando no hay desarrolladores a mano. La fase de construcción puede ser más compleja, ya que los errores siempre están en la mente de un desarrollador que dirige un despliegue. From c9905dcf54c8f258bdf5f9277c054c37359434bf Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:01:03 +0100 Subject: [PATCH 236/472] Second review for processes --- content/es/processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/es/processes.md b/content/es/processes.md index 40ef34e8f..94add15b2 100644 --- a/content/es/processes.md +++ b/content/es/processes.md @@ -7,8 +7,8 @@ El caso más sencillo que podemos plantear es que el código es un script indepe **Los procesos "twelve-factor" no tienen estado y son "[share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture)".** Cualquier información que necesite persistencia se debe almacenar en un ['backing service'](./backing-services) con estado, habitualmente una base de datos. -Tanto el espacio de memoria de un proceso como el sistema de ficheros se pueden usar como si fueran una cache temporal para hacer transacciones. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca dan por hecho que cualquier cosa cacheada en memoria o en el disco vaya a estar disponible al realizar una petición al ejecutar diferentes procesos. Con muchos procesos de cada tipo ejecutandose al mismo tiempo, existe una gran probabilidad de que otro proceso distinto sirva una petición en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (provocado por el despliegue de código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). +Tanto el espacio de memoria de un proceso como el sistema de ficheros se pueden usar como si fueran una cache temporal para hacer transacciones. Por ejemplo, descargar un fichero de gran tamaño, realizar alguna operación sobre él, y almacenar sus resultados en una base de datos. Las aplicaciones "twelve-factor" nunca dan por hecho que cualquier cosa cacheada en memoria o en el disco vaya a estar disponible al realizar una petición al ejecutar diferentes procesos. Con muchos procesos de cada tipo ejecutándose al mismo tiempo, existe una gran probabilidad de que otro proceso distinto sirva una petición en el futuro. Incluso cuando solo está corriendo un solo proceso, un reinicio (provocado por el despliegue de código, un cambio de configuración o un cambio de contexto del proceso) normalmente elimina todo el estado local (e.g. memoria y sistema de ficheros). -Los compresores de estáticos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" es preferible realizar esta compilación durante la [fase de construcción](./build-release-run), como con el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), que en tiempo de ejecución. +Los compresores de estáticos (como [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usan el sistema de ficheros como una cache para ficheros compilados. En las aplicaciones "twelve-factor" es preferible realizar esta compilación durante la [fase de construcción](./build-release-run), como con el [asset pipeline de Rails](http://guides.rubyonrails.org/asset_pipeline.html), en lugar de hacerlo en tiempo de ejecución. Algunos sistemas webs dependen de ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence), esto quiere decir que cachean la información de la sesión de usuario en la memoria del proceso de la aplicación y esperan peticiones futuras del mismo visitante para redirigirle al mismo proceso. Las "sticky sessions" son una violación de "twelve-factor" y no deberían usarse nunca ni depender de ellas. La información del estado de la sesión es un candidato perfecto para almacenes de información que ofrecen mecanismos de tiempo de expiración, como [Memcached](http://memcached.org/) o [Redis](http://redis.io/). From c192cad9e9922ff5fb3a0579a0db308a11948ef6 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:01:25 +0100 Subject: [PATCH 237/472] Second review for port-binding --- content/es/port-binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/es/port-binding.md b/content/es/port-binding.md index d90ea9ba2..39939235f 100644 --- a/content/es/port-binding.md +++ b/content/es/port-binding.md @@ -1,13 +1,13 @@ ## VII. Asignación de puertos ### Publicar servicios mediante asignación de puertos -A menudo, las aplicaciones web, se ejecutan mediante contenedores web. Por ejemplo, las aplicaciones de PHP se suelen ejecutar como módulos del [HTTPD de Apache](http://httpd.apache.org/), y las aplicaciones Java en [Tomcat](http://tomcat.apache.org/). +Las aplicaciones web se ejecutan a menudo mediante contenedores web. Por ejemplo, las aplicaciones de PHP se suelen ejecutar como módulos del [HTTPD de Apache](http://httpd.apache.org/), y las aplicaciones Java en [Tomcat](http://tomcat.apache.org/). **Las aplicaciones "twelve factor" son completamente auto-contenidas** y no dependen de un servidor web en ejecución para crear un servicio web público. Una aplicación web **usa HTTP como un servicio al que se le asigna un puerto**, y escucha las peticiones que recibe por dicho puerto. En los entornos de desarrollo, los desarrolladores usan una URL del servicio (por ejemplo `http://localhost:5000/`), para acceder al servicio que ofrece la aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una dirección pública se redirijan hacia el proceso web que tiene asignado su puerto correspondiente. -Ésto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Ésto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. +Esto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. HTTP no es el único servicio que usa asignación de puertos. La verdad, es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigna un puerto y queda a la espera de peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). From 1fabdbe47580cc2ef824870cbff3560b6256a22c Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:01:53 +0100 Subject: [PATCH 238/472] Second review for concurrency --- content/es/concurrency.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/concurrency.md b/content/es/concurrency.md index d1b020371..fc48ef1fa 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -1,7 +1,7 @@ ## VIII. Concurrencia ### Escalar mediante el modelo de procesos -Todo programa de ordenador, al ejecutarse, se encuentra representado en memoria por uno o más procesos. Las aplicaciones web se pueden ejecutar de diferentes formas desde el punto de vista del modelo de procesos que usan. Por ejemplo, los procesos PHP se ejecutan como procesos pesados (o simplemente procesos), hijos del proceso Apache, estos procesos se crean bajo demanda debido a la cantidad de peticiones cuando es necesario. Los procesos Java funcionan de forma distinta, la Máquina Virtual de Java (JVM) proporciona un conjunto de procesos que reservan al principio una gran cantidad de recursos del sistema (CPU y memoria), gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución son prácticamente transparentes para los desarrolladores de la aplicación. +Todo programa de ordenador, al ejecutarse, se encuentra representado en memoria por uno o más procesos. Las aplicaciones web se pueden ejecutar de diferentes formas desde el punto de vista del modelo de procesos que usan. Por ejemplo, los procesos PHP se ejecutan como procesos pesados (o simplemente procesos), hijos del proceso Apache, creándolos bajo demanda a causa de la cantidad de peticiones si es necesario. Los procesos Java funcionan de forma distinta, la Máquina Virtual de Java (JVM) proporciona un conjunto de procesos que reservan al principio una gran cantidad de recursos del sistema (CPU y memoria), gestionando la concurrencia internamente mediante procesos ligeros (threads). En ambos casos, los procesos en ejecución son prácticamente transparentes para los desarrolladores de la aplicación. ![La escalabilidad está representada por el número de procesos en ejecución, mientras que la diversidad de carga de trabajo lo está por los tipos de procesos.](/images/process-types.png) From 745298ceeba9ed919994b5345ea2af095e4e6bc3 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:02:18 +0100 Subject: [PATCH 239/472] Second review for disposability --- content/es/disposability.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/es/disposability.md b/content/es/disposability.md index ea276ae50..203e01771 100644 --- a/content/es/disposability.md +++ b/content/es/disposability.md @@ -5,8 +5,8 @@ Los procesos deberían intentar conseguir **minimizar el tiempo de arranque**. En el mejor de los casos, un proceso necesita unos pocos segundos desde que se ejecuta el mandato hasta que arranca y está preparado para recibir peticiones o trabajos. Mejorar el tiempo de arranque proporciona mayor agilidad en el proceso de [distribución](./build-release-run) y escalado; y lo hace más robusto, porque el gestor de procesos puede mover procesos de forma segura entre máquinas físicas más fácilmente. -Los procesos **se paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implícitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos), y en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. +Los procesos **se paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implícitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos) y, en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. -Para un trabajador (o "worker") finalizar de manera segura se consigue devolviendo el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implícitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). +Para finalizar de manera segura, un trabajador (o "worker") debe devolver el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implícitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). Los procesos deberían estar **preparados contra finalizaciones inesperadas**, como en el caso de un fallo a nivel hardware. Aunque es un caso más raro que una finalización mediante la señal `SIGTERM`, se puede dar el caso. Lo recomendable es usar un sistema de colas robusto, como Beanstalkd, que devuelve los trabajos a su cola cuando los clientes se desconectan o expira su tiempo de espera ("timeout"). En cualquier caso, una aplicación "twelve-factor" es una arquitectura que trata finalizaciones inesperadas y peligrosas. El [diseño Crash-only](http://lwn.net/Articles/191059/) lleva este concepto a su [conclusión lógica](http://docs.couchdb.org/en/latest/intro/overview.html). From 28496a9e3d44b0b9d6cef7953db9482b84230e3c Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:02:41 +0100 Subject: [PATCH 240/472] Second review for dev-prod-parity --- content/es/dev-prod-parity.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md index c6bb9fc82..abedbc197 100644 --- a/content/es/dev-prod-parity.md +++ b/content/es/dev-prod-parity.md @@ -1,7 +1,7 @@ ## X. Igualdad entre desarrollo y producción ### Mantener desarrollo, preproducción y producción tan parecidos como sea posible -Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo (donde un desarrollador puede editar en vivo en un [despliegue](./codebase) local de la aplicación) y producción (un despliegue en el que la aplicación está en ejecución disponible para que lo usen los usuarios). Estas diferencias se pueden clasificar en tres tipos: +Históricamente, han existido dos tipos de entorno muy diferenciados: desarrollo (donde un desarrollador puede editar en vivo en un [despliegue](./codebase) local de la aplicación) y producción (un despliegue en el que la aplicación está en ejecución disponible para que lo usen los usuarios). Estas diferencias se pueden clasificar en tres tipos: * **Diferencias de tiempo**: Un desarrollador puede estar trabajando en un código durante días, semanas o incluso meses antes de que llegue a producción. * **Diferencias de personal**: Los desarrolladores escriben el código y los ingenieros de operaciones lo despliegan. @@ -9,7 +9,7 @@ Históricamente, han existido dos tipos de entorno muy diferenciados, desarrollo ** Las aplicaciones "twelve-factor" están diseñadas para hacer [despliegues continuos](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) que reducen las diferencias entre los entornos de desarrollo y producción.** Teniendo en cuenta las tres diferencias descritas anteriormente: -* Reducir las diferencias de tiempo: Un desarrollador puede escribir código y tenerlo desplegado en tan solo unas horas o incluso, minutos más tarde. +* Reducir las diferencias de tiempo: Un desarrollador puede escribir código y tenerlo desplegado en tan solo unas horas, o incluso, minutos más tarde. * Reducir las diferencias de personal: Los desarrolladores que escriben el código están muy involucrados en el despliegue y observan su comportamiento en producción. * Reducir las diferencias de herramientas: tratar de hacer que desarrollo y producción sean tan parecidos como sea posible. @@ -69,8 +69,8 @@ Los ["backing services"](./backing-services), como la base de datos de la aplica Los desarrolladores, a veces, caen en la tentación de usar "backing services" ligeros en sus entornos de desarrollo, mientras que en producción se usan los más serios y robustos. Por ejemplo, se usa SQLite en desarrollo y PostgreSQL en producción; o memoria local para la cache en desarrollo y Memcached en producción. -**Un desarrollador "twelve-factor" no cae en la tentación de usar diferentes "backing services" en desarrollo y producción**, incluso cuando los adaptadores teóricamente abstractos están lejos de cualquier diferencia en "backing services". Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que surgen de la nada, causando que el código que funciona y pasa los test en desarrollo o en preproducción, fallen en producción. Este tipo de errores provocan conflictos que desincentivan la filosofía del despliegue continuo. El coste de estos conflictos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se hace balance del total de tiempo de vida de una aplicación. +**Un desarrollador "twelve-factor" no cae en la tentación de usar diferentes "backing services" en desarrollo y producción**, incluso cuando los adaptadores teóricamente abstractos están lejos de cualquier diferencia en "backing services". Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que surgen de la nada, causando que el código que funciona y pasa los tests en desarrollo o en preproducción, falle en producción. Este tipo de errores provocan conflictos que desincentivan la filosofía del despliegue continuo. El coste de estos conflictos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se hace balance del total de tiempo de vida de una aplicación. -Los servicios ligeros locales son menos atractivos que antes. Los "backing services" modernos como Memcached, PostgreSQL, y RabbitMQ no son dificiles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinados con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas son bajos comparados con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. +Los servicios ligeros locales son menos atractivos que antes. Los "backing services" modernos como Memcached, PostgreSQL, y RabbitMQ no son difíciles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinadas con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas es bajo comparado con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. Los adaptadores de los "backing services" todavía son de gran utilidad, porque hacen que cambiar de unos a otros sea un trámite relativamente poco doloroso. No obstante, todos los despliegues de una aplicación (en entornos de desarrollo, preproducción y producción) deberían usar el mismo tipo y versión de cada uno de los "backing services". From 53d4003634a0134fa084fe309ee8033b96f6653b Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:03:07 +0100 Subject: [PATCH 241/472] Second review for logs --- content/es/logs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/es/logs.md b/content/es/logs.md index 1dbf5b399..62bab9437 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -1,16 +1,16 @@ ## XI. Historiales ### Tratar los historiales como una transmisión de eventos -Los *historiales* proporcionan visibilidad al comportamiento de la ejecución de la aplicación. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico"); pero este es solo un posible formato de salida. +Los *historiales* permiten observar el comportamiento de la aplicación durante su ejecución. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico") pero este, es tan solo un posible formato de salida. -Los historiales son la [transmisión](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de un conjunto de eventos ordenados y capturados de la salida de todos los procesos en ejecución y de los "backing services". En bruto, los historiales suelen estar en formato texto y tienen un evento por linea (aunque las trazas de excepciones suelen estar en varias lineas). Los historiales no tienen un principio y un final fijo, sino que fluyen continuamente mientras la aplicación está en funcionamiento. +Los historiales son la [transmisión](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de un conjunto de eventos ordenados y capturados de la salida de todos los procesos en ejecución y de los "backing services". En bruto, los historiales suelen estar en formato texto y tienen un evento por línea (aunque las trazas de excepciones suelen estar en varias líneas). Los historiales no tienen un principio y un final fijo, sino que fluyen continuamente mientras la aplicación está en funcionamiento. **Una aplicación "twelve-factor" nunca se preocupa del direccionamiento o el almacenamiento de sus transmisiones de salida.** No debería intentar escribir o gestionar ficheros de historial. En su lugar, cada proceso en ejecución escribe sus eventos a la `salida estándar` (o `stdout`). Durante el desarrollo, los desarrolladores verán el flujo en su terminal para observar el comportamiento de la aplicación. -En despliegues de preproducción y producción, cada transmision de proceso será capturado por el entorno de ejecución, siendo capturados junto con todos los otros flujos de la aplicación, y redirigido a uno o más destinos finales para ser revisados y archivados. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales, (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd) se usan con este objetivo. +En despliegues de preproducción y producción, cada transmisión del proceso será capturada por el entorno de ejecución, siendo capturadas junto con todos los otros flujos de la aplicación, y redirigidas a uno o más destinos finales para ser revisadas y archivadas. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales, (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd) se usan con este objetivo. -Las transmisiones de eventos para una aplicación pueden ser redirigidos a un fichero u observados en tiempo real mediante un "tail" en un terminal. Most significantly, la transmision se puede enviar a un sistema de analisis e indexado como [Splunk](http://www.splunk.com/), o a un sistema de almacenamiendo de datos de proposito general como [Hadoop/Hive](http://hive.apache.org/). Estos sistemas se tienen en cuenta por el gran poder y la flexibilidad para inspeccionar el comportamiento de la aplicación a lo largo del tiempo, incluyendo: +Las transmisiones de eventos para una aplicación pueden ser redirigidas a un fichero u observadas en tiempo real mediante un "tail" en un terminal. Cabe destacar que la transmisión se puede enviar a un sistema de análisis e indexado como [Splunk](http://www.splunk.com/), o a un sistema de almacenamiendo de datos de propósito general como [Hadoop/Hive](http://hive.apache.org/). Estos sistemas se tienen en cuenta por el gran poder y la flexibilidad para inspeccionar el comportamiento de la aplicación a lo largo del tiempo, incluyendo: * Encontrar eventos específicos del pasado. * Gráficas de tendencia a gran escala (como las peticiones por minuto). -* Activación de alertas de acuerdo con heurísticas definidas por el usuario (como una alerta cuando la cantidad de errores por minuto sobrepasa un cierto limite). +* Activación de alertas de acuerdo con heurísticas definidas por el usuario (como una alerta cuando la cantidad de errores por minuto sobrepasa un cierto límite). From c48ba112b145e40cecc57216f2eebc3ef874f338 Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Mon, 14 Dec 2015 21:03:22 +0100 Subject: [PATCH 242/472] Second review for admin-processes --- content/es/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/es/admin-processes.md b/content/es/admin-processes.md index f834394c6..b731703d5 100644 --- a/content/es/admin-processes.md +++ b/content/es/admin-processes.md @@ -1,4 +1,4 @@ -## XII. Procesos de administración +## XII. Administración de procesos ### Ejecutar las tareas de gestión/administración como procesos que solo se ejecutan una vez El [juego de procesos](./concurrency) es el conjunto de procesos que se usa para hacer las tareas habituales de la aplicación (como procesar las peticiones web). Por otro lado, es frecuente que los desarrolladores quieran ejecutar procesos de administración o mantenimiento una sola vez, como por ejemplo: @@ -7,7 +7,7 @@ El [juego de procesos](./concurrency) es el conjunto de procesos que se usa para * Ejecutar una consola (también conocidas como [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) para ejecutar código arbitrario o inspeccionar los modelos de la aplicación en una base de datos con datos reales. La mayoría de los lenguajes proporcionan un interprete del tipo REPL si se ejecuta el mismo mandato sin ningún argumento (e.g. `python` o `perl`) pero en algunos casos tienen un mandato distinto (e.g. `irb` en Ruby, `rails console` en Rails). * Ejecutar scripts incluidos en el repositorio de la aplicación (e.g. `php scripts/fix_bad_records.php`). -Los procesos de este tipo deberían ejecutarse en un entorno idéntico al que se usa normalmente en los [procesos](./processes) habituales de la aplicación. Estos procesos se ejecutan en una [distribución](./build-release-run) concreta, usando el mismo [código base](./codebase) y la misma [configuración](./config), que cualquier otro proceso que ejecuta esa distribución. El código de administración se debe enviar con el código de la aplicación para evitar problemas de sincronización. +Los procesos de este tipo deberían ejecutarse en un entorno idéntico al que se usa normalmente en los [procesos](./processes) habituales de la aplicación. Estos procesos se ejecutan en una [distribución](./build-release-run) concreta, usando el mismo [código base](./codebase) y la misma [configuración](./config) que cualquier otro proceso que ejecuta esa distribución. El código de administración se debe enviar con el código de la aplicación para evitar problemas de sincronización. Se deberían usar las mismas técnicas de [aislamiento de dependencias](./dependencies) en todos los tipos de procesos. Por ejemplo, si un proceso web Ruby usa el mandato `bundle exec thin start`, entonces una migración de la base de datos debería usar `bundle exec rake db:migrate`. De la misma manera, un programa Python que usa Virtualenv debería usar `bin/python` para ejecutar tanto el servidor web Tornado como cualquier proceso de administración `manage.py`. From ac6ba2e87e2c74b7d3527101e49c60214fb8a368 Mon Sep 17 00:00:00 2001 From: sebclick Date: Sat, 19 Dec 2015 18:53:10 +0100 Subject: [PATCH 243/472] fix french translation --- content/fr/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index f541cb58a..9a043a77d 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -1,5 +1,5 @@ ## V. Assemblez, publiez, exécutez -### Séparez strictment les étapes d'assemblage et d'exécution +### Séparez strictement les étapes d'assemblage et d'exécution Une [base de code](./codebase) est transformée en un déploiement (non-développement) à travers les étapes suivantes : From beba8c3c110babdf596fff45696a4137f1b09e75 Mon Sep 17 00:00:00 2001 From: sebclick Date: Sat, 19 Dec 2015 19:01:29 +0100 Subject: [PATCH 244/472] Fix french translation --- content/fr/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/disposability.md b/content/fr/disposability.md index 3d9ead3e3..371e1210f 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -7,7 +7,7 @@ Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. -Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le orker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). +Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le worker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non gracieuses. Le [design crash-only (en)](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique (en)](http://docs.couchdb.org/en/latest/intro/overview.html). From 3ea47ec048d62bc7ac4e08675f9ea7d9cb6c499a Mon Sep 17 00:00:00 2001 From: Seungha Kim Date: Wed, 30 Dec 2015 15:01:07 +0900 Subject: [PATCH 245/472] Fix typo in Korean translation --- content/ko/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/config.md b/content/ko/config.md index 6675e5184..3bedff6d3 100644 --- a/content/ko/config.md +++ b/content/ko/config.md @@ -15,8 +15,8 @@ 설정에 대한 또 다른 접근방식은 Rails의 `config/database.yaml`처럼 버전 관리 시스템에 등록되지 않은 설정 파일을 이용하는 것입니다. 이 방법은 코드 저장소에 등록된 상수를 사용하는 것에 비하면 매우 큰 발전이지만, 설정 파일이 여러 위치에 여러 포맷으로 흝어지고 모든 설정을 한 곳에서 확인하고 관리하기 어렵게 만드는 경향이 있습니다. 게다가, 이러한 형식들은 언어와 프레임워크을 따라가는 경향이 있습니다. -**Twelve-Factor App은 설정을 *환경 변수*** (envvars나 env라고도 불림)에 저장합니다. 환경 변수는 코드 변경 없이 쉽게 배포 떄마다 쉽게 변경할 수 있습니다. 설정 파일과 달리, 잘못해서 코드 저장소에 올라갈 가능성도 낮습니다. 또한, 커스텀 설정 파일이나 Java System Property와 같은 다른 설정 매커니즘과 달리 언어나 OS에 의존하지 않는 표준입니다. +**Twelve-Factor App은 설정을 *환경 변수*** (envvars나 env라고도 불림)에 저장합니다. 환경 변수는 코드 변경 없이 쉽게 배포 때마다 쉽게 변경할 수 있습니다. 설정 파일과 달리, 잘못해서 코드 저장소에 올라갈 가능성도 낮습니다. 또한, 커스텀 설정 파일이나 Java System Property와 같은 다른 설정 매커니즘과 달리 언어나 OS에 의존하지 않는 표준입니다. 설정 관리의 다른 측면은 그룹핑입니다. 종종 애플리케이션은 설정을 명명된 그룹("environments"라고도 함)으로 구성하기도 합니다. 해당 그룹은 Rails의 'development', 'test', 'production' environments처럼, 배포의 이름을 따서 명명됩니다. 이 방법은 깔끔하게 확장하기 어렵습니다. 응용 프로그램의 배포가 증가함에 따라, 'staging'이라던가 'qa'같은 새로운 그룹의 이름이 필요하게 됩니다. 프로젝트가 성장함에 따라, 개발자은 자기 자신의 그룹를 추가하게 됩니다. 결과적으로 설정이 각 그룹의 조합으로 폭발하게 되고, 애플리케이션의 배포를 불안정하게 만듭니다. -Twelve-Factor App에서 환경 변수는 매우 정교한 관리이며, 각각의 환경변수는 서로 직교합니다. 환경 변수는 "environments"로 절대 그룹으로 묶이지 않지만, 대신 각 배포마다 독립적으로 관리됩니다. 이 모델은 애플리케이션의 수명주기를 거치는 동안 더 많은 배포로 원활하게 확장해 나갈 수 있습니다. \ No newline at end of file +Twelve-Factor App에서 환경 변수는 매우 정교한 관리이며, 각각의 환경변수는 서로 직교합니다. 환경 변수는 "environments"로 절대 그룹으로 묶이지 않지만, 대신 각 배포마다 독립적으로 관리됩니다. 이 모델은 애플리케이션의 수명주기를 거치는 동안 더 많은 배포로 원활하게 확장해 나갈 수 있습니다. From b77266c997facd36dca23bca430b34192fe65ab8 Mon Sep 17 00:00:00 2001 From: Thiago Borges Date: Wed, 6 Jan 2016 22:08:27 -0200 Subject: [PATCH 246/472] Fix Portuguese translation --- content/pt_br/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index 785b564ce..4bd688166 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -10,7 +10,7 @@ Uma *base de código* é um único repo (em um sistema de controle de versão ce Existe sempre uma correlação um-para-um entre a base de código e a aplicação: * Se existem várias bases de código, isto não é uma app -- é um sistema distribuído. Cada componente do sistema é uma app, e cada uma pode individualmente ser compatível com os 12 fatores. -* Multiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas artavés do [gerenciador de dependências](/dependencies). +* Multiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas através do [gerenciador de dependências](/dependencies). Existe apenas uma base de código por aplicação, mas existirão várias deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. From 92b2a350ec494872bc00b2568924ba9995635d28 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 7 Jan 2016 09:18:19 +0000 Subject: [PATCH 247/472] Add Heroku generated app.json --- app.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 app.json diff --git a/app.json b/app.json new file mode 100644 index 000000000..b59d77154 --- /dev/null +++ b/app.json @@ -0,0 +1,10 @@ +{ + "name": "12factor", + "scripts": { + }, + "env": { + }, + "addons": [ + + ] +} From 8019a07d47ecb7c262f711bf6ae7279eea2918e5 Mon Sep 17 00:00:00 2001 From: Maksim Kochkin Date: Tue, 12 Jan 2016 15:53:31 +0300 Subject: [PATCH 248/472] typo --- content/ru/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/toc.md b/content/ru/toc.md index f0eef2db8..8e07f6436 100644 --- a/content/ru/toc.md +++ b/content/ru/toc.md @@ -26,7 +26,7 @@ ### Масштабируйте приложение с помощью процессов ## [IX. Утилизируемость (Disposability)](./disposability) -### Максимизируйте надежность с помощью быстрого запуска и корректного завершение работы +### Максимизируйте надежность с помощью быстрого запуска и корректного завершения работы ## [X. Паритет разработки/работы приложения](./dev-prod-parity) ### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими From 1626aa1bfe608d5a87cfcf5b0b368079f8ca2bc9 Mon Sep 17 00:00:00 2001 From: lance Date: Wed, 20 Jan 2016 11:31:59 +0800 Subject: [PATCH 249/472] Fix typo in Chinese translation --- content/zh_cn/concurrency.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index 2a07019a0..3f87bbd0a 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -5,7 +5,7 @@ ![扩展表现为运行中的进程,工作多样性表现为进程类型。](/images/process-types.png) -**在 12-actor 应用中,进程是一等公民。**12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 +**在 12-factor 应用中,进程是一等公民。**12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 From 27f1bdf9614edcd4af2e4156f9c6a59dc77e3f46 Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Wed, 27 Jan 2016 17:22:42 -0200 Subject: [PATCH 250/472] Fix Portuguese translation in codebase.md --- content/pt_br/codebase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index 4bd688166..e326c7e34 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -12,7 +12,7 @@ Existe sempre uma correlação um-para-um entre a base de código e a aplicaçã * Se existem várias bases de código, isto não é uma app -- é um sistema distribuído. Cada componente do sistema é uma app, e cada uma pode individualmente ser compatível com os 12 fatores. * Multiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas através do [gerenciador de dependências](/dependencies). -Existe apenas uma base de código por aplicação, mas existirão várias deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. +Existe apenas uma base de código por aplicação, mas existirão vários deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. -A base de código é a mesma através de todos deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não deployados no ambiente de teste, o ambiente de teste ainda tem registros não deployados em prodição. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. +A base de código é a mesma através de todos os deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não deployados no ambiente de teste, o ambiente de teste ainda tem registros não deployados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. From 5ce2039626dd425a490d457e4f5661307ce5b715 Mon Sep 17 00:00:00 2001 From: "sc.hwang" Date: Fri, 29 Jan 2016 16:19:03 +0900 Subject: [PATCH 251/472] profreading intro in korean --- content/ko/intro.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/ko/intro.md b/content/ko/intro.md index 3c524fd3b..0914b5aac 100644 --- a/content/ko/intro.md +++ b/content/ko/intro.md @@ -1,12 +1,12 @@ 머리말 ============ -오늘날 소프트웨어는 보통 서비스로 제공되고, 웹앱 혹은 SaaS(Software As A Service)로 불립니다. Twelve-Factor app은 아래와 같은 SaaS 앱을 만들기 위한 방법론입니다. +최근 소프트웨어를 서비스 형태로 제공하는게 일반화 되면서, 웹앱 혹은 SaaS(Software As A Service)라고 부르게 되었다. Twelve-Factor app은 아래 특징을 가진 SaaS 앱을 만들기 위한 방법론이다. -* 설정 자동화를 위해 **선언적(declarative)** 양식을 사용하여 새로운 개발자들이 프로젝트에 참여하는데 드는 시간과 비용을 최소화합니다. -* OS에 대한 **종속성을 명확히**하고, 실행 환경 사이의 **극대화된 이식성**을 제공한다. -* 현대적인 **클라우드 플랫폼** 상에 **배포되기** 적합하고, 서버와 시스템의 관리를 필요하지 않게 합니다. -* 개발 환경과 운영 환경의 **차이를 최소화**하고 민첩성을 극대화하기 위해 **지속적인 배포**가 가능하게 합니다. -* 툴, 아키텍처, 개발 방식을 크게 바꾸지 않고 **확장(scale up)** 할 수 있습니다. +* 설정 자동화를 위한 **절차(declarative)** 를 체계화 하여 새로운 개발자가 프로젝트에 참여하는데 드는 시간과 비용을 최소화한다. +* OS에 따라 **달라지는 부분을 명확히**하고, 실행 환경 사이의 **이식성을 극대화** 한다. +* 최근 등장한 **클라우드 플랫폼** **배포에** 적합하고, 서버와 시스템의 관리가 필요없게 된다. +* 개발 환경과 운영 환경의 **차이를 최소화**하고 민첩성을 극대화하기 위해 **지속적인 배포**가 가능하다. +* 툴, 아키텍처, 개발 방식을 크게 바꾸지 않고 **확장(scale up)** 할 수 있다. -Twelve-Factor 방법론은 어떤 프로그래밍 언어로 작성된 애플리케이션이든 적용이 가능합니다. 그리고 어떤 백엔드 서비스(데이터베이스, 큐, 메모리 캐시 등)과의 조합에도 사용될 수 있습니다. \ No newline at end of file +Twelve-Factor 방법론은 어떤 프로그래밍 언어로 작성된 앱에도 적용할 수 있고 백엔드 서비스(데이터베이스, 큐, 메모리 캐시 등)와 다양한 조합으로 사용할 수 있다. \ No newline at end of file From dc3ee63542c232274ad2fb21ef94b70fea86676c Mon Sep 17 00:00:00 2001 From: "sc.hwang" Date: Fri, 29 Jan 2016 16:54:44 +0900 Subject: [PATCH 252/472] proofreading background in korean --- content/ko/background.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/content/ko/background.md b/content/ko/background.md index 1bb9903f9..be72db553 100644 --- a/content/ko/background.md +++ b/content/ko/background.md @@ -1,9 +1,8 @@ 배경 ========== -이 문서에 대한 기여자들은 수백개의 애플리케이션 개발과 배포에 직접적으로 참여했으며, [Heroku](http://www.heroku.com/) 플랫폼에서의 작업을 통해 방대한 양의 애플리케이션 개발, 운영, 확장을 간접적으로 관찰했습니다. +이 문서에 기여한 사람들은 수백개 앱의 개발과 배포에 직접 참여했으며, [Heroku](http://www.heroku.com/) 플랫폼을 통해서 방대한 앱의 개발, 운영, 확장을 간접적으로 관찰했다. -이 문서는 생태계의 다양한 SaaS 애플리케이션에 대한 저희의 경험과 관찰을 종합한 결과물입니다. 특히 응용프로그램의 시간이 지남에 따른 유기적인 성장, 애플리케이션의 코드베이스에서 작업하는 개발자들 간의 협업, [소프트웨어가 낡는 것에 의한 비용을 피하는 법](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)에 집중하여 애플리케이션 개발에 대한 이상적인 방법을 찾고자 했습니다. +이 문서는 실제로 쓰이는 다양한 SaaS 앱에 대한 경험과 관찰을 종합한 결과물이다. 특히 시간이 지나면서 앱이 유기적으로 성장하는 부분, 앱 코드베이스에서 작업하는 개발자들 간의 협업, [시간이 지나면서 망가지는 소프트웨어 유지비용을 줄이는 법](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/)에 집중하여 이상적인 앱 개발 방법을 찾고자 했다. - -이 문서는 저희가 현대적인 애플리케이션 개발에서 만났던 몇가지 시스템적인 문제에 대한 인지도를 높히고, 이 문제들에 대해 논의를 하기 위한 공통의 어휘를 제공하며, 이 문제들에 대한 넓은 개념의 해결책과 그에 대한 용어를 제공하기 위해 작성 되었습니다. 형식은 Martin Fowler의 책, *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)*과 *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*에서 영감을 받았습니다. \ No newline at end of file +이 문서는 우리가 최신 애플리케이션 개발에서 만났던 몇가지 시스템적인 문제에 대한 인지도를 높이고, 이 문제들을 가지고 논의 하는데 필요한 공통의 어휘를 제공하며, 이 문제들에 대한 넓은 개념의 해결책과 용어를 제공하기 위해 작성 했다. 형식은 Martin Fowler의 책, *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)*과 *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*에서 영감을 받았다. \ No newline at end of file From c03dd41e5532dcab4be822c7a6513bbac740dd71 Mon Sep 17 00:00:00 2001 From: Artur Szott Date: Sat, 30 Jan 2016 18:52:26 +0100 Subject: [PATCH 253/472] Provide encoding for reading localization files to solve problem on Windows platform --- web.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web.rb b/web.rb index 242c0a7d6..2622a782b 100644 --- a/web.rb +++ b/web.rb @@ -35,7 +35,7 @@ helpers do def render_markdown(file) - markdown = File.read("content/#{I18n.locale}/#{file}.md") + 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" From 4c21cd1b2b468d226e0247af853a63000809a3f0 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 1 Feb 2016 09:38:50 +0000 Subject: [PATCH 254/472] update ruby --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index a80d1ac97..3b02809b9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.2.1' +ruby '2.2.4' gem 'sinatra' gem 'thin' From 1af4cea2a5b87b515f700c325deb5c44ce9b06a4 Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 12:39:13 +0100 Subject: [PATCH 255/472] Update intro.mdf Fix a french translation error --- content/fr/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/intro.md b/content/fr/intro.md index 895c0b721..4aeeaa6f8 100644 --- a/content/fr/intro.md +++ b/content/fr/intro.md @@ -1,7 +1,7 @@ Introduction ============ -A 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 : +À 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; From c4a9f0134a162ace4ee4fdc3f5b1e8568e137903 Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 13:59:51 +0100 Subject: [PATCH 256/472] Update codebase.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In french the translate of "library" is "bibliothèque", not "librairie" --- content/fr/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/codebase.md b/content/fr/codebase.md index 14bfabe04..56030f7d5 100644 --- a/content/fr/codebase.md +++ b/content/fr/codebase.md @@ -10,7 +10,7 @@ Une *base de code* correspond à chaque dépôt (dans un système de contrôle d Il y a toujours un rapport direct entre la base de code et l'application : * S'il y a plusieurs bases de code, ce n'est pas une application, c'est un système distribué. Chaque composant du système distribué est une application, et chacun peut individuellement respecter la méthodologie 12 facteurs. -* Plusieurs applications partageant le même code est une violation des 12 facteurs. La solution dans ce cas est de factoriser le code partagé dans des librairies qui peuvent être intégrées via un [gestionnaire de dépendances](./dependencies). +* Plusieurs applications partageant le même code est une violation des 12 facteurs. La solution dans ce cas est de factoriser le code partagé dans des bibliothèques qui peuvent être intégrées via un [gestionnaire de dépendances](./dependencies). Il y a seulement une base de code par application, mais il y aura plusieurs déploiements de l'application. Un *déploiement* est une instance en fonctionnement de l'application. C'est, par exemple, le site en production, ou bien un ou plusieurs sites de validation. En plus de cela, chaque développeur a une copie de l'application qui fonctionne dans son environnement local de développement, ce qui compte également comme un déploiement. From eeb141892c094165dc1b66356770f40a8b1d7918 Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 14:04:21 +0100 Subject: [PATCH 257/472] Update dependencies.md Same mistake about "library" fixed again. --- content/fr/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index 1205db958..80bb45fc9 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -1,7 +1,7 @@ ## II. Dépendances ### Déclarez explicitement et isolez les dépendances -La plupart des languages de programmation offrent des systèmes pour créer des paquets à partir de librairies afin de les distribuer, tel que [CPAN](http://www.cpan.org/) pour Perl ou [Rubygems](http://rubygems.org/) pour Ruby. Les librairies installées à travers un système de packaging peuvent être installés à travers tout le système, ou bien limités au répertoire contenant l'application (que l'on appelle les "vendor" ou "bundles") +La plupart des languages 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és à travers tout le système, ou bien limités 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épendances 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. From 34a478078c6a910f17397a27f19e9706ba7a8f7f Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 14:30:28 +0100 Subject: [PATCH 258/472] Update config.md Small correction, not sure about the "leur propres environnement particuliers" --- content/fr/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/config.md b/content/fr/config.md index 82cefee7d..f6f6bbee6 100644 --- a/content/fr/config.md +++ b/content/fr/config.md @@ -11,7 +11,7 @@ Les applications stockent parfois la configuration avec des constantes dans le c Un bon moyen de tester si une application a correctement séparé son code, c'est de se demander si l'application pourrait être rendu open-source à tout instant, sans compromettre d'identifiants. -Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connecté (en)](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé dans le code. +Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connectés (en)](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé dans le code. Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un language ou un framework. From 6de12bed40ad30437b1a95ac270db2ba092c747e Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 14:39:55 +0100 Subject: [PATCH 259/472] Update build-release-run.md French fixes --- content/fr/build-release-run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index 9a043a77d..587678acb 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -4,8 +4,8 @@ Une [base de code](./codebase) est transformée en un déploiement (non-développement) à travers les étapes suivantes : * L'*étapes d'assemblage* (ou "build") est une transformation qui convertit un dépôt de code en un paquet autonome exécutable appelé l'assemblage (ou "build"). En utilisant une version du code référencée par un commit spécifié lors du processus de déploiement, l'étape d'assemblage va chercher toutes les [dépendances externes](./dependencies) et compile les fichiers binaires et les ressources. -* L'*étape de publication * (ou "release") prend le l'assemblage produit à l'étape précédente et la combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'assemblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. -* L'*étape d'exécution* (ou "runtime") fait fonctionner l'application dans l'environnement d'exécution, en lancant un ensemble de [processus](./processes) de l'application associée à la release considérée. +* L'*étape de publication * (ou "release") prend l'assemblage produit à l'étape précédente et le combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'assemblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. +* L'*étape d'exécution* (ou "runtime") fait fonctionner l'application dans l'environnement d'exécution, en lançant un ensemble de [processus](./processes) de l'application associée à la release considérée. ![Le code devient un assemblage, qui est combiné à la configuration pour créer une release](/images/release.png) From 5d4aec65688fd08cb0a6cf57c8a5efbeb77abaff Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 14:47:42 +0100 Subject: [PATCH 260/472] Update port-binding.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Librairie => bibliothèque --- content/fr/port-binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/port-binding.md b/content/fr/port-binding.md index 4e90f9f42..9fb28e089 100644 --- a/content/fr/port-binding.md +++ b/content/fr/port-binding.md @@ -1,13 +1,13 @@ ## 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 [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 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 librairie de serveur web, tel que [Tornado](http://www.tornadoweb.org/) pour Python, [Thin](http://code.macournoyer.com/thin/) pour Ruby, ou [Jetty](http://jetty.codehaus.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. +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://jetty.codehaus.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)). From 325b9a02e1e0c589e649cbc1b6f952862682c3ad Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 14:55:03 +0100 Subject: [PATCH 261/472] Update disposability.md Link fixed --- content/fr/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/disposability.md b/content/fr/disposability.md index 371e1210f..f4d0062aa 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -3,7 +3,7 @@ **Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est à dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustesse des déploiements de production. -Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release)(./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. +Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release](./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. From 8a3a2b3409db3ceefb634fe074fba69142570de1 Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 15:00:01 +0100 Subject: [PATCH 262/472] Update dev-prod-parity.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Librairies => Bibliothèques --- content/fr/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index bdccc4471..1d9f85bbb 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -38,7 +38,7 @@ Si l'on résume cela en un tableau : -[Les services externes](./backing-services), tel que la base de données, la file de messages, ou le cache sont des éléments importants de la parité développement/production. La plupart des langages fournissent des librairies qui simplifient l'accès à ces services externes, en fournissant des adaptateurs pour différents types de services. Voici quelques exemples dans le tableau ci dessous. +[Les services externes](./backing-services), tel que la base de données, la file de messages, ou le cache sont des éléments importants de la parité développement/production. La plupart des langages fournissent des bibliothèques qui simplifient l'accès à ces services externes, en fournissant des adaptateurs pour différents types de services. Voici quelques exemples dans le tableau ci dessous. From 4766dcb015e8efd596a733b8dff3724b4d4fe031 Mon Sep 17 00:00:00 2001 From: Ben-J Date: Mon, 1 Feb 2016 15:02:51 +0100 Subject: [PATCH 263/472] Update logs.md Plural fix --- content/fr/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/logs.md b/content/fr/logs.md index a78bc6ac3..8b9e578b7 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -11,6 +11,6 @@ Dans les déploiements de validation ou de production, les flux de chaque proces Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepot de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : -* Trouver un événements spécifique dans le passé +* Trouver un événement spécifique dans le passé * Faire des graphiques à grande échelle des tendances (comme les requêtes par minutes) * Lever des alertes, à partir d'heuristiques définies par l'utilisateur (comme alerter dès que la quantité d'erreurs par minutes dépasse un certain seuil) From d20ac6a490574f8a33219b991e4c4b78298980d5 Mon Sep 17 00:00:00 2001 From: "sc.hwang" Date: Tue, 2 Feb 2016 13:26:48 +0900 Subject: [PATCH 264/472] proofreading codebase --- content/ko/codebase.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/ko/codebase.md b/content/ko/codebase.md index 1db1bb3fd..fc4e4ae17 100644 --- a/content/ko/codebase.md +++ b/content/ko/codebase.md @@ -1,17 +1,17 @@ ## I. 코드베이스 ### 버전 관리되는 하나의 코드베이스와 다양한 배포 -Twelve-Factor App은 항상 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/) 등의 버전 컨트롤 시스템을 사용하여 변화를 추적합니다. 수정 추적 데터베이스의 복사본은 *코드 저장소*라고 부르며, 짧게는 *저장소*라고도 합니다. +Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/) 같은 버전 컨트롤 시스템을 사용하여 변화를 추적하며, 버전 추적 데이터베이스의 사본을 *코드 저장소*, 줄여서 *저장소*라고 부른다. -*코드베이스*는 하나의 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우), 혹은 하나의 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)입니다. +*코드베이스*는 단일 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우) 일수도 있고, 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)일수도 있다. ![하나의 코드베스는 여러 배포로 매핑됩니다.](/images/codebase-deploys.png) -코드베이스와 애플리케이션 사이에는 항상 1대1 관계가 성립됩니다. +코드베이스와 앱 사이에는 항상 1대1 관계가 성립된다. -* 여러 코드베이스가 있는 경우, 그 것은 애플리케이션이 아닙니다 - 그 것은 분산 시스템입니다. 분산 시스템의 각 구성 요소는 애플리케이션이며, 개별적으로는 Twelve-Factor에 따르고 있을 수 있습니다. -* 하나의 코드를 공유하는 여러개의 앱은 Twelve-Factor를 위반합니다. 해결책은 공유되는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](/dependencies)에 통합시키는 것입니다. +* 코드베이스가 여러개 있는 경우, 앱이 아니라 분산 시스템으로 봐야한다. 분산 시스템의 개별 구성요소가 앱이 되며, 개별 앱이 Twelve-Factor를 따른다. +* 여러개 앱이 동일한 코드를 공유한다면 Twelve-Factor를 위반하는것이다. 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](/dependencies)로 관리한다. -애플리케이션 하나에는 오직 하나의 코드베이스가 존재하지만, 응용 프로그램의 배포는 여러개 존재합니다. 하나의 *배포*는 애플리케이션의 하나의 실행 중인 인스턴스 입니다. 이것은 일반적으로 하나의 production 공간과 하나 이상의 staging 공간입니다. 또한 모든 개발자는 자신의 로컬 개발 환경에 실행되는 애플리케이션 을 가지고 있으며, 이 것 역시 각각 하나의 배포로 볼 수 있습니다. +앱의 코드베이스는 한개여야 하지만, 앱 배포는 여러개가 될수 있다. *배포*는 앱의 실행중인 인스턴스를 가리킨다. 보통 운영 사이트와 여러 스테이징 사이트가 여기에 해당한다. 모든 개발자는 자신의 로컬 개발 환경에 실행되는 앱을 가지고 있는데, 이것 역시 하나의 배포로 볼 수 있다. -각 배포는 다른 버전이 활성화 되어있을 수도 있지만, 코드베이스는 모든 배포에 대해 동일합니다. 예를 들어, 개발자는 아직 staging 환경에 배포하지 않은 커밋을 가지고 있을 수 있으며, staging 환경에는 아직 production 환경에 배포되지 않은 커밋이 있을 수 있습니다. 하지만, 이런 모든 것들이 같은 코드베이스를 공유하고 있고, 같은 애플리케이션의 다른 배포라고 할 수 있습니다. \ No newline at end of file +배포마다 다른 버전이 활성화 될수 있지만, 코드베이스 자체는 모든 배포에 대해 동일하다. 예를 들어, 개발자는 아직 스테이징 환경에 배포하지 않은 커밋이 있을 수 있으며, 스테이징 환경에는 아직 운영 환경에 배포되지 않은 커밋이 있을 수 있다. 하지만 이 모든 것들이 같은 코드베이스를 공유하고, 같은 앱의 다른 배포라고 할 수 있다. \ No newline at end of file From 89743e695b478e40aca27d25a10171010c08fe44 Mon Sep 17 00:00:00 2001 From: Artur Szott Date: Thu, 4 Feb 2016 22:59:36 +0100 Subject: [PATCH 265/472] Add space around navigation links --- public/css/screen.css | 1 + 1 file changed, 1 insertion(+) diff --git a/public/css/screen.css b/public/css/screen.css index 0fcc2431e..798dff028 100644 --- a/public/css/screen.css +++ b/public/css/screen.css @@ -124,6 +124,7 @@ nav #prev { float: left; } nav #next a, nav #prev a { + display: block; font-size: 19pt; text-decoration: none; color: #000; From eabf30b012126532f79fef4bdbc0c3c6e350302a Mon Sep 17 00:00:00 2001 From: Vladimir Rutsky Date: Tue, 16 Feb 2016 16:13:00 +0300 Subject: [PATCH 266/472] typo: "build stage fetches and vendors [deps]" --- content/en/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/build-release-run.md b/content/en/build-release-run.md index a7215b0a1..83525c1ec 100644 --- a/content/en/build-release-run.md +++ b/content/en/build-release-run.md @@ -3,7 +3,7 @@ A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches vendors [dependencies](./dependencies) and compiles binaries and assets. * The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. * The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. From 4d1807bef9c3c733bd66b9de1734e37532e33028 Mon Sep 17 00:00:00 2001 From: Muhammad Panji Date: Wed, 24 Feb 2016 06:01:34 +0700 Subject: [PATCH 267/472] Initial translation Bahasa Indonesia --- content/id/admin-processes.md | 14 ++++++ content/id/background.md | 9 ++++ content/id/backing-services.md | 15 +++++++ content/id/build-release-run.md | 19 +++++++++ content/id/codebase.md | 18 ++++++++ content/id/concurrency.md | 14 ++++++ content/id/config.md | 22 ++++++++++ content/id/dependencies.md | 12 ++++++ content/id/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/id/disposability.md | 14 ++++++ content/id/intro.md | 12 ++++++ content/id/logs.md | 16 +++++++ content/id/port-binding.md | 14 ++++++ content/id/processes.md | 15 +++++++ content/id/toc.md | 38 +++++++++++++++++ content/id/who.md | 4 ++ locales/id.yml | 7 +++ 17 files changed, 319 insertions(+) create mode 100644 content/id/admin-processes.md create mode 100644 content/id/background.md create mode 100644 content/id/backing-services.md create mode 100644 content/id/build-release-run.md create mode 100644 content/id/codebase.md create mode 100644 content/id/concurrency.md create mode 100644 content/id/config.md create mode 100644 content/id/dependencies.md create mode 100644 content/id/dev-prod-parity.md create mode 100644 content/id/disposability.md create mode 100644 content/id/intro.md create mode 100644 content/id/logs.md create mode 100644 content/id/port-binding.md create mode 100644 content/id/processes.md create mode 100644 content/id/toc.md create mode 100644 content/id/who.md create mode 100644 locales/id.yml diff --git a/content/id/admin-processes.md b/content/id/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/id/admin-processes.md @@ -0,0 +1,14 @@ +## 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. diff --git a/content/id/background.md b/content/id/background.md new file mode 100644 index 000000000..b9ecf6fbd --- /dev/null +++ b/content/id/background.md @@ -0,0 +1,9 @@ +Background +========== + +The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. + +This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. + diff --git a/content/id/backing-services.md b/content/id/backing-services.md new file mode 100644 index 000000000..60e43fced --- /dev/null +++ b/content/id/backing-services.md @@ -0,0 +1,15 @@ +## IV. Backing Services +### Treat backing services as attached resources + +A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). + +Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). + +**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. + +Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. + +A production deploy attached to four backing services. + +Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. + diff --git a/content/id/build-release-run.md b/content/id/build-release-run.md new file mode 100644 index 000000000..a7215b0a1 --- /dev/null +++ b/content/id/build-release-run.md @@ -0,0 +1,19 @@ +## V. Build, release, run +### Strictly separate build and run stages + +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: + +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) + +**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. + +Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. + +Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. + +Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. + diff --git a/content/id/codebase.md b/content/id/codebase.md new file mode 100644 index 000000000..94a62f41e --- /dev/null +++ b/content/id/codebase.md @@ -0,0 +1,18 @@ +## I. Codebase +### One codebase tracked in revision control, many deploys + +A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. + +A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). + +![One codebase maps to many deploys](/images/codebase-deploys.png) + +There is always a one-to-one correlation between the codebase and the app: + +* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. +* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). + +There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. + +The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. + diff --git a/content/id/concurrency.md b/content/id/concurrency.md new file mode 100644 index 000000000..5ae4706b9 --- /dev/null +++ b/content/id/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrency +### Scale out via the process model + +Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. + +![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) + +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. + +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. + +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. + +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/id/config.md b/content/id/config.md new file mode 100644 index 000000000..0bc603b82 --- /dev/null +++ b/content/id/config.md @@ -0,0 +1,22 @@ +## III. Config +### Store config in the environment + +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: + +* Resource handles to the database, Memcached, and other [backing services](./backing-services) +* Credentials to external services such as Amazon S3 or Twitter +* Per-deploy values such as the canonical hostname for the deploy + +Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. + +A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. + +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. + +Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. + +**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. + +Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. + +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. diff --git a/content/id/dependencies.md b/content/id/dependencies.md new file mode 100644 index 000000000..bf5a2dd91 --- /dev/null +++ b/content/id/dependencies.md @@ -0,0 +1,12 @@ +## 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, [Gem Bundler](http://gembundler.com/) 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. diff --git a/content/id/dev-prod-parity.md b/content/id/dev-prod-parity.md new file mode 100644 index 000000000..f6e573342 --- /dev/null +++ b/content/id/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod parity +### Keep development, staging, and production as similar as possible + +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: + +* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The personnel gap**: Developers write code, ops engineers deploy it. +* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. + +**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: + +* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. +* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. +* Make the tools gap small: keep development and production as similar as possible. + +Summarizing the above into a table: + +
+ + + + + + + + + + + + + + + + + + + + +
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
+ +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. + +**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. + +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. + +Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/id/disposability.md b/content/id/disposability.md new file mode 100644 index 000000000..085f2d721 --- /dev/null +++ b/content/id/disposability.md @@ -0,0 +1,14 @@ +## 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](http://kr.github.com/beanstalkd/), 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). + + diff --git a/content/id/intro.md b/content/id/intro.md new file mode 100644 index 000000000..eff1d33d4 --- /dev/null +++ b/content/id/intro.md @@ -0,0 +1,12 @@ +Introduction +============ + +In the modern era, software is commonly delivered as a service: called *web apps*, or *software-as-a-service*. The twelve-factor app is a methodology for building software-as-a-service apps that: + +* Use **declarative** formats for setup automation, to minimize time and cost for new developers joining the project; +* Have a **clean contract** with the underlying operating system, offering **maximum portability** between execution environments; +* Are suitable for **deployment** on modern **cloud platforms**, obviating the need for servers and systems administration; +* **Minimize divergence** between development and production, enabling **continuous deployment** for maximum agility; +* And can **scale up** without significant changes to tooling, architecture, or development practices. + +The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc). diff --git a/content/id/logs.md b/content/id/logs.md new file mode 100644 index 000000000..ab2f4f829 --- /dev/null +++ b/content/id/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Treat logs as event streams + +*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. + +Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/id/port-binding.md b/content/id/port-binding.md new file mode 100644 index 000000000..8b3a0407e --- /dev/null +++ b/content/id/port-binding.md @@ -0,0 +1,14 @@ +## VII. Port binding +### Export services via port binding + +Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). + +**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. + +In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. + +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. + +HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). + +Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/id/processes.md b/content/id/processes.md new file mode 100644 index 000000000..dbd86a7c8 --- /dev/null +++ b/content/id/processes.md @@ -0,0 +1,15 @@ +## VI. Processes +### Execute the app as one or more stateless processes + +The app is executed in the execution environment as one or more *processes*. + +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). + +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. + +The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. + +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. + +Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). + diff --git a/content/id/toc.md b/content/id/toc.md new file mode 100644 index 000000000..8fbd8a792 --- /dev/null +++ b/content/id/toc.md @@ -0,0 +1,38 @@ +Dua Belas Faktor +================== + +## [I. Basis kode](./codebase) +### Satu basis kode dilacak dalam kontrol revisi, sebarkan berkali-kali + +## [II. Dependensi](./dependencies) +### Deklarasi dan isolasi dependensi secara eksplisit + +## [III. Konfigurasi](./config) +### Letakkan konfigurasi di lingkungan + +## [IV. Layanan Pendukung](./backing-services) +### Perlakukan layanan pendukung sebagai sumber daya attached + +## [V. Bangun, rilis, jalankan](./build-release-run) +### Pisahkan dengan ketat tahap build dan run + +## [VI. Processes](./processes) +### Jalankan aplikasi sebagai satu atau lebih proses stateless + +## [VII. Port binding](./port-binding) +### Ekspor layanan menggunakan port binding + +## [VIII. Konkurensi](./concurrency) +### Scale out menggunakan model proses + +## [IX. Keterbuangan](./disposability) +### Maksimalkan kekuatan dengan startup cepat dan graceful shutdown + +## [X. Perbedaan Dev/prod](./dev-prod-parity) +### Buat development, staging, dan production semirip mungkin + +## [XI. Logs](./logs) +### Perlakukan log sebagai arus peristiwa + +## [XII. Proses Admin](./admin-processes) +### Jalankan pekerjaan admin / manajemen sebagai proses sekali jalan diff --git a/content/id/who.md b/content/id/who.md new file mode 100644 index 000000000..49eb40fd5 --- /dev/null +++ b/content/id/who.md @@ -0,0 +1,4 @@ +Who should read this document? +============================== + +Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. diff --git a/locales/id.yml b/locales/id.yml new file mode 100644 index 000000000..c33e630f9 --- /dev/null +++ b/locales/id.yml @@ -0,0 +1,7 @@ +id: + # Name of language listed in locales menu + language: Indonesian (id) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Teks ini adalah terjemahan" From 25da190254cd471990b43c189042e2ca0660e690 Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Wed, 24 Feb 2016 10:16:36 -0300 Subject: [PATCH 268/472] Removing an word to improve concordances and eliminate a repeated word --- content/pt_br/backing-services.md | 2 +- content/pt_br/dependencies.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/backing-services.md b/content/pt_br/backing-services.md index 1a6ce82d8..589124ba0 100644 --- a/content/pt_br/backing-services.md +++ b/content/pt_br/backing-services.md @@ -5,7 +5,7 @@ Um *serviço de apoio* é qualquer serviço que o app consuma via rede como part Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). -**O código para um app doze-fatores não faz distinção entre serviços locais e de terceiros.** Para o app, ambos são recursos anexados, acessíveis via uma URL ou outro localizador/credenciais na [config](./config). Um [deploy](./codebase) do app doze-fatores deve ser ser capaz de trocar um banco de dados MySQL por um gerenciado por terceiros (tais como [Amazon RDS](http://aws.amazon.com/rds/)) sem realizar quaisquer mudanças no código do app. Da mesma forma, um servidor local SMTP poderia ser trocado por um serviço de terceiros (tais como Postmark) sem as mudanças em código. Em ambos os casos, apenas o identificador de recurso precisa mudar. +**O código para um app doze-fatores não faz distinção entre serviços locais e de terceiros.** Para o app, ambos são recursos anexados, acessíveis via uma URL ou outro localizador/credenciais na [config](./config). Um [deploy](./codebase) do app doze-fatores deve ser capaz de trocar um banco de dados MySQL por um gerenciado por terceiros (tais como [Amazon RDS](http://aws.amazon.com/rds/)) sem realizar quaisquer mudanças no código do app. Da mesma forma, um servidor local SMTP poderia ser trocado por um serviço de terceiros (tais como Postmark) sem as mudanças em código. Em ambos os casos, apenas o identificador de recurso precisa mudar. Cada serviço de apoio distinto é um *recurso*. Por exemplo, um banco MySQL é um recurso; dois bancos MySQL (usados para sharding na camada da aplicação) qualificam como dois recursos distintos. O app doze-fatores trata tais bancos como *recursos anexados*, o que indica seu baixo acoplamento ao deploy que ele está anexado. diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 1f176a35a..7260ece11 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -5,7 +5,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. -Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer isolamento dependência. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. +Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. From b0df3daa6c890fccf69a9221f0780f8aaff60a43 Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Wed, 24 Feb 2016 10:47:43 -0300 Subject: [PATCH 269/472] =?UTF-8?q?Change=20a=20double=20use=20of=20"depen?= =?UTF-8?q?d=C3=AAncia"=20word?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 7260ece11..21ddbdb16 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -5,7 +5,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. -Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento de dependência. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. +Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. From 45f205e01ae10dbc9d194512c77ebed9de1e008d Mon Sep 17 00:00:00 2001 From: Joseph Mastey Date: Thu, 10 Mar 2016 10:32:36 -0600 Subject: [PATCH 270/472] Update title casing for background services Other titles are in Sentence case, but backing services got away with Title Case. Burn the heretic. --- content/en/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/backing-services.md b/content/en/backing-services.md index 60e43fced..2f8551947 100644 --- a/content/en/backing-services.md +++ b/content/en/backing-services.md @@ -1,4 +1,4 @@ -## IV. Backing Services +## IV. Backing services ### Treat backing services as attached resources A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). From c95023003aa9a4dc7d401e5135a3ec14e2d71685 Mon Sep 17 00:00:00 2001 From: Yakov Date: Fri, 11 Mar 2016 19:48:23 +0300 Subject: [PATCH 271/472] Typo (RU) --- content/ru/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/build-release-run.md b/content/ru/build-release-run.md index 0bdfd2de7..5c08d6993 100644 --- a/content/ru/build-release-run.md +++ b/content/ru/build-release-run.md @@ -15,4 +15,4 @@ Каждый релиз должен иметь уникальный идентификатор, такой как отметка времени релиза (например `2015-04-06-15:42:17`) или увеличивающееся число (например `v100`). Релизы могут только добавляться и каждый релиз невозможно изменить после его создания. Любые изменения обязаны создавать новый релиз. -Сборка инициируется разработчиком приложения всяких раз, когда разворачивается новый код. Запуск этапа выполнения, напротив, может происходить автоматически в таких случаях, как перезагрузка сервера, или перезапуск упавшего процесса менеджером процессов. Таким образом, этап выполнения должен быть как можно более технически простым, так как проблемы, которые могут помешать приложению запуститься могут возникнуть в середине ночи, когда нет доступных разработчиков. Этап сборки может быть более сложным, так как возможные ошибки всегда видимы разработчику, который запустил развёртывание. +Сборка инициируется разработчиком приложения всякий раз, когда разворачивается новый код. Запуск этапа выполнения, напротив, может происходить автоматически в таких случаях, как перезагрузка сервера, или перезапуск упавшего процесса менеджером процессов. Таким образом, этап выполнения должен быть как можно более технически простым, так как проблемы, которые могут помешать приложению запуститься могут возникнуть в середине ночи, когда нет доступных разработчиков. Этап сборки может быть более сложным, так как возможные ошибки всегда видимы разработчику, который запустил развёртывание. From 9c1c7e81d4913a32f5b67e7fe67ece7a220a9822 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Sat, 19 Mar 2016 16:11:04 -0300 Subject: [PATCH 272/472] Fix typo in pt_br/toc.md: procesos -> processos --- content/pt_br/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index cffee5bc7..caf3e9be2 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -34,5 +34,5 @@ Os Doze Fatores ## [XI. Logs](./logs) ### Trate logs como fluxo de eventos -## [XII. Procesos de Admin](./admin-processes) +## [XII. Processos de Admin](./admin-processes) ### Executar tarefas de administração/gerenciamento como processos pontuais From 2228347579f9d8755cd0073ff8498feaf9d88776 Mon Sep 17 00:00:00 2001 From: Rogerio Prado de Jesus Date: Sat, 19 Mar 2016 16:22:08 -0300 Subject: [PATCH 273/472] =?UTF-8?q?Fix=20typo=20in=20pt=5Fbr:=20implata?= =?UTF-8?q?=C3=A7=C3=A3o=20=20->=20implanta=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index b009f76d6..ac774902c 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -7,7 +7,7 @@ Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvol * **A lacuna de pessoal:** Desenvolvedores escrevem código, engenheiros de operação fazem o deploy dele. * **A lacuna de ferramentas:** Desenvolvedores podem estar usando um conjunto como Nginx, SQLite, e OS X, enquanto o app em produção usa Apache, MySQL, e Linux. -**O App doze-fatores é projetado para [implatação contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: +**O App doze-fatores é projetado para [implantação contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: * Diminua a lacuna de tempo: um desenvolvedor pode escrever código e ter o deploy feito em horas ou até mesmo minutos depois. * Diminua a lacuna de pessoal: desenvolvedores que escrevem código estão proximamente envolvidos em realizar o deploy e acompanhar seu comportamento em produção. From edc64068481868214c7766c66d52b3fcd134cee2 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 21 Mar 2016 09:35:48 +0000 Subject: [PATCH 274/472] fix casing --- content/en/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/toc.md b/content/en/toc.md index 742cb8a5a..d8fbe2c5e 100644 --- a/content/en/toc.md +++ b/content/en/toc.md @@ -10,7 +10,7 @@ The Twelve Factors ## [III. Config](./config) ### Store config in the environment -## [IV. Backing Services](./backing-services) +## [IV. Backing services](./backing-services) ### Treat backing services as attached resources ## [V. Build, release, run](./build-release-run) From 60b1c744fe6896e456d5e4b13bb7a2066b036c35 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 21 Mar 2016 09:41:10 +0000 Subject: [PATCH 275/472] Revert "Initial translation Bahasa Indonesia" --- content/id/admin-processes.md | 14 ------ content/id/background.md | 9 ---- content/id/backing-services.md | 15 ------- content/id/build-release-run.md | 19 --------- content/id/codebase.md | 18 -------- content/id/concurrency.md | 14 ------ content/id/config.md | 22 ---------- content/id/dependencies.md | 12 ------ content/id/dev-prod-parity.md | 76 --------------------------------- content/id/disposability.md | 14 ------ content/id/intro.md | 12 ------ content/id/logs.md | 16 ------- content/id/port-binding.md | 14 ------ content/id/processes.md | 15 ------- content/id/toc.md | 38 ----------------- content/id/who.md | 4 -- locales/id.yml | 7 --- 17 files changed, 319 deletions(-) delete mode 100644 content/id/admin-processes.md delete mode 100644 content/id/background.md delete mode 100644 content/id/backing-services.md delete mode 100644 content/id/build-release-run.md delete mode 100644 content/id/codebase.md delete mode 100644 content/id/concurrency.md delete mode 100644 content/id/config.md delete mode 100644 content/id/dependencies.md delete mode 100644 content/id/dev-prod-parity.md delete mode 100644 content/id/disposability.md delete mode 100644 content/id/intro.md delete mode 100644 content/id/logs.md delete mode 100644 content/id/port-binding.md delete mode 100644 content/id/processes.md delete mode 100644 content/id/toc.md delete mode 100644 content/id/who.md delete mode 100644 locales/id.yml diff --git a/content/id/admin-processes.md b/content/id/admin-processes.md deleted file mode 100644 index 870a56096..000000000 --- a/content/id/admin-processes.md +++ /dev/null @@ -1,14 +0,0 @@ -## 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. diff --git a/content/id/background.md b/content/id/background.md deleted file mode 100644 index b9ecf6fbd..000000000 --- a/content/id/background.md +++ /dev/null @@ -1,9 +0,0 @@ -Background -========== - -The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. - -This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). - -Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. - diff --git a/content/id/backing-services.md b/content/id/backing-services.md deleted file mode 100644 index 60e43fced..000000000 --- a/content/id/backing-services.md +++ /dev/null @@ -1,15 +0,0 @@ -## IV. Backing Services -### Treat backing services as attached resources - -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). - -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). - -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. - -Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. - -A production deploy attached to four backing services. - -Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. - diff --git a/content/id/build-release-run.md b/content/id/build-release-run.md deleted file mode 100644 index a7215b0a1..000000000 --- a/content/id/build-release-run.md +++ /dev/null @@ -1,19 +0,0 @@ -## V. Build, release, run -### Strictly separate build and run stages - -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: - -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. - -![Code becomes a build, which is combined with config to create a release.](/images/release.png) - -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. - -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. - -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. - -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. - diff --git a/content/id/codebase.md b/content/id/codebase.md deleted file mode 100644 index 94a62f41e..000000000 --- a/content/id/codebase.md +++ /dev/null @@ -1,18 +0,0 @@ -## I. Codebase -### One codebase tracked in revision control, many deploys - -A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. - -A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). - -![One codebase maps to many deploys](/images/codebase-deploys.png) - -There is always a one-to-one correlation between the codebase and the app: - -* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. -* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). - -There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. - -The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. - diff --git a/content/id/concurrency.md b/content/id/concurrency.md deleted file mode 100644 index 5ae4706b9..000000000 --- a/content/id/concurrency.md +++ /dev/null @@ -1,14 +0,0 @@ -## VIII. Concurrency -### Scale out via the process model - -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. - -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) - -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. - -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. - -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. - -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/id/config.md b/content/id/config.md deleted file mode 100644 index 0bc603b82..000000000 --- a/content/id/config.md +++ /dev/null @@ -1,22 +0,0 @@ -## III. Config -### Store config in the environment - -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: - -* Resource handles to the database, Memcached, and other [backing services](./backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy - -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. - -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. - -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. - -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. - -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. - -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. - -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. diff --git a/content/id/dependencies.md b/content/id/dependencies.md deleted file mode 100644 index bf5a2dd91..000000000 --- a/content/id/dependencies.md +++ /dev/null @@ -1,12 +0,0 @@ -## 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, [Gem Bundler](http://gembundler.com/) 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. diff --git a/content/id/dev-prod-parity.md b/content/id/dev-prod-parity.md deleted file mode 100644 index f6e573342..000000000 --- a/content/id/dev-prod-parity.md +++ /dev/null @@ -1,76 +0,0 @@ -## X. Dev/prod parity -### Keep development, staging, and production as similar as possible - -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: - -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. - -**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: - -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. - -Summarizing the above into a table: - - - - - - - - - - - - - - - - - - - - - - -
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
- -[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
- -Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. - -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. - -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. - -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/id/disposability.md b/content/id/disposability.md deleted file mode 100644 index 085f2d721..000000000 --- a/content/id/disposability.md +++ /dev/null @@ -1,14 +0,0 @@ -## 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](http://kr.github.com/beanstalkd/), 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). - - diff --git a/content/id/intro.md b/content/id/intro.md deleted file mode 100644 index eff1d33d4..000000000 --- a/content/id/intro.md +++ /dev/null @@ -1,12 +0,0 @@ -Introduction -============ - -In the modern era, software is commonly delivered as a service: called *web apps*, or *software-as-a-service*. The twelve-factor app is a methodology for building software-as-a-service apps that: - -* Use **declarative** formats for setup automation, to minimize time and cost for new developers joining the project; -* Have a **clean contract** with the underlying operating system, offering **maximum portability** between execution environments; -* Are suitable for **deployment** on modern **cloud platforms**, obviating the need for servers and systems administration; -* **Minimize divergence** between development and production, enabling **continuous deployment** for maximum agility; -* And can **scale up** without significant changes to tooling, architecture, or development practices. - -The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc). diff --git a/content/id/logs.md b/content/id/logs.md deleted file mode 100644 index ab2f4f829..000000000 --- a/content/id/logs.md +++ /dev/null @@ -1,16 +0,0 @@ -## XI. Logs -### Treat logs as event streams - -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. - -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. - -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. - -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. - -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: - -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/id/port-binding.md b/content/id/port-binding.md deleted file mode 100644 index 8b3a0407e..000000000 --- a/content/id/port-binding.md +++ /dev/null @@ -1,14 +0,0 @@ -## VII. Port binding -### Export services via port binding - -Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). - -**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. - -In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. - -This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. - -HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). - -Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/id/processes.md b/content/id/processes.md deleted file mode 100644 index dbd86a7c8..000000000 --- a/content/id/processes.md +++ /dev/null @@ -1,15 +0,0 @@ -## VI. Processes -### Execute the app as one or more stateless processes - -The app is executed in the execution environment as one or more *processes*. - -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). - -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. - -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. - -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. - -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). - diff --git a/content/id/toc.md b/content/id/toc.md deleted file mode 100644 index 8fbd8a792..000000000 --- a/content/id/toc.md +++ /dev/null @@ -1,38 +0,0 @@ -Dua Belas Faktor -================== - -## [I. Basis kode](./codebase) -### Satu basis kode dilacak dalam kontrol revisi, sebarkan berkali-kali - -## [II. Dependensi](./dependencies) -### Deklarasi dan isolasi dependensi secara eksplisit - -## [III. Konfigurasi](./config) -### Letakkan konfigurasi di lingkungan - -## [IV. Layanan Pendukung](./backing-services) -### Perlakukan layanan pendukung sebagai sumber daya attached - -## [V. Bangun, rilis, jalankan](./build-release-run) -### Pisahkan dengan ketat tahap build dan run - -## [VI. Processes](./processes) -### Jalankan aplikasi sebagai satu atau lebih proses stateless - -## [VII. Port binding](./port-binding) -### Ekspor layanan menggunakan port binding - -## [VIII. Konkurensi](./concurrency) -### Scale out menggunakan model proses - -## [IX. Keterbuangan](./disposability) -### Maksimalkan kekuatan dengan startup cepat dan graceful shutdown - -## [X. Perbedaan Dev/prod](./dev-prod-parity) -### Buat development, staging, dan production semirip mungkin - -## [XI. Logs](./logs) -### Perlakukan log sebagai arus peristiwa - -## [XII. Proses Admin](./admin-processes) -### Jalankan pekerjaan admin / manajemen sebagai proses sekali jalan diff --git a/content/id/who.md b/content/id/who.md deleted file mode 100644 index 49eb40fd5..000000000 --- a/content/id/who.md +++ /dev/null @@ -1,4 +0,0 @@ -Who should read this document? -============================== - -Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. diff --git a/locales/id.yml b/locales/id.yml deleted file mode 100644 index c33e630f9..000000000 --- a/locales/id.yml +++ /dev/null @@ -1,7 +0,0 @@ -id: - # Name of language listed in locales menu - language: Indonesian (id) - - # A text to make known that the article is a translation not an original. - # Empty for English, original. - translation: "Teks ini adalah terjemahan" From df35d3d1a7d55e0de9f94550624b1ad3953cbd03 Mon Sep 17 00:00:00 2001 From: Christian Koep Date: Mon, 4 Apr 2016 13:44:49 +0200 Subject: [PATCH 276/472] Fixed German translation error (build-release-run) --- content/de/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/build-release-run.md b/content/de/build-release-run.md index ca94f9e79..1839025b7 100644 --- a/content/de/build-release-run.md +++ b/content/de/build-release-run.md @@ -1,7 +1,7 @@ ## V. Build, release, run ### Build- und Run-Phase strikt trennen -Eine [Codebase](./codebase) durch drei Phasen in einen (Nicht-Entwicklungs)-Deploy transformiert: +Eine [Codebase](./codebase) wird durch drei Phasen in einen (Nicht-Entwicklungs)-Deploy transformiert: * 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. From 37e9e4b07ddf113c21e1ae1728b400b9b4552432 Mon Sep 17 00:00:00 2001 From: Francisco Capdevila Date: Fri, 15 Apr 2016 15:22:45 -0300 Subject: [PATCH 277/472] Fix typo. --- content/es/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/build-release-run.md b/content/es/build-release-run.md index e64310b15..c37f0adee 100644 --- a/content/es/build-release-run.md +++ b/content/es/build-release-run.md @@ -11,7 +11,7 @@ El [código base](./codebase) se transforma en un despliegue (que no es de desar **Las aplicaciones "twelve-factor" hacen una separación completa de las fases de construcción, de distribución y de ejecución.** Por ejemplo, es imposible hacer cambios en el código en la fase de ejecución, porque no hay una manera de propagar dichos cambios a la fase de construcción. -Las herramientas de despliegue ofrecen, normalmente, herramientas de gestión de distribuciones (releases). La capacidad de volver a una versuón anterior es especialmente útil. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. +Las herramientas de despliegue ofrecen, normalmente, herramientas de gestión de distribuciones (releases). La capacidad de volver a una versión anterior es especialmente útil. Por ejemplo, la herramienta de despliegues [Capistrano](https://github.com/capistrano/capistrano/wiki) almacena distribuciones en un subdirectorio llamado `releases`, donde la distribución actual es un enlace simbólico al directorio de la distribución actual. Su mandato `rollback` hace fácil y rápidamente el trabajo de volver a la versión anterior. Cada distribución debería tener siempre un identificador único de distribución, como por ejemplo una marca de tiempo (timestamp) de la distribución (`2011-04-06-20:32:17`) o un número incremental (como `v100`). Las distribuciones son como un libro de contabilidad, al que solo se le pueden agregar registros y no pueden ser modificados una vez son creados. Cualquier cambio debe crear una nueva distribución. From 9066d59711a8a116b71288dde79176cfedc011ca Mon Sep 17 00:00:00 2001 From: Francisco Capdevila Date: Fri, 15 Apr 2016 15:41:35 -0300 Subject: [PATCH 278/472] Typo. --- content/es/port-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/port-binding.md b/content/es/port-binding.md index 39939235f..b48fe93f3 100644 --- a/content/es/port-binding.md +++ b/content/es/port-binding.md @@ -7,7 +7,7 @@ Las aplicaciones web se ejecutan a menudo mediante contenedores web. Por ejemplo En los entornos de desarrollo, los desarrolladores usan una URL del servicio (por ejemplo `http://localhost:5000/`), para acceder al servicio que ofrece la aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una dirección pública se redirijan hacia el proceso web que tiene asignado su puerto correspondiente. -Esto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Maquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. +Esto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Máquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. HTTP no es el único servicio que usa asignación de puertos. La verdad, es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigna un puerto y queda a la espera de peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). From eafef193dcd44ce9e36ced7f99e7d95343b5ff76 Mon Sep 17 00:00:00 2001 From: Francisco Capdevila Date: Fri, 15 Apr 2016 15:45:38 -0300 Subject: [PATCH 279/472] Update port-binding.md --- content/es/port-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/port-binding.md b/content/es/port-binding.md index b48fe93f3..ff2b451d4 100644 --- a/content/es/port-binding.md +++ b/content/es/port-binding.md @@ -7,7 +7,7 @@ Las aplicaciones web se ejecutan a menudo mediante contenedores web. Por ejemplo En los entornos de desarrollo, los desarrolladores usan una URL del servicio (por ejemplo `http://localhost:5000/`), para acceder al servicio que ofrece la aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una dirección pública se redirijan hacia el proceso web que tiene asignado su puerto correspondiente. -Esto se implementa, normalmente, usando una [declaracion de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Máquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. +Esto se implementa, normalmente, usando una [declaración de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Máquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. HTTP no es el único servicio que usa asignación de puertos. La verdad, es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigna un puerto y queda a la espera de peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). From 8c8b1fd6ad33fe2b1e3ba044cb8c13c771d2f4a8 Mon Sep 17 00:00:00 2001 From: Francisco Capdevila Date: Fri, 15 Apr 2016 16:27:09 -0300 Subject: [PATCH 280/472] Fix typos. --- content/es/dev-prod-parity.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md index abedbc197..7821774b9 100644 --- a/content/es/dev-prod-parity.md +++ b/content/es/dev-prod-parity.md @@ -38,7 +38,7 @@ Resumiendo lo anterior en una tabla: -Los ["backing services"](./backing-services), como la base de datos de la aplicación, el sistema de colas, o la cache, es donde la igualdad en los entornos de desarrollo y producción es importante. Muchos lenguajes ofrecen librerías en las que se simplifica el acceso a los servicios de respaldo, incluidos *adaptadores* para diferentes tipos de servicios. Se pueden observar algunos ejemplos en la siguiente tabla. +Los ["backing services"](./backing-services), como la base de datos de la aplicación, el sistema de colas, o la caché, es donde la igualdad en los entornos de desarrollo y producción es importante. Muchos lenguajes ofrecen librerías en las que se simplifica el acceso a los servicios de respaldo, incluidos *adaptadores* para diferentes tipos de servicios. Se pueden observar algunos ejemplos en la siguiente tabla. @@ -60,14 +60,14 @@ Los ["backing services"](./backing-services), como la base de datos de la aplica - +
RabbitMQ, Beanstalkd, Redis
CacheCaché Ruby/Rails ActiveSupport::Cache Memoria, sistema de ficheros, Memcached
-Los desarrolladores, a veces, caen en la tentación de usar "backing services" ligeros en sus entornos de desarrollo, mientras que en producción se usan los más serios y robustos. Por ejemplo, se usa SQLite en desarrollo y PostgreSQL en producción; o memoria local para la cache en desarrollo y Memcached en producción. +Los desarrolladores, a veces, caen en la tentación de usar "backing services" ligeros en sus entornos de desarrollo, mientras que en producción se usan los más serios y robustos. Por ejemplo, se usa SQLite en desarrollo y PostgreSQL en producción; o memoria local para la caché en desarrollo y Memcached en producción. **Un desarrollador "twelve-factor" no cae en la tentación de usar diferentes "backing services" en desarrollo y producción**, incluso cuando los adaptadores teóricamente abstractos están lejos de cualquier diferencia en "backing services". Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que surgen de la nada, causando que el código que funciona y pasa los tests en desarrollo o en preproducción, falle en producción. Este tipo de errores provocan conflictos que desincentivan la filosofía del despliegue continuo. El coste de estos conflictos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se hace balance del total de tiempo de vida de una aplicación. From eacf88ee6c180d4af2317f23aab69dbb8fc35393 Mon Sep 17 00:00:00 2001 From: Francisco Capdevila Date: Fri, 15 Apr 2016 17:04:17 -0300 Subject: [PATCH 281/472] Fix unbalanced parenthesis. --- content/es/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/logs.md b/content/es/logs.md index 62bab9437..4900e1226 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -7,7 +7,7 @@ Los historiales son la [transmisión](http://adam.heroku.com/past/2011/4/1/logs_ **Una aplicación "twelve-factor" nunca se preocupa del direccionamiento o el almacenamiento de sus transmisiones de salida.** No debería intentar escribir o gestionar ficheros de historial. En su lugar, cada proceso en ejecución escribe sus eventos a la `salida estándar` (o `stdout`). Durante el desarrollo, los desarrolladores verán el flujo en su terminal para observar el comportamiento de la aplicación. -En despliegues de preproducción y producción, cada transmisión del proceso será capturada por el entorno de ejecución, siendo capturadas junto con todos los otros flujos de la aplicación, y redirigidas a uno o más destinos finales para ser revisadas y archivadas. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales, (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd) se usan con este objetivo. +En despliegues de preproducción y producción, cada transmisión del proceso será capturada por el entorno de ejecución, siendo capturadas junto con todos los otros flujos de la aplicación, y redirigidas a uno o más destinos finales para ser revisadas y archivadas. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd)) se usan con este objetivo. Las transmisiones de eventos para una aplicación pueden ser redirigidas a un fichero u observadas en tiempo real mediante un "tail" en un terminal. Cabe destacar que la transmisión se puede enviar a un sistema de análisis e indexado como [Splunk](http://www.splunk.com/), o a un sistema de almacenamiendo de datos de propósito general como [Hadoop/Hive](http://hive.apache.org/). Estos sistemas se tienen en cuenta por el gran poder y la flexibilidad para inspeccionar el comportamiento de la aplicación a lo largo del tiempo, incluyendo: From a32e38af84f4ca9e985aa60aeb3b332a4ca85c26 Mon Sep 17 00:00:00 2001 From: Seth Bergman Date: Sun, 17 Apr 2016 08:50:55 -0500 Subject: [PATCH 282/472] Added files via upload --- public/images/favicon.png | Bin 0 -> 1989 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/favicon.png diff --git a/public/images/favicon.png b/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4d4245a9cbc7e64335545f0b012fbed3475887d8 GIT binary patch literal 1989 zcmV;$2RitPP)dYnOmroWfX?EIo-Y~;F#oRS^$Sw<)=YZnrA@_yig))D210^30^Az7F$+$VDY|4y+ z2fu#|caok@Wc`H^)<6EauQ!8e=JT` zyf)QMlQ@Dt`i)cTYY9P&H`O*-#J5UJk$F90@)7iR-kkEDpIv8@6^(btX(?V>(nCH6 zbQ;ZWL`q`Q<$uXc+gLM4*C7I0~P;ORB8$<`a z2HGeOvL;Rju-r2TAR4ZF2C#mN7Y zN1r(!?1TO2XMnMta#@^{D|}XK?w6BgR@M(Fe3{AZM^b8MvoJWj4a}3O9A02M4;Yt;K!-qx= z{$<4;@e5S^q69xT4}Al3nP2dVg->ezw9JF2&2v}zqSos|-MHjE=(8FgT@U8^de3Xn ziqk~=!F7&keUgm&RWdtDv>e?e<4$C~-jk%ww+aFWn%do2@f>j)5~} ze&gJZ>b{>)_qS2{(TT?j^SU-i+>;2T*AyE#1~ytC&t2m@S)B%Tc<>GA_+y1RS)FXs zk!NbXPiFWnEe^^rl-2e7I(+(o>99thIi6dri$xhh`S?NNSLK#f@T)ZGqu&Gl(w-*2 zQE%4|%l!Aqz`t7Gw4hHY&(Jx2U?p3pQnm-qL^vi4d%B~1~9_Wt9?1bp)>q&_0 za~l*Jw%bB}L{=)Qn%A(kJy?}H@Om4RF0W9&@`9ckJRdS_2;OjWT;=r)s@N z2B`HsYUPZJr*2oBKKiYWuGN@l`N9{AOmUKOc8lWnGqh4swV z+Ftl0TE}C@A1mCF24=Hs#Bj}^ZO`q2UCqHlUV zz9&&aMwI_n0xvpV@h6>Z_p#%T73%Pqgb|X>{TcX&m&{|g`??G((@Bn>2Z}n1NT98mx?OCP? z$7I*bjQcuC0dG0#@Bn?5Z{!=1GNL?nyJX-y*>o9Nm&&+Gcw+L@0epMPsWq}jq!O`3 z%G>IAzwdc{H-sUNDmEsydvj%E%!zO6GE$!lW`EyeZ zPYkHT8)()*O<~v^#fN0zT^V-`JRnbf;5h>~hM}tz8#dZPp8QZVhH4JO-*FpbNj$WE z=SAK98GGPpraHfpohI8Wn Date: Sun, 17 Apr 2016 08:56:04 -0500 Subject: [PATCH 283/472] Added reference to favicon --- views/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/layout.erb b/views/layout.erb index b36f824a2..897044eb4 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -8,7 +8,7 @@ - + From a83efaf04dd1627e898c3bbb7f39e074fb1d3ac6 Mon Sep 17 00:00:00 2001 From: Seth Bergman Date: Sun, 17 Apr 2016 08:59:22 -0500 Subject: [PATCH 284/472] Update background.md Links open in new tab --- content/en/background.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/background.md b/content/en/background.md index b9ecf6fbd..9be3f1677 100644 --- a/content/en/background.md +++ b/content/en/background.md @@ -1,9 +1,9 @@ Background ========== -The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. +The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the Heroku platform. -This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and avoiding the cost of software erosion. -Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *Patterns of Enterprise Application Architecture* and *Refactoring*. From 71630bdfc10ce6d370bf81aba00482c366553325 Mon Sep 17 00:00:00 2001 From: Pierre Baillet Date: Thu, 21 Apr 2016 15:12:52 +0200 Subject: [PATCH 285/472] Typos for french --- content/fr/admin-processes.md | 2 +- content/fr/backing-services.md | 2 +- content/fr/config.md | 4 ++-- content/fr/dependencies.md | 4 ++-- content/fr/disposability.md | 2 +- content/fr/logs.md | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/content/fr/admin-processes.md b/content/fr/admin-processes.md index 69ff90f02..5e51ba20a 100644 --- a/content/fr/admin-processes.md +++ b/content/fr/admin-processes.md @@ -11,4 +11,4 @@ Les processus ponctuels d'administration devraient être lancés dans un environ La même technique d'[isolation de dépendances](./dependencies) doit être utilisée sur tous les types de processus. Par exemple, si le processus web de Ruby utilise la commande `bundle exec thin start`, alors une migration de base de données devrait être faite via `bundle exec rake db:migrate`. De la même manière, un programme Python qui utilise Virtualenv devrait utiliser la commande incluse `bin/python` pour lancer à la fois le serveur web Tornado et tout processus administrateur `manage.py`. -Les applications 12 facteurs préfèrent les languages qui fournissent un terminal REPL prêt à l'emploi, et qui facilitent l'exécution de scripts ponctuels. Dans un déploiement local, les développeurs invoquent les processus ponctuels d'administration depuis le terminal, par une commande directement dans le répertoire où se trouve l'application. Dans un déploiement de production, les développeurs peuvent utiliser ssh ou d'autres mécanismes d'exécution de commandes fournis par l'environnement d'exécution de ce déploiement pour exécuter un tel processus. +Les applications 12 facteurs préfèrent les langages qui fournissent un terminal REPL prêt à l'emploi, et qui facilitent l'exécution de scripts ponctuels. Dans un déploiement local, les développeurs invoquent les processus ponctuels d'administration depuis le terminal, par une commande directement dans le répertoire où se trouve l'application. Dans un déploiement de production, les développeurs peuvent utiliser ssh ou d'autres mécanismes d'exécution de commandes fournis par l'environnement d'exécution de ce déploiement pour exécuter un tel processus. diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md index 7913f39e2..37cd5d2fc 100644 --- a/content/fr/backing-services.md +++ b/content/fr/backing-services.md @@ -11,4 +11,4 @@ Chaque service externe est une *ressource*. Par exemple, une base de données My Un déploiement de production lié à quatre services externes. -Les resources peuvent être attachées et détachées à volonté à des déploiements. Par exemple, si la base de données de l'application pose problème pour des raisons matérielles, l'administrateur de l'application peut vouloir lancer un nouveau serveur de base de données restauré à partir d'une sauvegarde récente. L'application courante pourrait être détachée à l'ancienne, puis rattachée à la nouvelle — le tout sans changement dans le code. +Les resources peuvent être attachées et détachées à volonté à des déploiements. Par exemple, si la base de données de l'application pose problème pour des raisons matérielles, l'administrateur de l'application peut vouloir lancer un nouveau serveur de base de données restauré à partir d'une sauvegarde récente. L'application courante pourrait être détachée de l'ancienne, puis rattachée à la nouvelle — le tout sans changement dans le code. diff --git a/content/fr/config.md b/content/fr/config.md index f6f6bbee6..94fe08163 100644 --- a/content/fr/config.md +++ b/content/fr/config.md @@ -1,7 +1,7 @@ ## III. Configuration ### Stockez la configuration dans l'environnement -La *configuration* d'une application est tout ce qui est susceptible de varier entre des [déploiements](./codebase) (validation, production, environnement de développement, etc). Cela inclue : +La *configuration* d'une application est tout ce qui est susceptible de varier entre des [déploiements](./codebase) (validation, production, environnement de développement, etc). Cela inclut : * Les ressources gérées par la base de données, Memcached, ou tout autre [service de stockage](./backing-services) * Les identifiants pour des services externes, tel qu'Amazon S3 ou Twitter @@ -13,7 +13,7 @@ Un bon moyen de tester si une application a correctement séparé son code, c'es Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connectés (en)](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé dans le code. -Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un language ou un framework. +Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un langage ou un framework. **Les applications 12 facteurs stockent la configuration dans des *variables d'environnement*** (souvent raccourcies en *variables d'env*, ou *env*). Les variables d'environnement sont faciles à changer entre des déploiements sans changer le moindre code ; contrairement aux fichiers de configuration, il y a peu de chance pour qu'elles soient ajoutées au dépôt de code accidentellement ; et contrairement aux fichiers de configuration personnalisés, ou tout autre mécanisme de configuration comme les propriétés système Java, ce sont des standards agnostiques du langage ou du système d'exploitation. diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index 80bb45fc9..548b9903d 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -1,11 +1,11 @@ ## II. Dépendances ### Déclarez explicitement et isolez les dépendances -La plupart des languages 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és à travers tout le système, ou bien limités au répertoire contenant l'application (que l'on appelle les "vendor" ou "bundles") +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épendances 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, [Gem Bundler](http://gembundler.com/) 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. Peut importe la chaine 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. +Par exemple, [Gem Bundler](http://gembundler.com/) 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 chaine 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 oeil à 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`. diff --git a/content/fr/disposability.md b/content/fr/disposability.md index f4d0062aa..aac4fe309 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -5,7 +5,7 @@ Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release](./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. -Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problèmes lorsque la connection est perdue. +Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problème lorsque la connection est perdue. Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le worker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). diff --git a/content/fr/logs.md b/content/fr/logs.md index 8b9e578b7..30df80dae 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -1,7 +1,7 @@ ## XI. Logs ### Traitez les logs comme des flux d'évènements -Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits sur un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. +Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits dans un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. Les logs sont des [flux (en)](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. @@ -12,5 +12,5 @@ Dans les déploiements de validation ou de production, les flux de chaque proces Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepot de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : * Trouver un événement spécifique dans le passé -* Faire des graphiques à grande échelle des tendances (comme les requêtes par minutes) +* Faire des graphiques à grande échelle des tendances (comme le nombre de requêtes par minutes) * Lever des alertes, à partir d'heuristiques définies par l'utilisateur (comme alerter dès que la quantité d'erreurs par minutes dépasse un certain seuil) From a0369dfc3214b0d61e2c879e4a1ba8a7d4b9e4e1 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Tue, 3 May 2016 08:49:12 +0100 Subject: [PATCH 286/472] fix location --- public/images/{favicon.png => favicon.ico} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename public/images/{favicon.png => favicon.ico} (100%) diff --git a/public/images/favicon.png b/public/images/favicon.ico similarity index 100% rename from public/images/favicon.png rename to public/images/favicon.ico From 9aaaceddf2b3c7a1aeeab7b71fad873f5dcd3dd5 Mon Sep 17 00:00:00 2001 From: Artur Szott Date: Mon, 1 Feb 2016 20:23:57 +0100 Subject: [PATCH 287/472] Add polish locale and translate intro.md --- content/pl/intro.md | 12 ++++++++++++ locales/pl.yml | 7 +++++++ 2 files changed, 19 insertions(+) create mode 100644 content/pl/intro.md create mode 100644 locales/pl.yml diff --git a/content/pl/intro.md b/content/pl/intro.md new file mode 100644 index 000000000..1b5be75f5 --- /dev/null +++ b/content/pl/intro.md @@ -0,0 +1,12 @@ +Wprowadzenie +============ + +We współczesnym świecie oprogramowanie jest powszechnie wytwarzane w formie usługi, nazywane _software-as-sarvice (SaaS)_ lub aplikacjami internetowymi. Dwanaście aspektów aplikacji jest metodologią budowania aplikacji SaaS, które: + +* Używają **deklaratywnego** formatu by zautomatyzować konfigurację aplikacji w celu zmniejszenia czasu i kosztów dołączenia nowych programistów do projektu; +* Mają **czysty kontrakt** z systemem operacyjnym, umożliwiając **jak największą możliwość przenoszenia** pomiędzy środowiskami, w których działają; +* Są dopasowane do **wdrożenia** na nowoczesne **chmury obliczeniowe**, zapobiegając potrzebie użycia serwerów i administracji systemu; +* **Minimalizują rozbieżności** pomiędzy środowiskami developerskimi i produkcyjnymi, umożliwiając **nieustanne wdrażanie aplikacji** by zmaksymalizować prędkość zmian; +* I mogą **skalować się** bez większej zmiany narzędzi, architektury, czy sposobu pracy zespołu. + +Metodologia dwunastu aspektów może być stosowana do aplikacji napisanych w każdym języku programowania i wykorzystujących dowolną kombinację usług wspierających (bazy danych, kolejki, cache pamięci etc). diff --git a/locales/pl.yml b/locales/pl.yml new file mode 100644 index 000000000..fb77304b9 --- /dev/null +++ b/locales/pl.yml @@ -0,0 +1,7 @@ +pl: + # Name of language listed in locales menu + language: "Polski (pl)" + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "To jest tłumaczenie." From 2b46f670c0dea21cda88fbc41e6fffd14f913e88 Mon Sep 17 00:00:00 2001 From: Aaron D Borden Date: Tue, 17 May 2016 20:13:20 -0700 Subject: [PATCH 288/472] Fix links for HTTPS Everywhere --- content/de/concurrency.md | 4 ++-- content/de/logs.md | 4 ++-- content/en/concurrency.md | 2 +- content/en/logs.md | 2 +- content/es/concurrency.md | 2 +- content/es/logs.md | 2 +- content/fr/concurrency.md | 2 +- content/fr/logs.md | 2 +- content/it/concurrency.md | 4 ++-- content/it/logs.md | 4 ++-- content/ja/concurrency.md | 2 +- content/ja/logs.md | 2 +- content/ko/concurrency.md | 4 ++-- content/ko/logs.md | 4 ++-- content/pt_br/logs.md | 2 +- content/ru/concurrency.md | 2 +- content/ru/logs.md | 2 +- content/zh_cn/concurrency.md | 2 +- content/zh_cn/logs.md | 2 +- 19 files changed, 25 insertions(+), 25 deletions(-) diff --git a/content/de/concurrency.md b/content/de/concurrency.md index f92441b1e..0e60c78c0 100644 --- a/content/de/concurrency.md +++ b/content/de/concurrency.md @@ -5,10 +5,10 @@ Jedes Computerprogramm wird, wenn es läuft, repräsentiert durch einen oder meh ![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](http://adam.heroku.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 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. 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. 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. -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. \ No newline at end of file +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. diff --git a/content/de/logs.md b/content/de/logs.md index c31658ed1..f4ce2dbfb 100644 --- a/content/de/logs.md +++ b/content/de/logs.md @@ -3,7 +3,7 @@ *Logs* machen das Verhalten einer laufenden App sichtbar. In Server-basierten Umgebungen werden sie üblicherweise in eine Datei auf der Platte geschrieben (eine Logdatei) - das ist aber nur ein Ausgabeformat. -Logs sind der [Stream](http://adam.heroku.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) +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. @@ -13,4 +13,4 @@ Der Stream von Ereignissen für eine App kann in eine Datei geleitet werden oder * 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). \ No newline at end of file +* Aktives Alarmieren aufgrund benutzerdefinierter Heuristiken (wie ein Alarm wenn die Anzahl von Fehlern pro Minute eine gewisse Grenze überschreitet). diff --git a/content/en/concurrency.md b/content/en/concurrency.md index 5ae4706b9..952778bcd 100644 --- a/content/en/concurrency.md +++ b/content/en/concurrency.md @@ -5,7 +5,7 @@ Any computer program, once run, is represented by one or more processes. Web ap ![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. diff --git a/content/en/logs.md b/content/en/logs.md index ab2f4f829..a893811a9 100644 --- a/content/en/logs.md +++ b/content/en/logs.md @@ -3,7 +3,7 @@ *Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. **A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. diff --git a/content/es/concurrency.md b/content/es/concurrency.md index fc48ef1fa..334c7d752 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -5,7 +5,7 @@ Todo programa de ordenador, al ejecutarse, se encuentra representado en memoria ![La escalabilidad está representada por el número de procesos en ejecución, mientras que la diversidad de carga de trabajo lo está por los tipos de procesos.](/images/process-types.png) -**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede distribuir la ejecución de su aplicación para gestionar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. +**En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede distribuir la ejecución de su aplicación para gestionar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. Esto no exime a los procesos de gestionar su propia división interna mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual aislada tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. diff --git a/content/es/logs.md b/content/es/logs.md index 4900e1226..3ae035370 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -3,7 +3,7 @@ Los *historiales* permiten observar el comportamiento de la aplicación durante su ejecución. En entornos basados en servidores es muy común escribir un fichero en disco (un "fichero de histórico") pero este, es tan solo un posible formato de salida. -Los historiales son la [transmisión](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de un conjunto de eventos ordenados y capturados de la salida de todos los procesos en ejecución y de los "backing services". En bruto, los historiales suelen estar en formato texto y tienen un evento por línea (aunque las trazas de excepciones suelen estar en varias líneas). Los historiales no tienen un principio y un final fijo, sino que fluyen continuamente mientras la aplicación está en funcionamiento. +Los historiales son la [transmisión](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) de un conjunto de eventos ordenados y capturados de la salida de todos los procesos en ejecución y de los "backing services". En bruto, los historiales suelen estar en formato texto y tienen un evento por línea (aunque las trazas de excepciones suelen estar en varias líneas). Los historiales no tienen un principio y un final fijo, sino que fluyen continuamente mientras la aplicación está en funcionamiento. **Una aplicación "twelve-factor" nunca se preocupa del direccionamiento o el almacenamiento de sus transmisiones de salida.** No debería intentar escribir o gestionar ficheros de historial. En su lugar, cada proceso en ejecución escribe sus eventos a la `salida estándar` (o `stdout`). Durante el desarrollo, los desarrolladores verán el flujo en su terminal para observar el comportamiento de la aplicación. diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index 2aae5d574..0b9123d8d 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -5,7 +5,7 @@ Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou pl ![La scalabilité est exprimée par des processus qui s'exécutent, la diversité de la charge de travail est exprimée par les types de processus](/images/process-types.png) -**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". +**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrone que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. diff --git a/content/fr/logs.md b/content/fr/logs.md index 30df80dae..895873032 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -3,7 +3,7 @@ Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits dans un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. -Les logs sont des [flux (en)](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. +Les logs sont des [flux (en)](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. **Une application 12 facteurs ne s'inquiète jamais du routage ou du stockage de ses flux de sortie.** Elle ne devrait pas tenter d'écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d'événements, sans tampon, vers `stdout`, la sortie standard ; en phase de développement local, les développeurs pourront voir ce flux dans leur terminal et observer le comportement de l'application. diff --git a/content/it/concurrency.md b/content/it/concurrency.md index 85e2bb9b1..79598ec21 100644 --- a/content/it/concurrency.md +++ b/content/it/concurrency.md @@ -5,10 +5,10 @@ Ogni software, una volta avviato, è rappresentato da uno o più processi. Le we ![Il fattore di scale è espresso con un numero di processi dello stesso tipo avviati, la diversità del carico di lavoro, invece, come le varie tipologie di processo.](/images/process-types.png) -**In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro ad un tipo di processo ben definito. Ad esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. +**In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro ad un tipo di processo ben definito. Ad esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo ed interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice ed affidabile. L'array dei tipi di processo ed il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). -I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [Upstart](http://upstart.ubuntu.com/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. \ No newline at end of file +I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [Upstart](http://upstart.ubuntu.com/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. diff --git a/content/it/logs.md b/content/it/logs.md index ae6e901f5..d818d6177 100644 --- a/content/it/logs.md +++ b/content/it/logs.md @@ -3,7 +3,7 @@ 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). Ad ogni modo, è solo un formato. -Un log può essere definito infatti come uno [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) di eventi aggregati ed 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 i 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 log può essere definito infatti come uno [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) di eventi aggregati ed 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 i 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. @@ -13,4 +13,4 @@ Uno stream di eventi di un'applicazione può essere quindi indirizzato verso un * 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); \ No newline at end of file +* 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); diff --git a/content/ja/concurrency.md b/content/ja/concurrency.md index 1795c25e6..8daf90366 100644 --- a/content/ja/concurrency.md +++ b/content/ja/concurrency.md @@ -5,7 +5,7 @@ ![スケールは実行されるプロセスの数として表現され、ワークロードの種類はプロセスタイプとして表現される。](/images/process-types.png) -**Twelve-Factor Appではプロセスは第一級市民である。** Twelve-Factor Appにおけるプロセスの考え方は、[サービスのデーモンを実行するためのUnixプロセスモデル](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)から大きなヒントを得ている。このモデルを使い、個々のワークロードの種類を *プロセスタイプ* に割り当てることで、開発者はアプリケーションが多様なワークロードを扱えるように設計することができる。例えば、HTTPリクエストはWebプロセスによって処理し、時間のかかるバックグラウンドタスクはワーカープロセスによって処理することができる。 +**Twelve-Factor Appではプロセスは第一級市民である。** Twelve-Factor Appにおけるプロセスの考え方は、[サービスのデーモンを実行するためのUnixプロセスモデル](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)から大きなヒントを得ている。このモデルを使い、個々のワークロードの種類を *プロセスタイプ* に割り当てることで、開発者はアプリケーションが多様なワークロードを扱えるように設計することができる。例えば、HTTPリクエストはWebプロセスによって処理し、時間のかかるバックグラウンドタスクはワーカープロセスによって処理することができる。 このモデルは、ランタイムVM内のスレッドや、[EventMachine](http://rubyeventmachine.com/)、[Twisted](http://twistedmatrix.com/trac/)、[Node.js](http://nodejs.org/)などの非同期イベントモデルによって、個々のプロセスがプロセス内部で多重化することを禁止するわけではない。しかし個々のVMはそれほど大きくなる(垂直にスケールする)ことができないため、アプリケーションは複数の物理マシンで動作する複数のプロセスへと拡大できなければならない。 diff --git a/content/ja/logs.md b/content/ja/logs.md index 0998a4d41..0f02c7f47 100644 --- a/content/ja/logs.md +++ b/content/ja/logs.md @@ -3,7 +3,7 @@ *ログ* は実行中のアプリケーションの挙動を可視化する。サーバーベースの環境では、ログは一般的にディスク上のファイル(“ログファイル”)に書き込まれる。しかしこれは出力フォーマットの一つに過ぎない。 -ログは、すべての実行中のプロセスとバックエンドサービスの出力ストリームから収集されたイベントが、集約されて時刻順に並べられた[ストリーム](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/)である。生の状態のログは、通常1行が1つのイベントを表すテキストフォーマットである(例外のバックトレースは複数行に渡る場合もあるが)。ログには固定の始まりと終わりはなく、アプリケーションが稼動している限り流れ続ける。 +ログは、すべての実行中のプロセスとバックエンドサービスの出力ストリームから収集されたイベントが、集約されて時刻順に並べられた[ストリーム](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/)である。生の状態のログは、通常1行が1つのイベントを表すテキストフォーマットである(例外のバックトレースは複数行に渡る場合もあるが)。ログには固定の始まりと終わりはなく、アプリケーションが稼動している限り流れ続ける。 **Twelve-Factor Appはアプリケーションの出力ストリームの送り先やストレージについて一切関知しない。** アプリケーションはログファイルに書き込んだり管理しようとするべきではない。代わりに、それぞれの実行中のプロセスはイベントストリームを`stdout`(標準出力)にバッファリングせずに書きだす。ローカルでの開発中、開発者はこのストリームをターミナルのフォアグラウンドで見ることで、アプリケーションの挙動を観察する。 diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md index 466e092ee..2603057f8 100644 --- a/content/ko/concurrency.md +++ b/content/ko/concurrency.md @@ -5,10 +5,10 @@ ![Scale는 실행되는 프로세스의 갯수로 표현되고, Workload Diversity는 프로세스의 타입으로 표현됩니다. ](/images/process-types.png) -**Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션이 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. +**Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션이 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. 이는 런타임 VM 내부의 쓰레드나 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. 프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](.processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. -Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [Upstart](http://upstart.ubuntu.com/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. \ No newline at end of file +Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [Upstart](http://upstart.ubuntu.com/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. diff --git a/content/ko/logs.md b/content/ko/logs.md index 553c4a753..d3fe4e766 100644 --- a/content/ko/logs.md +++ b/content/ko/logs.md @@ -3,7 +3,7 @@ *로그*는 실행 중인 app의 동작을 확인할 수 있는 수단입니다. 서버 기반 환경에서 로그는 보통 디스크에 파일(로그 파일)로 저장됩니다. 하지만, 이것은 출력 포맷 중 하나에 불과합니다. -로그는 모든 실행중인 프로세스와 백그라운드 서비스의 아웃풋 스트림으로부터 수집된 이벤트가 시간 순서로 정렬된 [스트림](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/)입니다. 가공되지 않는 로그는 보통, 하나의 이벤트가 하나의 라인으로 기록된 텍스트 포맷입니다.(예외(exception)에 의한 backtrace는 여러 라인에 걸쳐 있을 수도 있습니다.) 로그는 고정된 시작과 끝이 있는 것이 아니라, app이 실행되는 동안 계속 흐르는 흐름입니다. +로그는 모든 실행중인 프로세스와 백그라운드 서비스의 아웃풋 스트림으로부터 수집된 이벤트가 시간 순서로 정렬된 [스트림](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/)입니다. 가공되지 않는 로그는 보통, 하나의 이벤트가 하나의 라인으로 기록된 텍스트 포맷입니다.(예외(exception)에 의한 backtrace는 여러 라인에 걸쳐 있을 수도 있습니다.) 로그는 고정된 시작과 끝이 있는 것이 아니라, app이 실행되는 동안 계속 흐르는 흐름입니다. **Twelve-Factor App은 아웃풋 스트림의 전달이나 저장에 절대 관여하지 않습니다.** app은 로그 파일을 작성하거나, 관리하려고 해서는 안됩니다. 대신, 각 프로세스는 이벤트 스트림을 버퍼링 없이 `stdout`에 출력합니다. 로컬 개발환경에서 작업 중인 개발자는 app의 동작을 관찰하기 원하면 각자의 터미널에 출력되는 이 스트림을 볼 수 있습니다. @@ -13,4 +13,4 @@ * 과거의 특정 이벤트를 찾기 * 트렌드에 대한 거대한 규모의 그래프 (예: 분당 요청 수) -* 유저가 정의한 휴리스틱에 따른 알림 (예: 분당 오류 수가 임계 값을 넘는 경우 알림을 발생시킴) \ No newline at end of file +* 유저가 정의한 휴리스틱에 따른 알림 (예: 분당 오류 수가 임계 값을 넘는 경우 알림을 발생시킴) diff --git a/content/pt_br/logs.md b/content/pt_br/logs.md index 37d95e2d1..3162be066 100644 --- a/content/pt_br/logs.md +++ b/content/pt_br/logs.md @@ -3,7 +3,7 @@ *Logs* provém visibilidade no comportamento de um app em execução. Em ambientes de servidor eles são comumente escritos num arquivo em disco (um "logfile"); mas este é apenas um formato de saída. -Logs são o [fluxo](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) de eventos agregados e ordenados por tempo coletados dos fluxos de saída de todos os processos em execução e serviços de apoio. Logs na sua forma crua são tipicamente um formato de texto com um evento por linha (apesar que pilhas de exceção podem ocupar várias linhas). Logs não tem começos ou términos fixos, mas fluem continuamente enquanto o app estiver operante. +Logs são o [fluxo](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) de eventos agregados e ordenados por tempo coletados dos fluxos de saída de todos os processos em execução e serviços de apoio. Logs na sua forma crua são tipicamente um formato de texto com um evento por linha (apesar que pilhas de exceção podem ocupar várias linhas). Logs não tem começos ou términos fixos, mas fluem continuamente enquanto o app estiver operante. **Um app doze-fatores nunca se preocupa com o roteamento ou armazenagem do seu fluxo de saída.** Ele não deve tentar escrever ou gerir arquivos de logs. No lugar, cada processo em execução escreve seu próprio fluxo de evento, sem buffer, para o `stdout`. Durante o desenvolvimento local, o desenvolvedor verá este fluxo no plano de frente do seu terminal para observar o comportamento do app. diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index 3a6dd88ac..226da62e4 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -5,7 +5,7 @@ ![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) -**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. +**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. diff --git a/content/ru/logs.md b/content/ru/logs.md index 63efd1701..b7b955f46 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -3,7 +3,7 @@ *Журналирование* обеспечивает наглядное представление поведения работающего приложения. Обычно в серверной среде журнал записывается в файл на диске ("logfile"), но это только один из форматов вывода. -Журнал -- это [поток](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потоков вывода всех запущенных процессов и вспомогательных сервисов. Журнал в своём сыром виде обычно представлен текстовым форматом с одним событием на строчку (хотя трассировки исключений могут занимать несколько строк). Журнал не имеет фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. +Журнал -- это [поток](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) агрегированных, упорядоченных по времени событий, собранных из потоков вывода всех запущенных процессов и вспомогательных сервисов. Журнал в своём сыром виде обычно представлен текстовым форматом с одним событием на строчку (хотя трассировки исключений могут занимать несколько строк). Журнал не имеет фиксированного начала и конца, поток сообщений непрерывен, пока работает приложение. **Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий без буферизации в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index 3f87bbd0a..f3b0f7fee 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -5,7 +5,7 @@ ![扩展表现为运行中的进程,工作多样性表现为进程类型。](/images/process-types.png) -**在 12-factor 应用中,进程是一等公民。**12-Factor 应用的进程主要借鉴于 [unix 守护进程模型](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 *进程类型* 。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责。 +**在 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](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 diff --git a/content/zh_cn/logs.md b/content/zh_cn/logs.md index b751b6e9d..7873a7804 100644 --- a/content/zh_cn/logs.md +++ b/content/zh_cn/logs.md @@ -3,7 +3,7 @@ *日志* 使得应用程序运行的动作变得透明。在基于服务器的环境中,日志通常被写在硬盘的一个文件里,但这只是一种输出格式。 -日志应该是 [事件流](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) 的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行,日志最原始的格式确实是一个事件一行。日志没有确定开始和结束,但随着应用在运行会持续的增加。 +日志应该是 [事件流](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) 的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行,日志最原始的格式确实是一个事件一行。日志没有确定开始和结束,但随着应用在运行会持续的增加。 **12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(`stdout`)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 From 9113044e3d3b4c3a9cb13b4f22005952ed7c85d0 Mon Sep 17 00:00:00 2001 From: Artur Szott Date: Mon, 1 Feb 2016 20:51:09 +0100 Subject: [PATCH 289/472] Add complete polish translation --- content/pl/admin-processes.md | 14 ++++++ content/pl/background.md | 10 +++++ content/pl/backing-services.md | 15 +++++++ content/pl/build-release-run.md | 18 ++++++++ content/pl/codebase.md | 17 ++++++++ content/pl/concurrency.md | 14 ++++++ content/pl/config.md | 22 ++++++++++ content/pl/dependencies.md | 12 ++++++ content/pl/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/pl/disposability.md | 14 ++++++ content/pl/logs.md | 16 +++++++ content/pl/port-binding.md | 14 ++++++ content/pl/processes.md | 15 +++++++ content/pl/toc.md | 38 +++++++++++++++++ content/pl/who.md | 4 ++ 15 files changed, 299 insertions(+) create mode 100644 content/pl/admin-processes.md create mode 100644 content/pl/background.md create mode 100644 content/pl/backing-services.md create mode 100644 content/pl/build-release-run.md create mode 100644 content/pl/codebase.md create mode 100644 content/pl/concurrency.md create mode 100644 content/pl/config.md create mode 100644 content/pl/dependencies.md create mode 100644 content/pl/dev-prod-parity.md create mode 100644 content/pl/disposability.md create mode 100644 content/pl/logs.md create mode 100644 content/pl/port-binding.md create mode 100644 content/pl/processes.md create mode 100644 content/pl/toc.md create mode 100644 content/pl/who.md diff --git a/content/pl/admin-processes.md b/content/pl/admin-processes.md new file mode 100644 index 000000000..c894c734f --- /dev/null +++ b/content/pl/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Zarządzanie aplikacją +### Uruchamiaj zadania administracyjne jako jednorazowe procesy + +[Formacja](./concurrency) jest zestawem procesów używanych przez aplikację podczas jej działania (np. obsługi zapytań z sieci). Do często wykonywanych zadań administracyjnych należą: + +* Wykonanie migracji bazy danych (np. `manage.py migrate` w Django, `rake db:migrate` w Railsach). +* Uruchomienie konsoli (znanej również jako powłoka [REPL](http://pl.wikipedia.org/wiki/REPL)) by wykonać frament kodu lub podejrzeć modele działającej bazy danych. Większość środowisk języków programowania udostępnia REPL poprzez wywołanie interpretera bez dodatkowych argumentów (np. `python` lub `perl`). W innych przypadkach przeznaczone są do tego osobne polecenia (np. `irb` w Ruby, `rails console` w Railsach). +* Wykonywanie pojedynczych skryptów znajdujących się w repozytorium kodu aplikacji (np. `php scripts/fix_bad_records.php`). + +Pojedyncze zadania powinny być uruchamiane w identycznym środowisku jak [długoterminowe procesy](./processes) aplikacji. Działają w ramach tego samego [wdrożenia](./build-release-run), używając tego samego [kodu](./codebase) i [konfiguracji](./config) jak każdy inny działający proces. Kod zadania administracyjnego musi zostać dołączony do kodu aplikacji by uniknąć problemów z synchronizacją. + +Te same techniki [izolacji zależności](./dependencies) powinny być używane dla wszystkich typów procesów. Dla przykładu, jeśli proces sieciowy Ruby używa polecenia `bundle exec thin start`, wtedy do migracji bazy danych powinno się użyć `bundle exec rake db:migrate`. Podobnie program napisany w Pythonie używający Virtualenv powinien używać dołączonego `bin/python` by uruchomić zarówno webserver Tornado lub `manage.py` do procesów zarządzania. + +Aplikacja 12factor zaleca używanie języków programowania, które udostępniają powłokę REPL oraz takich w których można łatwo uruchomić pojedynczy skrypt. W środowisku lokalnym developerzy uruchamiają zadania zarządzające aplikacją poprzez bezpośrednie wywołanie polecenia w konsoli w katalogu roboczym aplikacji. We wdrożeniu produkcyjnym, developer może użyć ssh lub innego mechanizmu służącego do zdalnego wykonywania poleceń, by uruchomić ten sam proces. diff --git a/content/pl/background.md b/content/pl/background.md new file mode 100644 index 000000000..aac752d74 --- /dev/null +++ b/content/pl/background.md @@ -0,0 +1,10 @@ +Background +========== + +Kontrybutorzy tego dokumentu byli bezpośrednio zaangażowani w tworzenie i wdrażanie setek aplikacji i pośrednio byli świadkami produkcji, działania i skalowania setek tysięcy aplikacji dzięki naszej pracy na platformie [Heroku](http://www.heroku.com/). + +Ten dokument jest podsumowaniem całego naszego doświadczenia i obserwacji szerokiej gamy aplikacji SaaS. Jest on połączeniem idealnych praktyk developmentu, zwracania szczególnej uwagi na naturalny rozrost aplikacji w czasie, dynamiki współpracy developerów pracujących nad jednym codebase'm, oraz [unikania kosztów gnijącego oprogramowania](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Naszym celem jest podniesienie poziomu świadomości o podstawowych problemach, które dostrzegliśmy przy tworzeniu nowoczesnych aplikacji, zapewnienie wspólnego słownictwa dp rozmowy o tych problemach oraz zaoferowanie ogólnych rozwiązań dla tych problemów wraz z towarzyszącą terminologią. Format dokumentu jest inspirowany książkami Martina Fowlera + *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* oraz *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. + diff --git a/content/pl/backing-services.md b/content/pl/backing-services.md new file mode 100644 index 000000000..fb0b67bb1 --- /dev/null +++ b/content/pl/backing-services.md @@ -0,0 +1,15 @@ +## IV. Usługi wspierające +### Traktuj usługi wspierające jako przydzielone zasoby + +Usługą wspierającą jest każda, z której aplikacja korzysta przez sieć jako część normalnego działania. Zaliczamy do nich np. magazyny danych (takie jak [MySQL](http://dev.mysql.com/) albo [CouchDB](http://couchdb.apache.org/)), systemy wysyłania/kolejkowania wiadomości (takie jak [RabbitMQ](http://www.rabbitmq.com/) czy [Beanstalkd](http://kr.github.com/beanstalkd/)), usługi SMTP do zewnętrznej wysyłki emaili (np. [Postfix](http://www.postfix.org/)) oraz systemy cachowania pamięci (np. [Memcached](http://memcached.org/)). + +Usługa wspierająca taka jak baza danych jest zazwyczaj zarządzana przez tych samych programistów, którzy zajmują się wdrażaniem aplikacji. Dodatkowo aplikacja może również korzystać z usług oferowanych przez osoby trzecie. Do przykładów zaliczają się usługi SMTP ([Postmark](http://postmarkapp.com/)),usługi zbierające metryki ([New Relic](http://newrelic.com/) czy [Loggly](http://www.loggly.com/)), usługi przechowywania danych (takie jak [Amazon S3](http://aws.amazon.com/s3/)), czy również usługi dostępne przez publiczne API (jak np. [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), lub [Last.fm](http://www.last.fm/api)). + +**Aplikacje 12factor nie rozróżniają usług lokalnych od zewnętrznych.** Dla aplikacji wszystkie są załączonymi zasobami, dostepnymi przez adres URL lub inny standard zdefiniowany w [konfiguracji](./config). Przy [wdrożeniu](./codebase) aplikacji nie może być problemów ze zmianą lokalnej bazy MySQL na oferowaną przez zewnętrznego usługodawcę (np. [Amazon RDS](http://aws.amazon.com/rds/)) bez żadnych zmian w kodzie aplikacji. Podobnie lokalny serwer SMTP może być zamieniony na zewnętrzną usługę SMTP (taką jak Postmark) bez zmian kodu. W obu przypadkach zmiana powinna wystąpić jedynie w konfiguracji aplikacji. + +Każda usługa jest traktowana jako *zasób*. Zasobem będzie np. baza MySQL; dwie bazy danych (używane do [shardingu](https://en.wikipedia.org/wiki/Shard_(database_architecture)) w warstwie aplikacji) kwalifikują się jako dwa odrębne zasoby. Aplikacja 12factor traktuje te bazy danych jako *załączone zasoby*, co wskazuje, że nie są z nią trwale powiązane. + +Produkcyjne wdrożenie aplikacji korzystajace z czterech usług wspierających. + +Zasoby mogą być dołączane i odłączane jeśli zajdzie taka potrzeba. W momencie gdy baza danych aplikacji z powodu usterek sprzętowych nie działa poprawnie, administrator może przełączyć bazę danych aplikacji na nowy serwer odtworzoną z ostatniego zapisu przywracania danych. Obecna produkcyjna baza może więc zostać przełączona bez żadnych zmian w kodzie aplikacji. + diff --git a/content/pl/build-release-run.md b/content/pl/build-release-run.md new file mode 100644 index 000000000..30d950da9 --- /dev/null +++ b/content/pl/build-release-run.md @@ -0,0 +1,18 @@ +## V. Buduj, publikuj, uruchamiaj +### Oddzielaj etap budowania od uruchamiania + +[Codebase](./codebase) jest przetwarzany we wdrożenie w trzech etapach (poza lokalnym środowiskiem). + +* Podczas *etapu budowania* kod z repozytorium konwertowany jest do wykonywalnej paczki tzw. *buildu*. Używając wersji kodu zdefiniowanej przez commit w procesie deploymentu, w tym etapie pobiera i dołącza się do projektu [zależności](./dependencies) oraz kompiluje niezbędne zasoby. +* Podczas *etapu publikacji* aplikacji używany jest build stworzony w poprzednim etapie i konfigurowany na podstawie [ustawień](./config) obecnego wdrożenia. Stworzony w ten sposób *release* zawiera zbudowane źródło kodu, jego konfigurację i jest gotowy do uruchomienia w wybranym środowisku. +* *Etap uruchamiania* (znany również jako "runtime") startuje aplikację w środowisku wykonawczym przez uruchomienie zestawu [procesów](./processes) w oparciu o wcześniej przygotowany release. + +![Kod staje się buildem, jeśli zostanie połączony z konfiguracją by stworzyć release](/images/release.png) + +**Aplikacja 12factor ściśle rozgranicza etapy budowy, publikacji i uruchomiania** Kiedy aplikacja została już uruchomiona, nie można zmienić jej kodu w inny sposób niż zbudować ją na nowo na podstawie wcześniej naniesionych zmian. + +Narzędzia do obsługi wdrożeń zazwyczaj oferują moduły do zarządzania releasami, w tym możliwość do powrotu do poprzedniej wersji (rollback). Np. narzędzie [Capistrano](https://github.com/capistrano/capistrano/wiki) przechowuje releasy w podkatalogu `releases`, gdzie obecna wersja opublikowanej aplikacji jest symlinkowana do jednej z wersji przechowywanej w katalogu Capistrano. Komenda `rollback` pozwala na szybką zmianę wersji opublikowanej aplikacji na jedną z poprzednich. + +Każdy release powinien zawsze posiadać unikalny identyfikator, jak np. data publikacji aplikacji (taka jak `2011-04-06-20:32:17`) lub inkrementowany numer (np. `v100`). Do rejestru opublikowanych wersji aplikacji można jedynie dodawać jej nowe wersje, jego zawartość nie może być zmieniana w żaden inny sposób. + +Aplikacja może zostać zbudowana gdy developer zdecyduje o wdrożeniu zmian do kodu. Uruchomienie aplikacji może natomiast nastąpić automatycznie po restarcie serwera lub jednego z procesów aplikacji po błędzie krytycznym. Dlatego też etap uruchamiania aplikacji powinien być jak najbardziej jednolity minimalizując równocześnie ryzyko wystąpienia problemów ze startem aplikacji - mogą one spowodować zaprzestanie działania aplikacji np. w nocy, kiedy to nie ma żadnego developera "pod ręką". Etap budowy aplikacji może być bardziej złożony, ponieważ ewentualne błędy są zawsze widoczne dla developera, który nadzoruje ten proces. diff --git a/content/pl/codebase.md b/content/pl/codebase.md new file mode 100644 index 000000000..8586f044f --- /dev/null +++ b/content/pl/codebase.md @@ -0,0 +1,17 @@ +## I. Codebase +### Jedno źródło kodu śledzone systemem kontroli wersji, wiele wdrożeń + +Aplikacja 12factor napisana jest zawsze zarządzania w systemie kontroli wersji takim jak [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), czy [Subversion](http://subversion.apache.org/). Miejsce, w którym trzymany i rewizjonowany jest kod nazywane jest *repozytorium kodu źródłowego*, często skracane do samego *code repo*, albo po prostu *repo*. + +*Codebase* (baza kodu) jest więc niczym innym jak pojedynczym repo (w przypadku zcentralizowanego systemu kontroli wersji jak Subversion), albo zestawem repozytoriów, które współdzielą tzw. root commit. (w przypadku zdecentralizowanego systemu jak Git). + +![Jeden codebase, wiele wdrożeń](/images/codebase-deploys.png) + +Aplikacja powinna zawsze odzwierciedlać bazowy kod: + +* Jeśli istnieje wiele źródeł, z których pobierany jest kod, nie można mówić o aplikacji, a systemie rozproszonym. Każdy komponent w systemie rozproszonym będzie wtedy aplikacją i każdy z osobna może spełniać wszystkie zasady 12factor. +* Jeśli wiele aplikacji dzieli ten sami kod, mamy do czynienia z naruszeniem 12factor. Wyjściem z tej sytuacji może być wyizolowanie współdzielonego kodu do bibliotek, które będą dodane do aplikacji przez tzw. [dependency manager](./dependencies). + +Aplikacja może posiadać tylko jeden codebase, jednocześnie mając wiele wdrożeń. *Deploy* (z ang. wdrożenie) jest działającą instancją aplikacji. Zazwyczaj mówi się o wersji produkcyjnej i jednej lub więcej przedprodukcyjnych. Ponadto każdy developer pracujący nad aplikacją posiada jej kopię działającą w swoim lokalnym środowisku developerskim, co również kwalifikuje się jako osobne wdrożenie. + +Codebase jest taki sam dla wszystkich wdrożeń aplikacji, jednak poszczególne wdrożenia aplikacji mogą korzystać z jego różnych wersji. Dla przykładu, developer pracujący nad aplikacją może nanieść zmiany, które nie znajdą się jeszcze w wersji produkcyjnej. Obie wersje dzielą jednak ten sam codebase, przez co kwalifikują się jako osobne wdrożenia tej samej aplikacji. diff --git a/content/pl/concurrency.md b/content/pl/concurrency.md new file mode 100644 index 000000000..09ebf4297 --- /dev/null +++ b/content/pl/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Współbieżność +### Skaluj przez odpowiednio dobrane procesy + +Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jeden lub więcej procesów. Aplikacje internetowe mogą być uruchamiane w różnorodny sposób. Dla przykładu - procesy PHP uruchamiane są na żądanie (w zależności od potrzeby obsługi odpowiednio dużej liczby zapytań) się jako podrzędne procesy Apache'a. W Javie procesy obsługiwane są zupełnie inaczej, z JVM zapewniającym jeden nadrzędny proces, który rezerwuje zasoby systemu (CPU oraz pamięć) na starcie oraz współbieżnością zarządzaną wewnętrznie i opartą na wątkach. Dla developerów aplikacji różnica jednak nie będzie szczególnie odczuwalna. + +![Skala wyrażana jest przez działające procesy, natomiast różnorodność obciążenia wyrażana jest w typach procesów](/images/process-types.png) + +**W aplikacji 12factor, procesy są typem pierwszoklasowym** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych. + +Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku maszyny wirtualnej lub w asynchronicznym modelu wydarzeń, którego implementację możemy znaleźć wśród narzędzi takich jak [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), albo [Node.js](http://nodejs.org/). Należy pamiętać, że pojedyncza maszyna wirtualna może z czasem wymagać coraz więcej zasobów (skala pionowa), dlatego aplikacja musi być również w stanie pracować w oparciu o wiele procesów działających na wielu fizycznych maszynach. + +Największa zaleta modelu procesów objawia się w momencie skalowania. [Niezależność oraz dzielenie się na podprocesy](./processes) umożliwia proste i bezproblemowe dodawanie wiekszej liczby równolegle działajacych procesów. Tablica typów procesów i liczba procesów nazywana jest ich *formacją*. + +Procesy aplikacji 12factor [nigdy nie powinny być uruchamiane w tle](http://dustin.github.com/2010/02/28/running-processes.html) i nie mogą zapisywać plików PID. Zamiast tego opierają się na narzędziach systemu operacyjnego: do zarządzania procesami (np. [Upstart](http://upstart.ubuntu.com/), do zarządzania rozproszonymi procesami w chmurze, lub [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) w developmencie) do zarządzania [stumieniami wyjściowymi](./logs), do obsługi zatrzymanych procesów, restartu i zakończenia działań zainicjowanych przez użytkownika. diff --git a/content/pl/config.md b/content/pl/config.md new file mode 100644 index 000000000..1425579b3 --- /dev/null +++ b/content/pl/config.md @@ -0,0 +1,22 @@ +## III. Konfiguracja +### Przechowuj konfigurację w środowisku + +*Konfiguracja* to jedyny element, który może się różnić pomiędzy [wdrożeniami](./codebase) aplikacji (staging, produkcja, środowisko developerskie, etc). W jej skład wchodzą: + +* Ustawienia połączeń do baz danych, Memcached, i innych [usług wspierających](./backing-services) +* Dane uwierzytelniające zewnętrznych usług takich jak Amazon S3 czy Twitter +* Wartości różne dla każdego wdrożenia, jak np. kanoniczna nazwa hosta + +Aplikacja czasem przechowuje konfigurację jako stałe wartości w kodzie źródłowym. Niestety jest to złamanie zasady 12factor wg której konfiguracja jest **ściśle oddzielona od kodu aplikacji**. + +Dowodem na to, czy aplikacja posiada swoją konfigurację oddzieloną od kodu jest to, czy można ją udostępnić na zasadach open source bez równoczesnego udostępniania np. danych uwierzytelniających. + +Należy pamiętać, że definicja "konfiguracji" **nie** dotyczy wewnętrznych ustawień aplikacji takich jak np. plik `config/routes.rb` w Railsach lub to jak [są połączone moduły kodu](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) w [Springu](http://spring.io/). Konfiguracja tego typu nie zmienia się pomiędzy wdrożeniami co sprawia, że najbardziej odpowiednim miejscem do jej przechowywania jest kod aplikacji. + +Innym podejściem do konfiguacji jest korzystanie z plików, które nie znajdują się w repozytorium i nie są wersjonowane, jak np. `config/database.yml` w Railsach. Jest to duże usprawnienie względem używania stałych wartości, które są zapisywane w repozytorium. Minusem tego rozwiązania jest możliwość przypadkowego umieszczenia pliku konfiguracyjnego w repo. Ponadto można spotkać się z tendencją do rozrzucania takich plików w różnych katalogach i różnych formatach, co czyni je trudnymi do znalezienia i zarządzania z jednego miejsca. + +**Aplikacja 12factor przechowuje konfigurację w *zmiennych środowiskowych*** (czasem nazywane z języka angielskiego *env vars* lub *env*). W tej sytuacji można łatwo modyfikować zmienne środowiskowe pomiędzy wdrożeniami bez zmiany kodu aplikacji. W odróżnieniu do plików konfiguracyjnych istnieje mała szansa by zostały umieszczone przypadkowo w repozytorium. Ich kolejną zaletą jest to, że nie są powiązane z językiem programowania, frameworkiem, jak np. Java System Properties, czy też systemem operacyjnym. + +Kolejnym zagadnieniem zarządzania konfiguracją jest jej grupowanie. Czasem aplikacje gromadzą konfigurację w grupach (czasem nazywane "środowiskami") nazywanych od nazwy wdrożenia, takie jak `development`, `test`, czy `produkcja` w Railsach. Ten sposób organizacji jest niestety nieskalowalny. Im więcej różnych wdrożeń, tym większa potrzeba nazw, jak np. `staging` czy `qa`. Wraz z rozwojem projektu programiści mogą dodawać swoje specjalne konfiguracje, jak `staging-józefa`. Efektem tego mogą być niezliczone kombinacje nazw plików konfiguracyjnych, co utrudniać będzie zarządzanie wdrożonymi aplikacji. + +W aplikacji 12factor zmienne środowiskowe służą do precyzyjnej kontroli poszczególnych ustawień, posiadając różne, nie mylące się ze sobą nazwy. Nigdy nie są zgrupowane w "środowiskach", tylko niezależnie ustawiane dla każdego wdrożenia. Taki model konfiguracji skaluje się bez problemu, nawet jeśli aplikacja będzie potrzebowała w przyszłości więcej zróżnicowanych wdrożeń. diff --git a/content/pl/dependencies.md b/content/pl/dependencies.md new file mode 100644 index 000000000..a0cebd86e --- /dev/null +++ b/content/pl/dependencies.md @@ -0,0 +1,12 @@ +## 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. [Gem Bundler](http://gembundler.com/) 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ę zalenoż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łąćzone. diff --git a/content/pl/dev-prod-parity.md b/content/pl/dev-prod-parity.md new file mode 100644 index 000000000..c1d53da17 --- /dev/null +++ b/content/pl/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Jednolitość środowisk +### Utrzymuj środowisko developerskie, stagingowe i produkcyjne tak podobne jak tylko możliwe + +Z doświadczenia wiadomo, że od zawsze istniały różnice pomiędzy środowiskiem developerskim (developer pracujący nad swoją lokalną wersją [kodu](./codebase) aplikacji) a produkcyjnym (działająca aplikacja dostępna dla użytkowników. Ze względu na ich charakter, możemy wymienić trzy rodzaje różnic: + +* **Różnica czasowa:** Developer może pracować nad kodem przez dni, tygodnie, miesiące zanim ostatecznie pojawi się on w wersji produkcyjnej. +* **Różnica odpowiedzialności**: Developer tworzy kod aplikacji, natomiast kto inny wdraża go do na produkcję. +* **Różnica narzędzi**: Developer może używać narzędzi takich jak Nginx, SQLite i systemu OS X, natomiast wersja produkcyjna będzie opierać się na Apache, MySQL i systemie Linux. + +**Aplikacja 12factor jest zaprojektowana tak by można ją było [bez przerwy wdrażać na produkcję](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) minimalizując różnice pomiędzy środowiskami.** Mając na uwadze powyższe różnice, można sobie z nimi radzić na różne sposoby: + +* Zmniejsz czas deploymentu: czas wdrożenia kodu napisanego przez developera powinien być mierzony w godzinach, a nawet w minutach. +* Przenieś odpowiedzialność: developer piszący kod powinien być zaangażowany we wdrożenia aplikacji na produkcję. +* Stosuj ten sam zestaw narzędzi: utrzymuj wszystkie środowiska w których działa aplikacja tak podobne jak to możliwe. + +Podsumowując w formie tabeli: + + + + + + + + + + + + + + + + + + + + + + +
Tradycyjna aplikacjaAplikacja 12factor
Czas pomiędzy wdrożeniamiTygodnieGodziny
Tworzenie kodu vs wdrażanie koduRóżne osobyTe same osoby
Środowisko developerskie vs produkcyjneMocno różniące sięJak najbardziej zbliżone
+ +Zachowanie podobieństw między wdrożeniami jest ważne w przypadku [usług wspierających](./backing-services) takich jak baza danych aplikacji, system kolejkowania czy też cache. Wiele języków oferuje biblioteki, które upraszczają korzystanie z usług wspierających w tym *adaptery* do usług różnego typu. Kilka przykładów w tabeli poniżej: + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypJęzykBibliotekaAdaptery
Baza danychRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
KolejkaPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CachePamięć, system plików, Memcached
+ +Czasami zdarza się, że developerzy w swoim lokalnym środowisku wolą korzystać z "lżejszych" wersji różnych usług, na produkcji natomiast używając bardziej zaawansowanych narzędzi. Przykładem takiej sytuacji jest używanie lokalnie SQLite, a PostgreSQL na produkcji. Podobnie wygląda też użycie na środowisku developerskim do cachowania pamięci, zamiast Memcached znajdującego się na produkcji. + +**Developer postępujący zgodnie zasadami 12factor opiera się pokusie używania usług różniących się pomiędzy środowiskami**, nawet wtedy, gdy adaptery teoretycznie ukrywają różnice w implementacji pod warstwą abstrakcji. Z powodu różnic pomiędzy usługami wspierającymi mogą pojawić się niezgodności, powodując, że kod, który działał i był testowany lokalnie lub na stagingu, przestanie funkcjonować na produkcji. Pojawianie się tego typu błędów negatywnie wpływa na proces ciągłego wdrażania aplikacji. Czas stracony na wykrywaniu takich błędów i konsekwentnych awariach podczas wdrażania aplikacji może sporo kosztować, zwłaszcza gdy podobne problemy będą się z czasem gromadzić. + +Lekkie wersje usług w obecnych czasach nie są już tak atrakcyjne jak kiedyś. Nowoczesne usługi takie jak Memcached, PostgreSQL oraz RabbitMQ nie są trudne do instalacji w lokalnym środowisku, dzięki narzędziom jak [Homebrew](http://mxcl.github.com/homebrew/) i [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Innym rozwiązaniem są narzędzia do deklaratywnego [provisioningu](https://en.wikipedia.org/wiki/Provisioning) takie jak [Chef](http://www.opscode.com/chef/) czy [Puppet](http://docs.puppetlabs.com/) połączone z lekkimi środowiskami wirtualnymi jak np. [Vagrant](http://vagrantup.com/). Pozwala ono developerom na uruchamianie lokalnych środowisk, które są bardzo zbliżone do produkcyjnych. Koszt instalacji i używania takich rozwiązań jest stosunkowo niski, biorąc pod uwagę korzyści płynące z utrzymywania jednolitych środowisk i procesu ciągłego wdrażania aplikacji. + +Adaptery dla różnych usług wspierających są wciąż użyteczne, gdyż dzięki nim zmiana usługi jest relatywnie łatwa. Należy jednak pamiętać, że wszystkie wdrożenia aplikacji (środowiska developerskie, stagingowe, produkcyjne) powinny używać tych samych typów i wersji usług wspierających. diff --git a/content/pl/disposability.md b/content/pl/disposability.md new file mode 100644 index 000000000..6d9673afb --- /dev/null +++ b/content/pl/disposability.md @@ -0,0 +1,14 @@ +## IX. Zbywalność +### Zwiększ elastyczność aplikacji przez szybki start i bezproblemowe zamknięcie + +**[Procesy](./processes) aplikacji 12factor są *jednorazowe*, znaczy to, że mogą być wystartowane lub zatrzymane w dowolnym momencie.** Ułatwia to elastyczne skalowanie i szybkie wdrożenia [kodu](./codebase), zmianę [konfiguracji](./config) oraz zapewnia większą stabilność przy wdrożeniu na produkcję. + +Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealnej sytuacji proces powinien potrzebować kilku sekund na to aby wystartować i być gotowym na przyjmowanie zapytań. Dzięki krótkiemu czasowi startu można szybciej wykonywać kolejne [wdrożenia](./build-release-run) oraz łatwiej skalować aplikację. Zwiększa to również zdolności aplikacji do radzenia sobie z problemami, ponieważ `process manager` może bezproblemowo przenieść je na nową maszynę fizyczną, gdy zajdzie taka potrzeba. + +Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long poolingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie. + +Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](http://kr.github.com/beanstalkd/), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [indepotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). + +Architektura aplikacji 12factor jest również zaprojektowana by działające procesy zostały poprawnie **zakończone w razie awarii** sprzętu. Podczas gdy taka sytuacja jest o wiele rzadsza niż otrzymanie sygnału `SIGTERM`, wciąż może mieć miejsce. Zalecanym podejściem w takich przypadkach jest stosowanie serwerowego systemu kolejkowania zadań, jak Beanstalkd, który zwróci zadanie do kolejki, gdy klient się rozłączy, bądź minie maksymalny czas obsługi pojedynczego zapytania. Architektura ["crash-only"](http://lwn.net/Articles/191059/) jest więc rozwinięciem takiego [konceptu](http://docs.couchdb.org/en/latest/intro/overview.html). + + diff --git a/content/pl/logs.md b/content/pl/logs.md new file mode 100644 index 000000000..50b3bf6f0 --- /dev/null +++ b/content/pl/logs.md @@ -0,0 +1,16 @@ +## XI. Logi +### Traktuj logi jako strumień zdarzeń + +*Logi* zapewniają wgląd w zachowanie działającej aplikacji. W środowiskach korzystających z serwera zazwyczaj są zapisywane na dysku (plik "logfile"); jednak jest to tylko wybrany format zapisu. + + Logi są listą zaagregowanych i uporządkowanych w czasie [zdarzeń](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) zebranych ze strumieni wyjściowych wszystkich uruchomionych procesów i usług wspierających. Logi w swojej pierwotnej formie występują zazwyczaj w formacie tekstowym, gdzie jedno zdarzenie zajmuje jedną linię w pliku (wyjątkiem jest jednak [backtrace](https://en.wikipedia.org/wiki/Stack_trace), który może zajmować wiele linii). Logi nie mają określonego początku ani końca, napływają nieustannie podczas działania aplikacji. + +**Aplikacja 12factor nie odpowiada za przekierowywanie i zapis swojego strumienia wyjściowego.** Nie powinna też zapisywać czy zarządzać plikami logów. Zamiast tego, każdy działający proces zapisuje swój niebuforowany strumień zdarzeń do `stdout`. Podczas pracy w lokalnym środowisku developer może obserwować zachowanie aplikacji przeglądając strumień w oknie terminala + +We wdrożeniu stagingowym czy produkcyjnym, każdy strumień procesów zostanie przechwycony przez środowisko wykonawcze, dołączony do pozostałych i skierowany do jednego lub wielu miejsc w celu przeglądania i długoterminowego zapisu. Miejsca zapisu nie są widoczne ani konfigurowane przez aplikację - w całości zarządza nimi środowisko wykonawcze. W tym celu można skorzystać z narzędzi do obsługi logów (takich jak [Logplex](https://github.com/heroku/logplex) lub [Fluent](https://github.com/fluent/fluentd)) dostępnych na licencji open-source. + +Strumień zdarzeń aplikacji może być skierowany do pliku lub obserwowany w czasie rzeczywistym przy pomocy komendy `tail` w terminalu. Przeważnie strumień jest wysyłany do systemu indeksowania i analizowania jak np. [Splunk](http://www.splunk.com/), albo do systemu magazynowania danych jak [Hadoop/Hive](http://hive.apache.org/). Wymienione systemy oferują duże możliwości i elastyczność obserwacji i badania zachowań aplikacji w czasie, w tym: + +* Wyszukiwanie konkretnych zdarzeń z przeszłości. +* Wizualizację masowych statystyk (np. zapytania na minutę). +* Wysyłanie powiadomień na podstawie wcześniej zdefiniowanych heurystyk (np. o tym, że liczba błędów przekroczyła dozwoloną wartość). diff --git a/content/pl/port-binding.md b/content/pl/port-binding.md new file mode 100644 index 000000000..55c1ddb69 --- /dev/null +++ b/content/pl/port-binding.md @@ -0,0 +1,14 @@ +## 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://jetty.codehaus.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. diff --git a/content/pl/processes.md b/content/pl/processes.md new file mode 100644 index 000000000..c30b084fe --- /dev/null +++ b/content/pl/processes.md @@ -0,0 +1,15 @@ +## VI. Procesy +### Uruchamiaj aplikację jako jeden lub więcej bezstanowych procesów + +Aplikacja jest uruchamiana w środowisku wykonawczym w postaci jednego lub kilku *procesów*. + +W najprostszym przypadku kod aplikacji jest samodzielnym skryptem, środowiskiem wykonawczym jest laptop developera z wsparciem dla języka programowania a proces jest uruchamiany za pomocą linii komend (na przykład `python my_script.py`). Innym razem wdrożenie produkcyjne mocno rozwiniętej aplikacji może wymagać wiele [różnych rodzajów procesów](./concurrency). + +**Wg zasad 12factor, procesy są bezstanowe i [nie-współdzielące](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Jakiekolwiek dane wymagające zapisu musza być zmagazynowane w "trwałej" [usłudze wspierającej](./backing-services), najczęściej będącą bazą danych. + +Przestrzeń adresowa lub system plików procesu mogą być używane jako tymczasowy cache dla pojedynczych operacji. Przykładem jest pobieranie dużych plików, działanie na nich, a następnie zapisywanie wyników operacji w bazie danych. Aplikacja dwunastu aspektów nigdy nie zakłada, że jakiś fragment informacji zapisany w pamięci lub dysku będzie dostępny w przyszłości podczas jakiegokolwiek zapytania -- wraz z wieloma aktywnymi procesami rośnie szansa, że przyszłe zapytanie zostanie obsłużone przez zupełnie inny proces. Nawet w przypadku pojedynczego procesu, restart (spowodowany przez deployment kodu, zmianę konfiguracji lub relokacja procesu do innej fizycznej lokalizacji wykonana przez środowisko wykonawcze) zazwyczaj usunie wszystkie dane z lokalnego stanu aplikacji (system plików, pamięć podręczna). + +Narzędzie do pakowania plików, z których korzysta aplikacja (takie jak [Jammit](http://documentcloud.github.com/jammit/) lub [django-compressor](http://django-compressor.readthedocs.org/)) używają systemu plików jako cache dla skompilowanych zasobów. Wg 12factor taka kompilacja powinna mieć miejsce podczas [etapu budowy aplikacji](./build-release-run), jak to się dzieje np. w [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html). + +Niektóre systemy sieciowe polegają na tzw. ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- oznacza to, że sesja użytkownika jest zapisywana tymczasowo w pamięci procesu aplikacji, zakładając, że kolejne zapytania dotyczące użytkownika będą kierowane do tego samego procesu. "Sticky sessions" są złamaniem zasad aplikacji 12factor i nigdy nie powinny być używane jako źródło informacji. Dane sesji nadają się bardziej do zapisu w magazynie oferującym wygasanie danych w czasie, jak np. [Memcached](http://memcached.org/) czy [Redis](http://redis.io/). + diff --git a/content/pl/toc.md b/content/pl/toc.md new file mode 100644 index 000000000..1adc429a1 --- /dev/null +++ b/content/pl/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Codebase](./codebase) +### Jedno źródło kodu śledzone systemem kontroli wersji, wiele wdrożeń + +## [II. Zależności](./dependencies) +### Jawnie zadeklaruj i wydziel zależności + +## [III. Konfiguracja](./config) +### Przechowuj konfigurację w środowisku + +## [IV. Usługi wspierające](./backing-services) +### Traktuj usługi wspierające jako przydzielone zasoby + +## [V. Buduj, publikuj, uruchamiaj](./build-release-run) +### Oddzielaj etap budowania od uruchamiania + +## [VI. Procesy](./processes) +### Uruchamiaj aplikację jako jeden lub więcej bezstanowych procesów + +## [VII. Przydzielanie portów](./port-binding) +### Udostępniaj usługi przez przydzielanie portów + +## [VIII. Współbieżność](./concurrency) +### Skaluj przez odpowiednio dobrane procesy + +## [IX. Zbywalność](./disposability) +### Zwiększ elastyczność pozwalając na szybkie uruchamianie i zatrzymywanie aplikacji + +## [X. Jednolitość środowisk](./dev-prod-parity) +### Utrzymuj konfigurację środowisk jak najbardziej zbliżoną do siebie + +## [XI. Logi](./logs) +### Traktuj logi jako strumień zdarzeń + +## [XII. Zarządzanie aplikacją](./admin-processes) +### Uruchamiaj zadania administracyjne jako jednorazowe procesy diff --git a/content/pl/who.md b/content/pl/who.md new file mode 100644 index 000000000..08d2c78b0 --- /dev/null +++ b/content/pl/who.md @@ -0,0 +1,4 @@ +Dla kogo przeznaczony jest ten dokument? +============================== + +Dla każdego developera tworzącego aplikacje, które działają jako usługa. Dla każdego Dev-opsa, który wdraża i zarządza takimi aplikacjami. From 042efba6febba215f6638792c8c9d29701bdf926 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 23 May 2016 09:00:16 +0100 Subject: [PATCH 290/472] update links for ssl --- content/pl/concurrency.md | 2 +- content/pl/logs.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/pl/concurrency.md b/content/pl/concurrency.md index 09ebf4297..8e3714ea8 100644 --- a/content/pl/concurrency.md +++ b/content/pl/concurrency.md @@ -5,7 +5,7 @@ Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jed ![Skala wyrażana jest przez działające procesy, natomiast różnorodność obciążenia wyrażana jest w typach procesów](/images/process-types.png) -**W aplikacji 12factor, procesy są typem pierwszoklasowym** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych. +**W aplikacji 12factor, procesy są typem pierwszoklasowym** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych. Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku maszyny wirtualnej lub w asynchronicznym modelu wydarzeń, którego implementację możemy znaleźć wśród narzędzi takich jak [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), albo [Node.js](http://nodejs.org/). Należy pamiętać, że pojedyncza maszyna wirtualna może z czasem wymagać coraz więcej zasobów (skala pionowa), dlatego aplikacja musi być również w stanie pracować w oparciu o wiele procesów działających na wielu fizycznych maszynach. diff --git a/content/pl/logs.md b/content/pl/logs.md index 50b3bf6f0..339ae69ba 100644 --- a/content/pl/logs.md +++ b/content/pl/logs.md @@ -3,13 +3,13 @@ *Logi* zapewniają wgląd w zachowanie działającej aplikacji. W środowiskach korzystających z serwera zazwyczaj są zapisywane na dysku (plik "logfile"); jednak jest to tylko wybrany format zapisu. - Logi są listą zaagregowanych i uporządkowanych w czasie [zdarzeń](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) zebranych ze strumieni wyjściowych wszystkich uruchomionych procesów i usług wspierających. Logi w swojej pierwotnej formie występują zazwyczaj w formacie tekstowym, gdzie jedno zdarzenie zajmuje jedną linię w pliku (wyjątkiem jest jednak [backtrace](https://en.wikipedia.org/wiki/Stack_trace), który może zajmować wiele linii). Logi nie mają określonego początku ani końca, napływają nieustannie podczas działania aplikacji. + Logi są listą zaagregowanych i uporządkowanych w czasie [zdarzeń](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) zebranych ze strumieni wyjściowych wszystkich uruchomionych procesów i usług wspierających. Logi w swojej pierwotnej formie występują zazwyczaj w formacie tekstowym, gdzie jedno zdarzenie zajmuje jedną linię w pliku (wyjątkiem jest jednak [backtrace](https://en.wikipedia.org/wiki/Stack_trace), który może zajmować wiele linii). Logi nie mają określonego początku ani końca, napływają nieustannie podczas działania aplikacji. **Aplikacja 12factor nie odpowiada za przekierowywanie i zapis swojego strumienia wyjściowego.** Nie powinna też zapisywać czy zarządzać plikami logów. Zamiast tego, każdy działający proces zapisuje swój niebuforowany strumień zdarzeń do `stdout`. Podczas pracy w lokalnym środowisku developer może obserwować zachowanie aplikacji przeglądając strumień w oknie terminala We wdrożeniu stagingowym czy produkcyjnym, każdy strumień procesów zostanie przechwycony przez środowisko wykonawcze, dołączony do pozostałych i skierowany do jednego lub wielu miejsc w celu przeglądania i długoterminowego zapisu. Miejsca zapisu nie są widoczne ani konfigurowane przez aplikację - w całości zarządza nimi środowisko wykonawcze. W tym celu można skorzystać z narzędzi do obsługi logów (takich jak [Logplex](https://github.com/heroku/logplex) lub [Fluent](https://github.com/fluent/fluentd)) dostępnych na licencji open-source. -Strumień zdarzeń aplikacji może być skierowany do pliku lub obserwowany w czasie rzeczywistym przy pomocy komendy `tail` w terminalu. Przeważnie strumień jest wysyłany do systemu indeksowania i analizowania jak np. [Splunk](http://www.splunk.com/), albo do systemu magazynowania danych jak [Hadoop/Hive](http://hive.apache.org/). Wymienione systemy oferują duże możliwości i elastyczność obserwacji i badania zachowań aplikacji w czasie, w tym: +Strumień zdarzeń aplikacji może być skierowany do pliku lub obserwowany w czasie rzeczywistym przy pomocy komendy `tail` w terminalu. Przeważnie strumień jest wysyłany do systemu indeksowania i analizowania jak np. [Splunk](http://www.splunk.com/), albo do systemu magazynowania danych jak [Hadoop/Hive](http://hive.apache.org/). Wymienione systemy oferują duże możliwości i elastyczność obserwacji i badania zachowań aplikacji w czasie, w tym: * Wyszukiwanie konkretnych zdarzeń z przeszłości. * Wizualizację masowych statystyk (np. zapytania na minutę). From 8ed477bc0403109523eaedabc4c2dc29bc9f1f01 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 23 May 2016 09:11:07 +0100 Subject: [PATCH 291/472] add polish translator --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index e99d2434b..6e8599f77 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho) and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott) and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From ae2cce2971ef1693a2b6232eefc8d9436f5a24fd Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 23 May 2016 09:11:33 +0100 Subject: [PATCH 292/472] update ruby and dependencies --- Gemfile | 2 +- Gemfile.lock | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 3b02809b9..f5b0e318a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.2.4' +ruby '2.3.1' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index 65e9dc77a..09bd5d0cf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,22 @@ GEM remote: http://rubygems.org/ specs: - daemons (1.2.2) - eventmachine (1.0.7) + daemons (1.2.3) + eventmachine (1.2.0.1) i18n (0.7.0) maruku (0.7.2) - rack (1.6.0) + rack (1.6.4) rack-protection (1.5.3) rack - sinatra (1.4.6) - rack (~> 1.4) + sinatra (1.4.7) + rack (~> 1.5) rack-protection (~> 1.4) tilt (>= 1.3, < 3) - thin (1.6.3) + thin (1.6.4) daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0) + eventmachine (~> 1.0, >= 1.0.4) rack (~> 1.0) - tilt (2.0.1) + tilt (2.0.4) PLATFORMS ruby @@ -26,3 +26,9 @@ DEPENDENCIES maruku sinatra thin + +RUBY VERSION + ruby 2.3.1p112 + +BUNDLED WITH + 1.12.4 From 2b66933fe4fe0e71ef176f3a551cc9c20d3c8706 Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Tue, 31 May 2016 16:02:34 -0300 Subject: [PATCH 293/472] Improve some conections between phrases --- content/pt_br/build-release-run.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/pt_br/build-release-run.md b/content/pt_br/build-release-run.md index 22c8402b6..f15750074 100644 --- a/content/pt_br/build-release-run.md +++ b/content/pt_br/build-release-run.md @@ -9,10 +9,10 @@ Uma [base de código](./codebase) é transformada num deploy (de não-desenvolvi ![Código vira uma construção, que é combinada com a configuração para se criar um lançamento.](/images/release.png) -**O app doze-fatores usa separação estrita entre os estágios de construção, lançamento e execução.** Por exemplo, é impossível alterar código em tempo de execução, já que não meios de se propagar tais mudanças de volta ao estágio de construção. +**O app doze-fatores usa separação estrita entre os estágios de construção, lançamento e execução.** Por exemplo, é impossível alterar código em tempo de execução, já que não há meios de se propagar tais mudanças de volta ao estágio de construção. Ferramentas para deploy tipicamente oferecem ferramentas de gestão de lançamento, mais notadamente a habilidade de se reverter à um lançamento prévio. Por exemplo, a ferramenta de deploy [Capistrano](https://github.com/capistrano/capistrano/wiki) armazena lançamentos em um subdiretório chamado `releases`, onde o lançamento atual é um link simbólico para o diretório da lançamento atual. Seu comando `rollback` torna fácil reverter para um lançamento prévio. -Cada lançamento deve sempre ter um identificador de lançamento único, tal qual o timestamp do lançamento (como `2011-04-06-20:32:17`) ou um número incremental (como `v100`). Lançamentos são livro-razões onde apenas se acrescenta informações e um lançamento não pode ser alterada uma vez que é criada. Qualquer mudança deve gerar um novo lançamento. +Cada lançamento deve sempre ter um identificador de lançamento único, tal qual o timestamp do lançamento (como `2011-04-06-20:32:17`) ou um número incremental (como `v100`). Lançamentos são livro-razões onde apenas se acrescenta informações, ou seja, uma vez criado o lançamento não pode ser alterado. Qualquer mudança deve gerar um novo lançamento. -Construções são iniciadas pelos desenvolvedores do app sempre que novos códigos entrem no deploy. A execução de um executável, todavia, pode acontecer automaticamente em casos como o reinício do servidor, ou um processo travado sendo reiniciado pelo gerenciador de processos. Assim, no estágio de execução deve haver quanto menos partes móveis quanto possível, já que problemas que previnem um app de rodar pode causá-lo a travar no meio da noite quando não há desenvolvedores por perto. O estágio de construção pode ser mais complexo, já que os erros estão sempre à vista do desenvolvedor que está cuidando do deploy. +Construções são iniciadas pelos desenvolvedores do app sempre que novos códigos entram no deploy. A execução de um executável, todavia, pode acontecer automaticamente em casos como o reinício do servidor, ou um processo travado sendo reiniciado pelo gerenciador de processos. Assim, no estágio de execução deve haver quanto menos partes móveis quanto possível, já que problemas que previnem um app de rodar pode causá-lo a travar no meio da noite quando não há desenvolvedores por perto. O estágio de construção pode ser mais complexo, já que os erros estão sempre à vista do desenvolvedor que está cuidando do deploy. From b1a718516972a9a56e0ba25adcdcf373f5b12caa Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Wed, 1 Jun 2016 08:12:12 -0300 Subject: [PATCH 294/472] Translating a missing part of phrase --- content/pt_br/concurrency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index 2e4a33492..efeb71e9d 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -1,11 +1,11 @@ ## VIII. Concorrência ### Escale através do processo modelo -Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processo PHP rodam como processos filho do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. +Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processos PHP rodam como processos filhos do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o(s) processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. ![Escala é expressado como processos em execução, a diversidade da carga de trabalho é expressada como tipos de processo.](/images/process-types.png) -**Na aplicação doze-fatores, processos são cidadãos de primeira classe.** Processos na aplicação doze-fatores, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. +**Na aplicação doze-fatores, processos são cidadãos de primeira classe.** Processos na aplicação doze-fatores utilizam fortes sugestões do modelo de processos UNIX para execução de serviços daemon, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. From bb56cf5f959b140ba17f5c6326e38ff732347c9d Mon Sep 17 00:00:00 2001 From: slauth Date: Tue, 7 Jun 2016 09:48:44 +0200 Subject: [PATCH 295/472] fixed typo --- content/de/who.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/who.md b/content/de/who.md index 7302cb950..b25d5aeb4 100644 --- a/content/de/who.md +++ b/content/de/who.md @@ -1,4 +1,4 @@ -We sollte dieses Dokument lesen? +Wer sollte dieses Dokument lesen? ============================== Jeder Entwickler der Apps baut, die als Dienst laufen. Administratoren, die solche Apps managen oder deployen. From ad2d7481ec05f944cb7f9c7649d4d4b7f91ec066 Mon Sep 17 00:00:00 2001 From: Hugo Abonizio Date: Mon, 25 Jul 2016 15:34:40 -0300 Subject: [PATCH 296/472] Remove duplicated word --- content/pt_br/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/logs.md b/content/pt_br/logs.md index 3162be066..4f4b57794 100644 --- a/content/pt_br/logs.md +++ b/content/pt_br/logs.md @@ -9,7 +9,7 @@ Logs são o [fluxo](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_no Em deploys de homologação ou produção, cada fluxo dos processos serão capturados pelo ambiente de execução, colados com todos os demais fluxos do app, e direcionados para um ou mais destinos finais para visualização e arquivamento de longo prazo. Estes destinos de arquivamento não são visíveis ou configuráveis pelo app, e ao invés disso, são completamente geridos pelo ambiente de execução. Roteadores de log open source (tais como [Logplex](https://github.com/heroku/logplex) e [Fluent](https://github.com/fluent/fluentd)) estão disponíveis para este propósito. -O fluxo de evento para um app pode ser direcionado para um arquivo, ou visto em tempo real via `tail` num terminal. Mais significativamente, o fluxo pode ser enviado para um sistema indexador e analisador tal como [Splunk](http://www.splunk.com/), ou um um sistema mais genérico de _data warehousing_ como o [Hadoop/Hive](http://hive.apache.org/). Estes sistemas permitem grande poder e flexibilidade para observar o comportamento de um app durante o tempo, incluindo: +O fluxo de evento para um app pode ser direcionado para um arquivo, ou visto em tempo real via `tail` num terminal. Mais significativamente, o fluxo pode ser enviado para um sistema indexador e analisador tal como [Splunk](http://www.splunk.com/), ou um sistema mais genérico de _data warehousing_ como o [Hadoop/Hive](http://hive.apache.org/). Estes sistemas permitem grande poder e flexibilidade para observar o comportamento de um app durante o tempo, incluindo: * Encontrando eventos específicos no passado. * Gráficos em larga escala de tendências (como requisições por minuto) From d688b4ae1c01bda6f2a4721b8d10030c5beb1778 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 27 Jul 2016 16:10:09 +0200 Subject: [PATCH 297/472] Empty test suite for Travis CI --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..f3b6e9fe9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +script: exit 0 +sudo: false From f9f2b6328ed1cb66be3fed95d2b6d315de9f5016 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 27 Jul 2016 16:38:18 +0200 Subject: [PATCH 298/472] Specify Ruby 2.3.1 for Travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index f3b6e9fe9..546e58466 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,2 +1,5 @@ +language: ruby +rvm: + - 2.3.1 script: exit 0 sudo: false From 82b27e69599f7a7fca9f30b538cb0de2f9305416 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 27 Jul 2016 16:31:36 +0200 Subject: [PATCH 299/472] Fix typo Props to @slauth --- content/de/who.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/who.md b/content/de/who.md index 7302cb950..b25d5aeb4 100644 --- a/content/de/who.md +++ b/content/de/who.md @@ -1,4 +1,4 @@ -We sollte dieses Dokument lesen? +Wer sollte dieses Dokument lesen? ============================== Jeder Entwickler der Apps baut, die als Dienst laufen. Administratoren, die solche Apps managen oder deployen. From c2312912a86d769c5c328d2bc5fc7af5ef7b63e1 Mon Sep 17 00:00:00 2001 From: adamhmetal Date: Wed, 3 Aug 2016 10:12:41 +0200 Subject: [PATCH 300/472] Fix typo --- content/pl/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/intro.md b/content/pl/intro.md index 1b5be75f5..7dc74abf3 100644 --- a/content/pl/intro.md +++ b/content/pl/intro.md @@ -1,7 +1,7 @@ Wprowadzenie ============ -We współczesnym świecie oprogramowanie jest powszechnie wytwarzane w formie usługi, nazywane _software-as-sarvice (SaaS)_ lub aplikacjami internetowymi. Dwanaście aspektów aplikacji jest metodologią budowania aplikacji SaaS, które: +We współczesnym świecie oprogramowanie jest powszechnie wytwarzane w formie usługi, nazywane _software-as-service (SaaS)_ lub aplikacjami internetowymi. Dwanaście aspektów aplikacji jest metodologią budowania aplikacji SaaS, które: * Używają **deklaratywnego** formatu by zautomatyzować konfigurację aplikacji w celu zmniejszenia czasu i kosztów dołączenia nowych programistów do projektu; * Mają **czysty kontrakt** z systemem operacyjnym, umożliwiając **jak największą możliwość przenoszenia** pomiędzy środowiskami, w których działają; From beec67493782615c1d6636c95622cd8768999546 Mon Sep 17 00:00:00 2001 From: Max Beizer Date: Wed, 17 Aug 2016 10:19:03 -0500 Subject: [PATCH 301/472] Force SSL with rack-ssl-enforcer (#113) * Add rack-ssl-enforcer * Use config var to conditionally force SSL --- .gitignore | 1 + Gemfile | 1 + Gemfile.lock | 4 +++- web.rb | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6471d9f4c..fa2d9f1f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .rvmrc +.bundle diff --git a/Gemfile b/Gemfile index f5b0e318a..67620ca50 100644 --- a/Gemfile +++ b/Gemfile @@ -6,3 +6,4 @@ gem 'sinatra' gem 'thin' gem 'maruku' gem 'i18n' +gem 'rack-ssl-enforcer' diff --git a/Gemfile.lock b/Gemfile.lock index 09bd5d0cf..9c24f402f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ GEM rack (1.6.4) rack-protection (1.5.3) rack + rack-ssl-enforcer (0.2.9) sinatra (1.4.7) rack (~> 1.5) rack-protection (~> 1.4) @@ -24,6 +25,7 @@ PLATFORMS DEPENDENCIES i18n maruku + rack-ssl-enforcer sinatra thin @@ -31,4 +33,4 @@ RUBY VERSION ruby 2.3.1p112 BUNDLED WITH - 1.12.4 + 1.12.5 diff --git a/web.rb b/web.rb index 2622a782b..6f2f81b66 100644 --- a/web.rb +++ b/web.rb @@ -1,8 +1,10 @@ require 'sinatra' require 'maruku' require 'i18n' +require 'rack/ssl-enforcer' configure do + use Rack::SslEnforcer if ENV['FORCE_SSL'] I18n.enforce_available_locales = true I18n.load_path = Dir[File.join(settings.root, 'locales', '*.yml')] I18n.backend.load_translations From c7521a3de26ccf290a862ad19374b896e25ea529 Mon Sep 17 00:00:00 2001 From: Wender Freese Date: Tue, 23 Aug 2016 09:23:49 -0300 Subject: [PATCH 302/472] Fixing some cut words and agreement of portuguese. --- content/pt_br/backing-services.md | 4 ++-- content/pt_br/build-release-run.md | 2 +- content/pt_br/codebase.md | 3 +-- content/pt_br/concurrency.md | 2 +- content/pt_br/config.md | 4 ++-- content/pt_br/dev-prod-parity.md | 4 ++-- content/pt_br/disposability.md | 4 +--- 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/content/pt_br/backing-services.md b/content/pt_br/backing-services.md index 589124ba0..efb86fce6 100644 --- a/content/pt_br/backing-services.md +++ b/content/pt_br/backing-services.md @@ -1,7 +1,7 @@ ## IV. Serviços de Apoio ### Trate serviços de apoio como recursos anexados -Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). +Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados (como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). @@ -11,4 +11,4 @@ Cada serviço de apoio distinto é um *recurso*. Por exemplo, um banco MySQL é Um deploy de produção anexado a quatro serviços de apoio. -Recursos podem ser anexados e desanexados a deploys à vontade. Por exemplo, se o banco de dados do app não está funcionando corretamente devido a um problema de hardware, o administrador do app pode subir um novo servidor de banco de dados restaurado de um backup recente. O atual banco de produção por ser desanexado, e o novo banco anexado -- tudo sem nenhuma mudança no código. +Recursos podem ser anexados e desanexados a deploys à vontade. Por exemplo, se o banco de dados do app não está funcionando corretamente devido a um problema de hardware, o administrador do app pode subir um novo servidor de banco de dados restaurado de um backup recente. O atual banco de produção pode ser desanexado, e o novo banco anexado -- tudo sem nenhuma mudança no código. diff --git a/content/pt_br/build-release-run.md b/content/pt_br/build-release-run.md index f15750074..610ddee68 100644 --- a/content/pt_br/build-release-run.md +++ b/content/pt_br/build-release-run.md @@ -11,7 +11,7 @@ Uma [base de código](./codebase) é transformada num deploy (de não-desenvolvi **O app doze-fatores usa separação estrita entre os estágios de construção, lançamento e execução.** Por exemplo, é impossível alterar código em tempo de execução, já que não há meios de se propagar tais mudanças de volta ao estágio de construção. -Ferramentas para deploy tipicamente oferecem ferramentas de gestão de lançamento, mais notadamente a habilidade de se reverter à um lançamento prévio. Por exemplo, a ferramenta de deploy [Capistrano](https://github.com/capistrano/capistrano/wiki) armazena lançamentos em um subdiretório chamado `releases`, onde o lançamento atual é um link simbólico para o diretório da lançamento atual. Seu comando `rollback` torna fácil reverter para um lançamento prévio. +Ferramentas para deploy tipicamente oferecem ferramentas de gestão de lançamento, mais notadamente a habilidade de se reverter à um lançamento prévio. Por exemplo, a ferramenta de deploy [Capistrano](https://github.com/capistrano/capistrano/wiki) armazena lançamentos em um subdiretório chamado `releases`, onde o lançamento atual é um link simbólico para o diretório de lançamento atual. Seu comando `rollback` torna fácil reverter para um lançamento prévio. Cada lançamento deve sempre ter um identificador de lançamento único, tal qual o timestamp do lançamento (como `2011-04-06-20:32:17`) ou um número incremental (como `v100`). Lançamentos são livro-razões onde apenas se acrescenta informações, ou seja, uma vez criado o lançamento não pode ser alterado. Qualquer mudança deve gerar um novo lançamento. diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index e326c7e34..497aa38a4 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -10,9 +10,8 @@ Uma *base de código* é um único repo (em um sistema de controle de versão ce Existe sempre uma correlação um-para-um entre a base de código e a aplicação: * Se existem várias bases de código, isto não é uma app -- é um sistema distribuído. Cada componente do sistema é uma app, e cada uma pode individualmente ser compatível com os 12 fatores. -* Multiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas através do [gerenciador de dependências](/dependencies). +* Múltiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas através do [gerenciador de dependências](/dependencies). Existe apenas uma base de código por aplicação, mas existirão vários deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. A base de código é a mesma através de todos os deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não deployados no ambiente de teste, o ambiente de teste ainda tem registros não deployados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. - diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index efeb71e9d..8099c8574 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -1,7 +1,7 @@ ## VIII. Concorrência ### Escale através do processo modelo -Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processos PHP rodam como processos filhos do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o(s) processo(os) executando é apenas minimamente visível para o desenvolvedores da aplicação. +Qualquer programa de computador, uma vez executado, está representado por um ou mais processos. Aplicações web têm tomado uma variedade de formas de processo de execução. Por exemplo, processos PHP rodam como processos filhos do Apache, iniciados sob demanda conforme necessário por volume de requisições. Processos Java tomam o caminho inverso, com a JVM proporcionando um processo uber maciço que reserva um grande bloco de recursos do sistema (CPU e memória) na inicialização, com concorrência gerenciada internamente via threads. Em ambos os casos, o(s) processo(os) em execução são apenas minimamente visível para os desenvolvedores da aplicação. ![Escala é expressado como processos em execução, a diversidade da carga de trabalho é expressada como tipos de processo.](/images/process-types.png) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index 2b4f861b9..31dfd703b 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -15,8 +15,8 @@ Note que esta definição de "configuração" **não** inclui configuração int Outra abordagem para configuração é o uso de arquivos de configuração que não são versionados no controle de versão, como `config/database.yml` em Rails. Isto é uma grande melhoria sobre o uso de constantes que são versionadas no repositório do código, mas ainda tem pontos fracos: é fácil de colocar por engano um arquivo de configuração no repositório; há uma tendência para que os arquivos de configuração sejam espelhados em diferentes lugares e diferentes formatos, tornando-se difícil de ver e gerenciar todas as configurações em um só lugar. Além disso estes formatos tendem a ser específicos da linguagem ou framework. -**A aplicação doze-fatores armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código. ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. +**A aplicação doze-fatores armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código; ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. -Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, aplicações de configuração em batch dentro de grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. +Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, as aplicações incluem a configuração em grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. Em uma aplicação doze-fatores, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independentemente para cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index ac774902c..945c4da82 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -69,8 +69,8 @@ Resumindo o acima em uma tabela: Desenvolvedores as vezes vem uma grande vantagem em usar um serviço de apoio leve em seus ambientes, enquanto um serviço de apoio mais sério e robusto seria usado em produção. Por exemplo, usando SQLite localmente e PostgreSQL em produção; ou memória de processo local para caching em desenvolvimento e Memcached em produção. -**O desenvolvedor doze-fatores resiste a tentação de usar diferentes serviços de apoio entre desenvolvimento e produção**, mesmo quando adaptadores teoricamente abstraem as diferenças dos serviços de apoio. Diferenças entre serviços de apoio significam que pequenas incompatibilidades aparecerão, causando código que funcionava e passava em desenvolvimento ou homologação, falhará em produção. Tais tipos de erros criam fricção que desincentivam deploy contínuo. O custo dessa fricção e do subsequente decaimento de deploy contínuo é extremamente alto quando considerado que vai acumular no tempo de vida da aplicação. +**O desenvolvedor doze-fatores resiste a tentação de usar diferentes serviços de apoio entre desenvolvimento e produção**, mesmo quando adaptadores teoricamente abstraem as diferenças dos serviços de apoio. Diferenças entre serviços de apoio significam que pequenas incompatibilidades aparecerão, fazendo com que código que funcionava e passava em desenvolvimento ou homologação, falhe em produção. Tais tipos de erros criam fricção que desincentivam deploy contínuo. O custo dessa fricção e do subsequente decaimento de deploy contínuo é extremamente alto quando considerado que vai acumular no tempo de vida da aplicação. -Serviços locais leves são menos tentadores que já foram um dia. Serviços de apoio modernos tais como Memcached, PostgreSQL, e RabbitMQ não são difíceis de instalar e rodam graças a sistemas modernos de empacotamento tias como [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternativamente, ferramentas de provisionamento declarativo tais como [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/) combinado com ambientes virtuais leves como [Vagrant](http://vagrantup.com/) permitem desenvolvedores rodar ambientes locais que são bem próximos dos ambientes de produção. O custo de instalar e usar esses sistemas é baixo comparado ao benefício de ter a paridade entre desenv/produção e deploy contínuo. +Serviços locais leves são menos tentadores que já foram um dia. Serviços de apoio modernos tais como Memcached, PostgreSQL, e RabbitMQ não são difíceis de instalar e rodam graças a sistemas modernos de empacotamento tais como [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternativamente, ferramentas de provisionamento declarativo tais como [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/) combinado com ambientes virtuais leves como [Vagrant](http://vagrantup.com/) permitem desenvolvedores rodar ambientes locais que são bem próximos dos ambientes de produção. O custo de instalar e usar esses sistemas é baixo comparado ao benefício de ter a paridade entre desenv/produção e deploy contínuo. Adaptadores para diferentes serviços de apoio ainda são úteis, pois eles fazem a portabilidade para novos serviços de apoio relativamente tranquilas. Mas todos os deploys do app (ambientes de desenvolvimento, homologação, produção) devem usar o mesmo tipo e versão de cada serviço de apoio. diff --git a/content/pt_br/disposability.md b/content/pt_br/disposability.md index 9df9a07da..b5d76a054 100644 --- a/content/pt_br/disposability.md +++ b/content/pt_br/disposability.md @@ -3,12 +3,10 @@ **Os [processos](./processos) de um app doze-fatores são *descartáveis*, significando que podem ser iniciados ou parados a qualquer momento.** Isso facilita o escalonamento elástico, rápido deploy de [código](./codebase) ou mudanças de [configuração](./config), e robustez de deploys de produção. -Processos devem empenhar-se em **minizar o tempo de inicialização**. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de [release](./build-release-run) e de escalonamento; e ele adiciona robustez, pois o o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário. +Processos devem empenhar-se em **minimizar o tempo de inicialização**. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de [release](./build-release-run) e de escalonamento; e ele adiciona robustez, pois o o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário. Processos **desligam-se graciosamente quando recebem um sinal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** do seu gestor de processos. Para um processo web, desligamento gracioso é alcançado quando cessa de escutar à porta de serviço (consequentemente recusando quaisquer requisições novas), permitindo qualquer requisição em andamento terminar, e então desligando. Implícito neste modelo é que as requisições HTTP são curtas (não mais que alguns poucos segundos), ou no caso de um longo _polling_, o cliente deve ser capaz de transparentemente tentar se reconectar quando a conexão for perdida. Para um processo de trabalho (worker), desligamento gracioso é alcançado retornando a tarefa atual para fila de trabalho. Por exemplo, no [RabbitMQ](http://www.rabbitmq.com/) o trabalhador pode enviar um [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); no [Beanstalkd](http://kr.github.com/beanstalkd/), a tarefa é retornada para a fila automaticamente sempre que um trabalhador se desconecta. Sistemas baseados em trava como o [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) precisam se certificar de soltar a trava no registro da tarefa. Implícito neste modelo é que todas as tarefas são [reentrantes](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), o que tipicamente é atingindo envolvendo os resultados numa transação, ou tornando a operação [idempotente](http://en.wikipedia.org/wiki/Idempotence). Processos também devem ser **robustos contra morte súbida**, no caso de uma falha de hardware. Ao passo que isso é muito menos comum que um desligamento via `SIGTERM`, isso ainda pode acontecer. Uma abordagem recomendada é usar um backend de filas robusto, como o Beanstalkd, que retorna tarefas à fila quando clientes desconectam ou esgotam o tempo de resposta. De qualquer forma, um app doze-fatores é arquitetado para lidar com terminações não esperadas e não graciosas. [Crash-only design](http://lwn.net/Articles/191059/) leva este conceito à sua [conclusão lógica](http://docs.couchdb.org/en/latest/intro/overview.html). - - From 9a0ebda29b52b7092f7802e62403bf9bb9b3c212 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Tue, 30 Aug 2016 22:47:38 +0100 Subject: [PATCH 303/472] Update local run instructions --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 6e8599f77..16e2329ab 100644 --- a/Readme.md +++ b/Readme.md @@ -7,7 +7,7 @@ Development ----------- bundle install - foreman start + heroku local:start open http://localhost:5000 Production deploy From 42f01e3ea7ff2c9a221f640adbba3ada9ad30759 Mon Sep 17 00:00:00 2001 From: Marcelo Date: Sat, 3 Sep 2016 12:36:47 -0300 Subject: [PATCH 304/472] Fixed some grammar and spelling issues --- content/pt_br/admin-processes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 4924ffd2d..cd162ec36 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -3,12 +3,12 @@ O [processo de formação](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app como ela é executada (tais como manipulação de requisições web). Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: -* Executando migrações de base de dados (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). -* Executando um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbitrário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). -* Executando uma vez os scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). +* Executar migrações de base de dados (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). +* Executar um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbitrário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). +* Executar uma vez os scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). Processos de administração pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado com essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. -Dozes-fatores favorece fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. +Doze-fatores favorece fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From 9a5027f7627d63fc487207f59b857a96da1cb933 Mon Sep 17 00:00:00 2001 From: Daniel Manesku Date: Sun, 4 Sep 2016 00:43:16 +0200 Subject: [PATCH 305/472] Adding Docker next to Vagrant --- content/en/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/dev-prod-parity.md b/content/en/dev-prod-parity.md index f6e573342..b3a47e012 100644 --- a/content/en/dev-prod-parity.md +++ b/content/en/dev-prod-parity.md @@ -71,6 +71,6 @@ Developers sometimes find great appeal in using a lightweight backing service in **The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Docker](https://www.docker.com/) and [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. From 34d126000fdc49f888518d955732550af3e7889c Mon Sep 17 00:00:00 2001 From: Cyril Sadovnik Date: Mon, 5 Sep 2016 15:14:28 +0400 Subject: [PATCH 306/472] Translated "or" --- content/ru/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md index a9326747b..abe5579ff 100644 --- a/content/ru/admin-processes.md +++ b/content/ru/admin-processes.md @@ -4,7 +4,7 @@ [Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам периодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: * Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). -* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` or `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). +* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` или `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). * Запуск разовых скриптов, хранящихся в репозитории приложения (например, `php scripts/fix_bad_records.php`). Разовые процессы администрирования следует запускать в среде идентичной регулярным [длительным процессам](./processes) приложения. Они запускаются на уровне [релиза](./build-release-run), используя те же [кодовую базу](./codebase) и [конфигурацию](./config), как и любой другой процесс, выполняющий этот релиз. Код администрирования должен поставляться вместе с кодом приложения, чтобы избежать проблем синхронизации. From a5804e99156302c1fa56bcb0659dd5d809a18353 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 17 Sep 2016 11:23:56 +0200 Subject: [PATCH 307/472] Load external JavaScript wihtout specifying protocol Closes #115 --- views/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/layout.erb b/views/layout.erb index 897044eb4..643bd102e 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -13,7 +13,7 @@ - + From d5025e243e0a59e6c87d70417b46d94af1a94e4b Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 17 Sep 2016 11:55:44 +0200 Subject: [PATCH 308/472] Link to https in the readme --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 6e8599f77..5a29d8ced 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ The Twelve-Factor App ===================== -Source for the content app running at: http://www.12factor.net/ +Source for the content app running at: https://www.12factor.net/ Development ----------- From 623ba6908c0228f17b7a03f7997dbd68af7e22a4 Mon Sep 17 00:00:00 2001 From: Pedro Galvan Date: Tue, 27 Sep 2016 12:39:53 -0500 Subject: [PATCH 309/472] Replaced 'disponible' (available) with the proper word: 'desechable' (disposable) --- content/es/disposability.md | 4 ++-- content/es/toc.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/disposability.md b/content/es/disposability.md index 203e01771..9900459f7 100644 --- a/content/es/disposability.md +++ b/content/es/disposability.md @@ -1,7 +1,7 @@ -## IX. Disponibilidad +## IX. Desechabilidad ### Hacer el sistema más robusto intentando conseguir inicios rápidos y finalizaciones seguras -**Los [procesos](./processes) de las aplicaciones "twelve-factor" están *disponibles*, lo que significa que pueden iniciarse o finalizarse en el momento que sea necesario.** Esto permite un escalado rápido y flexible, un despliegue rápido del [código](./codebase) y de los cambios de las [configuraciones](./config), y despliegues más robustos en producción. +**Los [procesos](./processes) de las aplicaciones "twelve-factor" son *desechables*, lo que significa que pueden iniciarse o finalizarse en el momento que sea necesario.** Esto permite un escalado rápido y flexible, un despliegue rápido del [código](./codebase) y de los cambios de las [configuraciones](./config), y despliegues más robustos en producción. Los procesos deberían intentar conseguir **minimizar el tiempo de arranque**. En el mejor de los casos, un proceso necesita unos pocos segundos desde que se ejecuta el mandato hasta que arranca y está preparado para recibir peticiones o trabajos. Mejorar el tiempo de arranque proporciona mayor agilidad en el proceso de [distribución](./build-release-run) y escalado; y lo hace más robusto, porque el gestor de procesos puede mover procesos de forma segura entre máquinas físicas más fácilmente. diff --git a/content/es/toc.md b/content/es/toc.md index 3fa758b62..a175f0660 100644 --- a/content/es/toc.md +++ b/content/es/toc.md @@ -25,7 +25,7 @@ Twelve Factors ## [VIII. Concurrencia](./concurrency) ### Escalar mediante el modelo de procesos -## [IX. Disponibilidad](./disposability) +## [IX. Desechabilidad](./disposability) ### Hacer el sistema más robusto intentando conseguir inicios rápidos y finalizaciones seguras ## [X. Paridad en desarrollo y producción](./dev-prod-parity) From 91b84de991e9aeaf9801ae7b27863beada9f4500 Mon Sep 17 00:00:00 2001 From: Remi Verchere Date: Wed, 5 Oct 2016 22:59:03 +0200 Subject: [PATCH 310/472] Update processes.md incorrect translation for database --- content/fr/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/processes.md b/content/fr/processes.md index 8ef21409f..cc79b9e2b 100644 --- a/content/fr/processes.md +++ b/content/fr/processes.md @@ -7,7 +7,7 @@ Dans la situation la plus simple, le code est un script indépendant, l'environn **Les processus 12 facteurs sont sans état et ne partagent [rien (en)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. -L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de donnes. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est-à-dire en mémoire et sur le disque). +L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de données. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est-à-dire en mémoire et sur le disque). Des outils de création de paquets de ressources (ou "asset packagers") (tel que [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) utilisent le système de fichier comme cache pour les ressources compilées. Une application 12 facteurs préfère faire cette compilation durant l'[étape d'assemblage](./build-release-run), comme avec le [pipeline des ressources de Rails](http://guides.rubyonrails.org/asset_pipeline.html), plutôt que durant l'exécution. From 20ccc9e59a380645551aaa97c353b08eccef55c2 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 10 Oct 2016 10:40:25 -0300 Subject: [PATCH 311/472] Explain the word deploy --- content/pt_br/codebase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index 497aa38a4..66181a436 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -12,6 +12,6 @@ Existe sempre uma correlação um-para-um entre a base de código e a aplicaçã * Se existem várias bases de código, isto não é uma app -- é um sistema distribuído. Cada componente do sistema é uma app, e cada uma pode individualmente ser compatível com os 12 fatores. * Múltiplas apps compartilhando uma base de código é uma violação dos 12 fatores. A solução aqui é dividir o código compartilhado entre bibliotecas que podem ser incluídas através do [gerenciador de dependências](/dependencies). -Existe apenas uma base de código por aplicação, mas existirão vários deploys da mesma. Um *deploy* é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. +Existe apenas uma base de código por aplicação, mas existirão vários deploys da mesma. Um *deploy* (ou implantação) é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. -A base de código é a mesma através de todos os deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não deployados no ambiente de teste, o ambiente de teste ainda tem registros não deployados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. +A base de código é a mesma através de todos os deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não implantados no ambiente de teste, o ambiente de teste ainda tem registros não implantados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. From e5df899003c2069e48470729505cc955782b3a30 Mon Sep 17 00:00:00 2001 From: kakty3 Date: Thu, 13 Oct 2016 22:51:24 +0700 Subject: [PATCH 312/472] Fix typo in russian translation (dev-prod-parity) --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index fdd594f03..e2bad32e3 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -69,7 +69,7 @@ Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьезные и надежные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кэширования при разработке и Memcached в рабочем окружении. -**Разработчик приложения двенадцати факторов должен сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. +**Разработчик приложения двенадцати факторов сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. Установка локальных сервисов стала менее непреодолимой задачей, чем она когда-то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, таким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. From 8d53432dd4cc992494c9ff8e27de20e2919b11d8 Mon Sep 17 00:00:00 2001 From: Toddy69 Date: Sat, 22 Oct 2016 16:34:31 +0200 Subject: [PATCH 313/472] fixed typos --- content/de/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/config.md b/content/de/config.md index 3f0850ac7..aae816698 100644 --- a/content/de/config.md +++ b/content/de/config.md @@ -14,7 +14,7 @@ Ein Lackmustest ob eine App die Konfiguration vollständig ausgelagert hat ist, 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 of Sprach- oder Plattform-spezifisch. +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. **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. From b1d044769219a8130bba17a2ebd10a859a9f9515 Mon Sep 17 00:00:00 2001 From: Jake Worth Date: Wed, 26 Oct 2016 16:03:27 -0500 Subject: [PATCH 314/472] Update Bundler name and link --- content/en/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/dependencies.md b/content/en/dependencies.md index bf5a2dd91..d53fd4cd8 100644 --- a/content/en/dependencies.md +++ b/content/en/dependencies.md @@ -5,7 +5,7 @@ Most programming languages offer a packaging system for distributing support lib **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, [Gem Bundler](http://gembundler.com/) 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. +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`. From f6ab251ba81573bfdb0430717ac598ca953262dd Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 27 Oct 2016 07:55:05 +0100 Subject: [PATCH 315/472] fix all bundler links --- content/de/dependencies.md | 4 ++-- content/es/dependencies.md | 2 +- content/fr/dependencies.md | 2 +- content/it/dependencies.md | 4 ++-- content/ja/dependencies.md | 2 +- content/ko/dependencies.md | 6 +++--- content/pl/dependencies.md | 2 +- content/pt_br/dependencies.md | 2 +- content/ru/dependencies.md | 2 +- content/zh_cn/dependencies.md | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/content/de/dependencies.md b/content/de/dependencies.md index 460b8419d..7d0057f1a 100644 --- a/content/de/dependencies.md +++ b/content/de/dependencies.md @@ -5,8 +5,8 @@ Die meisten Programmiersprachen bieten ein System an um unterstützende Biblioth **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 [Gem Bundler](http://gembundler.com/) 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. +So bietet zum Beispiel [Gem 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`. -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. \ No newline at end of file +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/es/dependencies.md b/content/es/dependencies.md index b6435da0c..092a616f0 100644 --- a/content/es/dependencies.md +++ b/content/es/dependencies.md @@ -5,7 +5,7 @@ La mayoría de los lenguajes de programación tienen un sistema de gestión de p **Una aplicación "twelve-factor" no depende nunca de la existencia explícita de paquetes instalados en el sistema.** Declara todas sus dependencias, completamente y explícitamente, mediante un manifiesto de *declaración de dependencias*. Además, usa herramientas de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implícitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita se aplica de la misma manera tanto en producción como en desarrollo. -Por ejemplo, la [gema Bundler](http://gembundler.com/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa qué conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". +Por ejemplo, la [gema Bundler](https://bundler.io/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa qué conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". Uno de los beneficios de la declaración explícita de dependencias es que simplifica la configuración para los nuevos desarrolladores de la aplicación. Cualquier desarrollador que se incorpore al equipo debe poder probar el código base de la aplicación en su máquina de desarrollo. Tan solo debe tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para ejecutar el código de la aplicación con un *mandato para construir*. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index 548b9903d..def9fbcb2 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -5,7 +5,7 @@ La plupart des langages de programmation offrent des systèmes pour créer des p **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épendances 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, [Gem Bundler](http://gembundler.com/) 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 chaine 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. +Par exemple, [Gem 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 chaine 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 oeil à 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`. diff --git a/content/it/dependencies.md b/content/it/dependencies.md index 8b86314d2..8e507ee49 100644 --- a/content/it/dependencies.md +++ b/content/it/dependencies.md @@ -5,8 +5,8 @@ Molti linguaggi di programmazione offrono dei sistemi di packaging per la distri **Un'applicazione che aderisce alla twelve-factor non si basa mai sull'esistenza implicita di librerie system-wide**. Le dipendenze vengono tutte dichiarate, tramite un manifest dedicato. Inoltre, viene contemplato anche l'uso di un tool di *isolamento delle dipendenze* durante l'esecuzione, in modo tale da assicurarsi che non ci siano delle "dipendenze implicite" che creino interferenze nel sistema in cui ci si trova. La specifica completa ed esplicita delle dipendenze si applica in modo uniforme: sia in production che in sviluppo. -Ad esempio, [Gem Bundler](http://gembundler.com/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. +Ad esempio, [Gem Bundler](https://bundler.io/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. Un altro importante beneficio di una dichiarazione esplicita delle dipendenze sta nel fatto che semplifica di molto la configurazione iniziale per gli sviluppatori appena entrati a lavorare al progetto. Il nuovo arrivato non dovrà fare altro che effettuare un check out della codebase nella propria macchina di sviluppo, occupandosi di dover installare solo ed esclusivamente le dipendenze, appunto, dichiarate. Molto spesso è inoltre presente un *build command* che permette di automatizzare il processo. Per Ruby/Bundler si usa `bundle install`, mentre per Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'è `lein deps`. -Ogni applicazione che aderisce alla metodologia twelve-factor, inoltre, non si basa mai sull'esistenza di un qualsiasi tool di sistema. Alcuni esempi sono *ImageMagick* o *curl*. Nonostante questi software esistano già su buona parte dei sistemi in circolazione, non è comunque detto che siano presenti su tutti quelli su cui girerà l'applicazione in futuro. Se l'app non può fare a meno di questo tool, si dovrebbe prendere in considerazione l'idea di "vendorizzarlo" nell'applicazione stessa. \ No newline at end of file +Ogni applicazione che aderisce alla metodologia twelve-factor, inoltre, non si basa mai sull'esistenza di un qualsiasi tool di sistema. Alcuni esempi sono *ImageMagick* o *curl*. Nonostante questi software esistano già su buona parte dei sistemi in circolazione, non è comunque detto che siano presenti su tutti quelli su cui girerà l'applicazione in futuro. Se l'app non può fare a meno di questo tool, si dovrebbe prendere in considerazione l'idea di "vendorizzarlo" nell'applicazione stessa. diff --git a/content/ja/dependencies.md b/content/ja/dependencies.md index 2bc89dc1b..562b8a89f 100644 --- a/content/ja/dependencies.md +++ b/content/ja/dependencies.md @@ -5,7 +5,7 @@ **Twelve-Factor Appは、システム全体にインストールされるパッケージが暗黙的に存在することに決して依存しない。** すべての依存関係を *依存関係宣言* マニフェストで完全かつ厳密に宣言する。さらに、実行時には *依存関係分離* ツールを使って、取り囲んでいるシステムから暗黙の依存関係が“漏れ出ない”ことを保証する。完全かつ明示的な依存関係の指定は、本番環境と開発環境の両方に対して同様に適用される。 -例えば、Rubyで使われる[Gem Bundler](http://gembundler.com/) は、依存関係宣言のためのマニフェストのフォーマットである`Gemfile`と依存関係分離のための`bundle exec`を提供している。Pythonではこれらのステップで2つの別々のツールが使われる -- [Pip](http://www.pip-installer.org/en/latest/)が宣言のために使われ、[Virtualenv](http://www.virtualenv.org/en/latest/)が分離のために使われる。C言語でも[Autoconf](http://www.gnu.org/s/autoconf/)で依存関係を宣言し、静的リンクで依存関係を分離することができる。ツールが何であれ、依存関係の宣言と分離は常に一緒に使わなければならない -- どちらか片方だけではTwelve-Factorを満足するのに不十分である。 +例えば、Rubyで使われる[Gem Bundler](https://bundler.io/) は、依存関係宣言のためのマニフェストのフォーマットである`Gemfile`と依存関係分離のための`bundle exec`を提供している。Pythonではこれらのステップで2つの別々のツールが使われる -- [Pip](http://www.pip-installer.org/en/latest/)が宣言のために使われ、[Virtualenv](http://www.virtualenv.org/en/latest/)が分離のために使われる。C言語でも[Autoconf](http://www.gnu.org/s/autoconf/)で依存関係を宣言し、静的リンクで依存関係を分離することができる。ツールが何であれ、依存関係の宣言と分離は常に一緒に使わなければならない -- どちらか片方だけではTwelve-Factorを満足するのに不十分である。 明示的に依存関係を宣言する利点の1つは、アプリケーションに新しい開発者が加わった際のセットアップを単純化できることである。新しい開発者は、言語のランタイムと依存関係管理ツールさえインストールされていれば、アプリケーションのコードベースを自分の開発マシンにチェックアウトすることができる。開発者は決められた *ビルドコマンド* で、アプリケーションのコードを実行するために必要なすべてのものをセットアップできる。例えば、Ruby/Bundlerのビルドコマンドは`bundle install`であり、Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)では`lein deps`である。 diff --git a/content/ko/dependencies.md b/content/ko/dependencies.md index 66ffb5e2b..51ce42d6f 100644 --- a/content/ko/dependencies.md +++ b/content/ko/dependencies.md @@ -1,12 +1,12 @@ -## II. 종속성 +## II. 종속성 ### 명시적으로 선언되고 분리된 종속성 대부분의 프로그래밍 언어는 라이브러리 배포를 위한 패키징 시스템을 제공하고 있습니다. Perl의 [CPAN](http://www.cpan.org/) 이나 Ruby의 [Rubygems](http://rubygems.org/)가 그 예입니다. 라이브러리는 패키징 시스템을 통해 시스템 전체(site pakages)나 애플리케이션을 포함한 디렉토리(vendoring 혹은 bundling)에 설치될 수 있습니다. **Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. -예를 들어, 루비에서 사용되는 [Gem Bundler](http://gembundler.com/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. +예를 들어, 루비에서 사용되는 [Gem Bundler](https://bundler.io/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. 명시적인 종속성 선언의 장점 중 하나는 애플리케이션 개발에 새로 참가하게 된 개발자가 설치를 간단하게 할 수 있다는 점입니다. 새로 참가한 개발자는 애플리케이션의 코드베이스를 개발 머신에 체크아웃 하고, 언어의 런타임과 종속성 매니저만 미리 설치하면 됩니다. 개발자는 정해져있는 *빌드 명령어*만 입력하면 응용 프로그램의 코드를 실행하는 데 필요한 모든 것을 설치할 수 있습니다. 예를 들어, Ruby의 빌드 명령어는 `bundle install`이며, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)에서는 `lein deps`입니다. -Twelve-Factor App은 어떠한 시스템 도구에도 암시적으로 의존하지 않습니다. 예를 들어, ImageMagick이나 `curl`을 사용하는 경우가 있습니다. 이러한 툴들은 대부분의 시스템에 존재하지만, 모든 시스템에 존재하는 것이 보장되는 것은 아닙니다. 미래의 시스템에서는 존재하지 않을 수 있으며, 호환되는 버전이 있으라는 보장도 없습니다. 애플리케이션에게 시스템 도구가 필요하다면, 그 도구를 애플리케이션과 통합해야 합니다. \ No newline at end of file +Twelve-Factor App은 어떠한 시스템 도구에도 암시적으로 의존하지 않습니다. 예를 들어, ImageMagick이나 `curl`을 사용하는 경우가 있습니다. 이러한 툴들은 대부분의 시스템에 존재하지만, 모든 시스템에 존재하는 것이 보장되는 것은 아닙니다. 미래의 시스템에서는 존재하지 않을 수 있으며, 호환되는 버전이 있으라는 보장도 없습니다. 애플리케이션에게 시스템 도구가 필요하다면, 그 도구를 애플리케이션과 통합해야 합니다. diff --git a/content/pl/dependencies.md b/content/pl/dependencies.md index a0cebd86e..e766d1bb7 100644 --- a/content/pl/dependencies.md +++ b/content/pl/dependencies.md @@ -5,7 +5,7 @@ Większość języków programowania oferuje narzędzia do dystrybucji dodatkowy **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. [Gem Bundler](http://gembundler.com/) 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ę zalenoż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. +Np. [Gem 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ę zalenoż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`. diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 21ddbdb16..98df7efdc 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -5,7 +5,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. -Por exemplo, [Gem Bundler](http://gembundler.com/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. +Por exemplo, [Gem Bundler](https://bundler.io/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. diff --git a/content/ru/dependencies.md b/content/ru/dependencies.md index 0421cf1ec..98935e21a 100644 --- a/content/ru/dependencies.md +++ b/content/ru/dependencies.md @@ -5,7 +5,7 @@ **Приложение двенадцати факторов никогда не зависит от неявно существующих, доступных всей системе пакетов.** Приложение объявляет все свои зависимости полностью и точно с помощью манифеста *декларации зависимостей*. Кроме того, оно использует инструмент *изоляции зависимостей* во время выполнения для обеспечения того, что неявные зависимости не "просочились" из окружающей системы. Полная и явная спецификация зависимостей применяется равным образом как при разработке, так и при работе приложения. -Например, [Gem Bundler](http://gembundler.com/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` -- для изоляции зависимостей. Python имеет два различных инструмента для этих задач: [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) -- для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей, и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. +Например, [Gem Bundler](https://bundler.io/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` -- для изоляции зависимостей. Python имеет два различных инструмента для этих задач: [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) -- для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей, и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличие среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например, для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. diff --git a/content/zh_cn/dependencies.md b/content/zh_cn/dependencies.md index 38040ce1b..2caa98103 100644 --- a/content/zh_cn/dependencies.md +++ b/content/zh_cn/dependencies.md @@ -5,7 +5,7 @@ **12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它一定通过 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 -例如, Ruby 的 [Gem Bundler](http://gembundler.com/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。 +例如, Ruby 的 [Gem Bundler](https://bundler.io/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。 显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler 下使用 `bundle install`,而 Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是 `lein deps`。 From 2a94ba004d69e62fa98554998fa01c2c9625cad3 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Thu, 27 Oct 2016 09:12:43 +0100 Subject: [PATCH 316/472] remove 'gem' from 'gem bundler' --- content/de/dependencies.md | 2 +- content/es/dependencies.md | 2 +- content/fr/dependencies.md | 2 +- content/it/dependencies.md | 2 +- content/ja/dependencies.md | 2 +- content/ko/dependencies.md | 2 +- content/pl/dependencies.md | 2 +- content/pt_br/dependencies.md | 2 +- content/ru/dependencies.md | 2 +- content/zh_cn/dependencies.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/content/de/dependencies.md b/content/de/dependencies.md index 7d0057f1a..2612b9d0c 100644 --- a/content/de/dependencies.md +++ b/content/de/dependencies.md @@ -5,7 +5,7 @@ Die meisten Programmiersprachen bieten ein System an um unterstützende Biblioth **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 [Gem 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. +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`. diff --git a/content/es/dependencies.md b/content/es/dependencies.md index 092a616f0..43bc11ca5 100644 --- a/content/es/dependencies.md +++ b/content/es/dependencies.md @@ -5,7 +5,7 @@ La mayoría de los lenguajes de programación tienen un sistema de gestión de p **Una aplicación "twelve-factor" no depende nunca de la existencia explícita de paquetes instalados en el sistema.** Declara todas sus dependencias, completamente y explícitamente, mediante un manifiesto de *declaración de dependencias*. Además, usa herramientas de *aislamiento de dependencias* durante la ejecución para asegurar que las dependencias, implícitamente, no afectan al resto del sistema. La especificación de dependencias completa y explícita se aplica de la misma manera tanto en producción como en desarrollo. -Por ejemplo, la [gema Bundler](https://bundler.io/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa qué conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". +Por ejemplo, la [Bundler](https://bundler.io/) de Ruby tiene el formato de su manifiesto `Gemfile` para declarar sus dependencias y `bundle exec` para aislar sus dependencias. En Python existen dos herramientas independientes para estas tareas -- [Pip](http://www.pip-installer.org/en/latest/) se usa para la declaración de dependencias y [Virtualenv](http://www.virtualenv.org/en/latest/) para el aislamiento. Incluso C tiene [Autoconf](http://www.gnu.org/s/autoconf/) para la declaración de sus dependencias, y el enlace estático proporciona aislamiento de sus dependencias. No importa qué conjunto de herramientas se use, la declaración y el aislamiento de dependencias se deben usar siempre juntas, usar solo una o la otra no es suficiente para satisfacer las condiciones de "twelve-factor". Uno de los beneficios de la declaración explícita de dependencias es que simplifica la configuración para los nuevos desarrolladores de la aplicación. Cualquier desarrollador que se incorpore al equipo debe poder probar el código base de la aplicación en su máquina de desarrollo. Tan solo debe tener instalados el entorno de ejecución del lenguaje y el gestor de dependencias como prerequisitos. Lo cual permitirá configurar todo lo necesario para ejecutar el código de la aplicación con un *mandato para construir*. Por ejemplo, el mandato para construir en Ruby/Bundler es `bundle install`, mientras que en Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) es `lein deps`. diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index def9fbcb2..b4e6f285f 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -5,7 +5,7 @@ La plupart des langages de programmation offrent des systèmes pour créer des p **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épendances 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, [Gem 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 chaine 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. +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 chaine 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 oeil à 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`. diff --git a/content/it/dependencies.md b/content/it/dependencies.md index 8e507ee49..8a002c163 100644 --- a/content/it/dependencies.md +++ b/content/it/dependencies.md @@ -5,7 +5,7 @@ Molti linguaggi di programmazione offrono dei sistemi di packaging per la distri **Un'applicazione che aderisce alla twelve-factor non si basa mai sull'esistenza implicita di librerie system-wide**. Le dipendenze vengono tutte dichiarate, tramite un manifest dedicato. Inoltre, viene contemplato anche l'uso di un tool di *isolamento delle dipendenze* durante l'esecuzione, in modo tale da assicurarsi che non ci siano delle "dipendenze implicite" che creino interferenze nel sistema in cui ci si trova. La specifica completa ed esplicita delle dipendenze si applica in modo uniforme: sia in production che in sviluppo. -Ad esempio, [Gem Bundler](https://bundler.io/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. +Ad esempio, [Bundler](https://bundler.io/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. Un altro importante beneficio di una dichiarazione esplicita delle dipendenze sta nel fatto che semplifica di molto la configurazione iniziale per gli sviluppatori appena entrati a lavorare al progetto. Il nuovo arrivato non dovrà fare altro che effettuare un check out della codebase nella propria macchina di sviluppo, occupandosi di dover installare solo ed esclusivamente le dipendenze, appunto, dichiarate. Molto spesso è inoltre presente un *build command* che permette di automatizzare il processo. Per Ruby/Bundler si usa `bundle install`, mentre per Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'è `lein deps`. diff --git a/content/ja/dependencies.md b/content/ja/dependencies.md index 562b8a89f..724105d0a 100644 --- a/content/ja/dependencies.md +++ b/content/ja/dependencies.md @@ -5,7 +5,7 @@ **Twelve-Factor Appは、システム全体にインストールされるパッケージが暗黙的に存在することに決して依存しない。** すべての依存関係を *依存関係宣言* マニフェストで完全かつ厳密に宣言する。さらに、実行時には *依存関係分離* ツールを使って、取り囲んでいるシステムから暗黙の依存関係が“漏れ出ない”ことを保証する。完全かつ明示的な依存関係の指定は、本番環境と開発環境の両方に対して同様に適用される。 -例えば、Rubyで使われる[Gem Bundler](https://bundler.io/) は、依存関係宣言のためのマニフェストのフォーマットである`Gemfile`と依存関係分離のための`bundle exec`を提供している。Pythonではこれらのステップで2つの別々のツールが使われる -- [Pip](http://www.pip-installer.org/en/latest/)が宣言のために使われ、[Virtualenv](http://www.virtualenv.org/en/latest/)が分離のために使われる。C言語でも[Autoconf](http://www.gnu.org/s/autoconf/)で依存関係を宣言し、静的リンクで依存関係を分離することができる。ツールが何であれ、依存関係の宣言と分離は常に一緒に使わなければならない -- どちらか片方だけではTwelve-Factorを満足するのに不十分である。 +例えば、Rubyで使われる[Bundler](https://bundler.io/) は、依存関係宣言のためのマニフェストのフォーマットである`Gemfile`と依存関係分離のための`bundle exec`を提供している。Pythonではこれらのステップで2つの別々のツールが使われる -- [Pip](http://www.pip-installer.org/en/latest/)が宣言のために使われ、[Virtualenv](http://www.virtualenv.org/en/latest/)が分離のために使われる。C言語でも[Autoconf](http://www.gnu.org/s/autoconf/)で依存関係を宣言し、静的リンクで依存関係を分離することができる。ツールが何であれ、依存関係の宣言と分離は常に一緒に使わなければならない -- どちらか片方だけではTwelve-Factorを満足するのに不十分である。 明示的に依存関係を宣言する利点の1つは、アプリケーションに新しい開発者が加わった際のセットアップを単純化できることである。新しい開発者は、言語のランタイムと依存関係管理ツールさえインストールされていれば、アプリケーションのコードベースを自分の開発マシンにチェックアウトすることができる。開発者は決められた *ビルドコマンド* で、アプリケーションのコードを実行するために必要なすべてのものをセットアップできる。例えば、Ruby/Bundlerのビルドコマンドは`bundle install`であり、Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)では`lein deps`である。 diff --git a/content/ko/dependencies.md b/content/ko/dependencies.md index 51ce42d6f..943c0731f 100644 --- a/content/ko/dependencies.md +++ b/content/ko/dependencies.md @@ -5,7 +5,7 @@ **Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. -예를 들어, 루비에서 사용되는 [Gem Bundler](https://bundler.io/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. +예를 들어, 루비에서 사용되는 [Bundler](https://bundler.io/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. 명시적인 종속성 선언의 장점 중 하나는 애플리케이션 개발에 새로 참가하게 된 개발자가 설치를 간단하게 할 수 있다는 점입니다. 새로 참가한 개발자는 애플리케이션의 코드베이스를 개발 머신에 체크아웃 하고, 언어의 런타임과 종속성 매니저만 미리 설치하면 됩니다. 개발자는 정해져있는 *빌드 명령어*만 입력하면 응용 프로그램의 코드를 실행하는 데 필요한 모든 것을 설치할 수 있습니다. 예를 들어, Ruby의 빌드 명령어는 `bundle install`이며, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)에서는 `lein deps`입니다. diff --git a/content/pl/dependencies.md b/content/pl/dependencies.md index e766d1bb7..4b0dd0cd4 100644 --- a/content/pl/dependencies.md +++ b/content/pl/dependencies.md @@ -5,7 +5,7 @@ Większość języków programowania oferuje narzędzia do dystrybucji dodatkowy **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. [Gem 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ę zalenoż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. +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ę zalenoż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`. diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 98df7efdc..776089651 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -5,7 +5,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. -Por exemplo, [Gem Bundler](https://bundler.io/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. +Por exemplo, [Bundler](https://bundler.io/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. diff --git a/content/ru/dependencies.md b/content/ru/dependencies.md index 98935e21a..a3149840d 100644 --- a/content/ru/dependencies.md +++ b/content/ru/dependencies.md @@ -5,7 +5,7 @@ **Приложение двенадцати факторов никогда не зависит от неявно существующих, доступных всей системе пакетов.** Приложение объявляет все свои зависимости полностью и точно с помощью манифеста *декларации зависимостей*. Кроме того, оно использует инструмент *изоляции зависимостей* во время выполнения для обеспечения того, что неявные зависимости не "просочились" из окружающей системы. Полная и явная спецификация зависимостей применяется равным образом как при разработке, так и при работе приложения. -Например, [Gem Bundler](https://bundler.io/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` -- для изоляции зависимостей. Python имеет два различных инструмента для этих задач: [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) -- для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей, и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. +Например, [Bundler](https://bundler.io/) в Ruby использует `Gemfile` как формат манифеста для объявления зависимостей и `bundle exec` -- для изоляции зависимостей. Python имеет два различных инструмента для этих задач: [Pip](http://www.pip-installer.org/en/latest/) используется для объявления и [Virtualenv](http://www.virtualenv.org/en/latest/) -- для изоляции. Даже C имеет [Autoconf](http://www.gnu.org/s/autoconf/) для объявления зависимостей, и статическое связывание может обеспечить изоляцию зависимостей. Независимо от того, какой набор инструментов используется, объявление и изоляция зависимостей должны всегда использоваться совместно -- только одного из них недостаточно, чтобы удовлетворить двенадцати факторам. Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличие среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например, для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. diff --git a/content/zh_cn/dependencies.md b/content/zh_cn/dependencies.md index 2caa98103..ce9a3eb4b 100644 --- a/content/zh_cn/dependencies.md +++ b/content/zh_cn/dependencies.md @@ -5,7 +5,7 @@ **12-Factor规则下的应用程序不会隐式依赖系统级的类库。** 它一定通过 *依赖清单* ,确切地声明所有依赖项。此外,在运行过程中通过 *依赖隔离* 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 -例如, Ruby 的 [Gem Bundler](https://bundler.io/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。 +例如, Ruby 的 [Bundler](https://bundler.io/) 使用 `Gemfile` 作为依赖项声明清单,使用 `bundle exec` 来进行依赖隔离。Python 中则可分别使用两种工具 -- [Pip](http://www.pip-installer.org/en/latest/) 用作依赖声明, [Virtualenv](http://www.virtualenv.org/en/latest/) 用作依赖隔离。甚至 C 语言也有类似工具, [Autoconf](http://www.gnu.org/s/autoconf/) 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。 显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个 *构建命令* 来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler 下使用 `bundle install`,而 Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) 则是 `lein deps`。 From 61b633c4c1ac18f19e84f9f76070752193bbd558 Mon Sep 17 00:00:00 2001 From: Carsten Lamm Date: Sat, 10 Dec 2016 21:25:45 +0100 Subject: [PATCH 317/472] improve german translation --- content/de/admin-processes.md | 10 +++++----- content/de/backing-services.md | 6 +++--- content/de/build-release-run.md | 8 +++----- content/de/codebase.md | 3 +-- content/de/concurrency.md | 10 +++++----- content/de/config.md | 10 +++++----- content/de/dependencies.md | 4 ++-- content/de/dev-prod-parity.md | 4 ++-- content/de/disposability.md | 8 ++++---- content/de/logs.md | 10 +++++----- content/de/port-binding.md | 6 +++--- content/de/processes.md | 6 +++--- 12 files changed, 41 insertions(+), 44 deletions(-) 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/). From 7010042348001a0eae1811deb81d2b2b0191aa14 Mon Sep 17 00:00:00 2001 From: Guilherme Viebig Date: Fri, 16 Dec 2016 19:47:51 -0200 Subject: [PATCH 318/472] Brazilian portuguese enhancements Translation was relatively poor --- content/pt_br/admin-processes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index cd162ec36..738ac5153 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Processos de administração -### Rode tarefas de administração/gestão como processos pontuais +## XII. Processos administrativos +### Rode tarefas de administração/gestão em processos pontuais -O [processo de formação](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app como ela é executada (tais como manipulação de requisições web). Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: +A [formação de processos](./concurrency) é o conjunto de processos que são usados para fazer as negociações regulares da app como ela é executada (tais como manipulação de requisições web). Separadamente, os desenvolvedores, muitas vezes desejam fazer tarefas pontuais de administração ou manutenção para a app, tais como: * Executar migrações de base de dados (ex: `manage.py migrate` no Django, `rake db:migrate` no Rails). * Executar um console (também conhecido como um [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) para rodar código arbitrário ou inspecionar os modelos da app ao vivo no banco de dados. A maioria das linguagens fornece um REPL para rodar o interpretador sem nenhum argumento (ex: `python` or `perl`) ou em alguns casos tem um comando separado (ex: `irb` para Ruby, `rails console` para Rails). * Executar uma vez os scripts comitados no repositório da app (ex: `php scripts/fix_bad_records.php`). -Processos de administração pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado com essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. +Processos administrativos pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado com essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. -Doze-fatores favorece fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, os desenvolvedores invocam processos de administração pontuais por um comando shell direto dentro do diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. +Doze-fatores favorecem fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, desenvolvedores invocam processos administrativos pontuais por um comando shell direto no diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From 27de743b9624ee838d094e5029773b4f168ed899 Mon Sep 17 00:00:00 2001 From: Matheus Silva Date: Sun, 25 Dec 2016 09:22:09 -0200 Subject: [PATCH 319/472] corrects accentuation --- content/pt_br/processes.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index bdedceb0b..217f644b5 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -11,5 +11,4 @@ O espaço de memória ou sistema de arquivos do processo pode ser usado como um Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação doze-fatores prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), do que em tempo de execução. -Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuaŕio na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). - +Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuário na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). From 2abdb211984c6ce6c845602f38b8705cdee2b0fa Mon Sep 17 00:00:00 2001 From: Matheus Silva Date: Sun, 25 Dec 2016 09:23:55 -0200 Subject: [PATCH 320/472] links to the translated version --- content/pt_br/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index 31dfd703b..a6abb1bce 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -1,9 +1,9 @@ ## III. Configurações ### Armazene as configurações no ambiente -A *configuração* de uma aplicação é tudo o que é provável variar entre [deploys](/codebase) (homologação, produção, ambientes de desenvolvimento, etc). Isto inclui: +A *configuração* de uma aplicação é tudo o que é provável variar entre [deploys](./codebase) (homologação, produção, ambientes de desenvolvimento, etc). Isto inclui: -* Recursos para a base de dados, Memcached, e outros [serviços de apoio](/backing-services) +* Recursos para a base de dados, Memcached, e outros [serviços de apoio](./backing-services) * Credenciais para serviços externos como Amazon S3 ou Twitter * Valores por deploy como o nome canônico do host para o deploy From a186cb101aa3b2db4b64487bfa719a35768797d8 Mon Sep 17 00:00:00 2001 From: Matheus Silva Date: Sun, 25 Dec 2016 11:13:27 -0200 Subject: [PATCH 321/472] breaks a line on dependencies --- content/pt_br/dependencies.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/pt_br/dependencies.md b/content/pt_br/dependencies.md index 776089651..5eb220463 100644 --- a/content/pt_br/dependencies.md +++ b/content/pt_br/dependencies.md @@ -6,6 +6,7 @@ A maioria das linguagens de programação oferecem um sistema de pacotes para a **Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema.** Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de *declaração de dependência*. Além disso, ela usa uma ferramenta de *isolamento de dependência* durante a execução para garantir que não há dependências implícitas "vazamento" a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento. Por exemplo, [Bundler](https://bundler.io/) para Ruby oferece o formato de manifesto `Gemfile` para declaração de dependência e `bundle exec` para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas -- [Pip](http://www.pip-installer.org/en/latest/) é utilizado para declaração e [Virtualenv](http://www.virtualenv.org/en/latest/) para isolamento. Mesmo C tem [Autoconf](http://www.gnu.org/s/autoconf/) para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos -- apenas um ou o outro não é suficiente para satisfazer doze-fatores. + Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico *comando de build*. Por exemplo, o comando de build para Ruby/Bundler é `bundle install`, enquanto que para Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) é `lein deps`. Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou `curl`. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação. From acc0441ed1599e4ceea6923cea816e192d986364 Mon Sep 17 00:00:00 2001 From: Anthony Pena Date: Wed, 4 Jan 2017 13:28:23 +0100 Subject: [PATCH 322/472] Update build-release-run.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "est accessible en écriture uniquement" is not a good translate for "are an append-only ledger". "append" imply the idea of write but only for add. "est accessible en écriture incrémentale uniquement" is more appropriate to include the idea of "add only". --- content/fr/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index 587678acb..0dc1f5376 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -13,7 +13,7 @@ Une [base de code](./codebase) est transformée en un déploiement (non-dévelop Les outils de déploiement offrent généralement des outils de gestion de release, permettant notamment de revenir à une release antérieure. Par exemple, l'outil de déploiement [Capistrano](https://github.com/capistrano/capistrano/wiki) stocke les releases dans un sous-répertoire appelé `releases`, où la release courante est un lien symbolique vers le répertoire de release courante. Sa commande `rollback` permet de facilement revenir à une release précédente. -Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). Les liste des releases est accessible en écriture uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. +Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). Les liste des releases est accessible en écriture incrémentale uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. Les assemblages sont initiées par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entrainer des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolues par le développeur qui réalise le déploiement. From 3aed9f77cdd9d8648892bbf03489c36126d4b332 Mon Sep 17 00:00:00 2001 From: Oleksandr Sergiienko Date: Mon, 13 Feb 2017 04:07:30 +0200 Subject: [PATCH 323/472] Added complete Ukrainian (uk) translation --- content/uk/admin-processes.md | 14 ++++++ content/uk/background.md | 8 ++++ content/uk/backing-services.md | 14 ++++++ content/uk/build-release-run.md | 18 ++++++++ content/uk/codebase.md | 17 ++++++++ content/uk/concurrency.md | 14 ++++++ content/uk/config.md | 22 ++++++++++ content/uk/dependencies.md | 12 ++++++ content/uk/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/uk/disposability.md | 12 ++++++ content/uk/intro.md | 12 ++++++ content/uk/logs.md | 16 +++++++ content/uk/port-binding.md | 14 ++++++ content/uk/processes.md | 14 ++++++ content/uk/toc.md | 38 +++++++++++++++++ content/uk/who.md | 4 ++ locales/uk.yml | 7 +++ 17 files changed, 312 insertions(+) create mode 100644 content/uk/admin-processes.md create mode 100644 content/uk/background.md create mode 100644 content/uk/backing-services.md create mode 100644 content/uk/build-release-run.md create mode 100644 content/uk/codebase.md create mode 100644 content/uk/concurrency.md create mode 100644 content/uk/config.md create mode 100644 content/uk/dependencies.md create mode 100644 content/uk/dev-prod-parity.md create mode 100644 content/uk/disposability.md create mode 100644 content/uk/intro.md create mode 100644 content/uk/logs.md create mode 100644 content/uk/port-binding.md create mode 100644 content/uk/processes.md create mode 100644 content/uk/toc.md create mode 100644 content/uk/who.md create mode 100644 locales/uk.yml diff --git a/content/uk/admin-processes.md b/content/uk/admin-processes.md new file mode 100644 index 000000000..19b876297 --- /dev/null +++ b/content/uk/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Задачі адміністрування +### Виконуйте задачі адміністрування/керування за допомогою разових процесів + +[Формація процесів](./concurrency) є певним набором процесів, які необхідні для виконання регулярних задач застосунку (наприклад, обробка веб-запитів). Разом з тим, розробникам часто необхідно виконувати разові адміністративні задачі для обслуговування застосунку, такі як: + +* Запуск міграції бази даних (наприклад, `manage.py migrate` в Django, `rake db:migrate` в Rails). +* Запуск консолі ([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) для виконання довільного коду або перевірки моделі застосунку на діючій базі даних. Більшість мов надають REPL шляхом запуску інтерпретатора без будь-яких аргументів (наприклад, `python` або `perl`) або в деяких випадках мають окрему команду (наприклад, `irb` для Ruby, `rails console` для Rails). +* Запуск разових скриптів, збережених в репозиторії застосунку (наприклад, `php scripts/fix_bad_records.php`). + +Разові процеси адміністрування слід запускати в такому ж середовищі, в якому запущені регулярні [тривалі процеси](./processes) застосунку. Вони запускаються на базі [релізу](./build-release-run), використовуючи ту ж [кодову базу](./codebase) і [конфігурацію](./config), як і будь-який інший процес на базі цього релізу. Для уникнення проблем з синхронізацією код адміністрування має поставлятися з кодом застосунку. + +Для всіх типів процесів мають використовуватися однакові методи [ізоляції залежностей](./dependencies). Наприклад, якщо веб-процес Ruby використовує команду `bundle exec thin start`, то для міграції бази даних слід використовувати `bundle exec rake db:migrate`. Аналогічно, для програми на Python з Virtualenv слід використовувати `bin/python` як для запуску веб-сервера Tornado, так і для запуску будь-яких `manage.py` процесів адміністрування. + +Методологія дванадцяти факторів надає перевагу мовам, які мають REPL "з коробки", і які дозволяють легко запускати разові скрипти. У локальному development середовищі розробник може запустити процес адміністрування за допомогою консольної команди всередині директорії застосунку. У production середовищі для запуску такого процесу розробники можуть використовувати ssh або інший механізм віддаленого виконання команд, що надається середовищем виконання. \ No newline at end of file diff --git a/content/uk/background.md b/content/uk/background.md new file mode 100644 index 000000000..fb1c16ccf --- /dev/null +++ b/content/uk/background.md @@ -0,0 +1,8 @@ +Передумови +========== + +Люди, що працювали над цим документом, брали безпосередню участь в розробці і розгортанні сотень застосунків, і мимоволі стали свідками розвитку, експлуатації та масштабування сотень тисяч застосунків під час нашої роботи над платформою [Heroku](http://www.heroku.com/). + +В цьому документі узагальнюється весь наш досвід використання і спостереження за найрізноманітнішими SaaS-застосунками "в дикій природі". Документ об'єднує ідеальні практики розробки застосунків, особлива увага приділяється динаміці органічного росту застосунку з плином часу, взаємодії між розробниками, які працюють над кодом застосунку, та [уникненню витрат при ерозії програмного забезпечення](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Наша мета полягає в тому, щоб підвищити обізнаність про деякі системні проблеми, які ми бачили в практиці розробки сучасних застосунків, а також в тому, щоб сформулювати спільні загальні поняття для обговорення цих проблем, і запропонувати набір загальних концептуальних рішень цих проблем з супутньою термінологією. Формат навіяний книгами Мартіна Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](https://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* та *[Refactoring](https://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file diff --git a/content/uk/backing-services.md b/content/uk/backing-services.md new file mode 100644 index 000000000..a650fc84a --- /dev/null +++ b/content/uk/backing-services.md @@ -0,0 +1,14 @@ +## IV. Сторонні служби +### Вважайте сторонні служби (backing services) підключеними ресурсами + +*Стороння служба* — це будь-яка служба, яка доступна застосунку по мережі і необхідна для його нормальної роботи: бази даних (наприклад, [MySQL](http://dev.mysql.com/) або [CouchDB](http://couchdb.apache.org/)), системи черг повідомлень (наприклад, [RabbitMQ](http://www.rabbitmq.com/) або [Beanstalkd](http://kr.github.com/beanstalkd/)), служби SMTP для вихідної пошти (наприклад, [Postfix](http://www.postfix.org/)), системи кешування (наприклад, [Memcached](http://memcached.org/)) тощо. + +Допоміжні служби, такі як бази даних, традиційно управляються тими ж системними адміністраторами, які розгортають застосунок. Окрім локальних служб, застосунок може також використовувати служби, що надаються і керуються третіми сторонами: SMTP-сервіси (наприклад, [Postmark](http://postmarkapp.com/)), сервіси збору метрик (наприклад, [New Relic](http://newrelic.com/) або [Loggly](http://www.loggly.com/)), сховища бінарних даних (наприклад, [Amazon S3](http://aws.amazon.com/s3/)), а також різні сервіси, що надають доступ через API (наприклад, [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), або [Last.fm](http://www.last.fm/api)). + +**Код застосунку дванадцяти факторів не бачить жодних відмінностей між локальними і сторонніми сервісами.** Для застосунку кожен з них є підключеним ресурсом, доступним за URL-адресою або іншими даними, що зберігаються в [конфігурації](./config). [Розгортання](./codebase) застосунку дванадцяти факторів повинно мати можливість, наприклад, замінити локальну базу даних MySQL на будь-яку керовану третьою стороною (наприклад, [Amazon RDS](http://aws.amazon.com/rds/)) без жодних змін в коді застосунку. Крім того, локальний сервер SMTP може бути замінений на сторонній SMTP-сервіс (наприклад, Postmark) без зміни коду. В обох випадках необхідно змінити лише налаштування відповідного ресурсу в конфігурації застосунку. + +Кожна окрема стороння служба є *ресурсом*. Наприклад, база даних MySQL є ресурсом; дві бази даних MySQL (що використовуються для шардінгу на рівні застосунку) кваліфікуються як два різних ресурси. Застосунок дванадцяти факторів сприймає ці бази даних як *підключені ресурси*, що вказує на їхній слабкий зв'язок з розгортанням, в якому вони підключені. + +production-розгортання, в якому підключені чотири сторонні служби + +Ресурси за необхідності можуть бути підключені та відключені до розгортання застосунку. Наприклад, якщо база даних застосунку функціонує некорекно у зв'язку з апаратними проблемами, адміністратор може запустити новий сервер бази даних, відновленої з останньої резервної копії. Поточна база даних може бути відключена, а нова база даних підключена — все це без будь-яких змін коду. \ No newline at end of file diff --git a/content/uk/build-release-run.md b/content/uk/build-release-run.md new file mode 100644 index 000000000..eaaed6b44 --- /dev/null +++ b/content/uk/build-release-run.md @@ -0,0 +1,18 @@ +## V. Збірка, реліз, виконання +### Суворо відокремлюйте етапи збірки та виконання + +[Кодова база](./codebase) перетворюється в розгортання (крім розгортання для розробки) у три етапи: + +* *Етап збірки* — це трансформація, яка перетворює код в репозиторії у пакунок, що може бути запущений, і який називається *збірка*. Використовуючи версію коду за вказаним у процесі розгортання коммітом, етап збірки завантажує [залежності](./dependencies) та компілює бінарні файли і ресурси (assets). +* *Етап релізу* приймає збірку, отриману на етапі збірки, і об'єднує її з поточною [конфігурацією](./config) розгортання. Отриманий *реліз* містить збірку і конфігурацію і готовий до негайного запуску в середовищі виконання. +* *Етап виконання* (також відомий як "runtime") запускає застосунок у середовищі виконання, увімкнувши деякий набір [процесів](./processes) застосунку з певного релізу. + +![Код стає збіркою, яка поєднується з конфігурацією для створення релізу.](/images/release.png) + +**Застосунок дванадцяти факторів дотримується суворого відокремлення етапів збірки, релізу і виконання.** Наприклад, не можна вносити зміни в код під час етапу виконання, оскільки немає способу поширити ці зміни назад на етап збірки. + +Інструменти розгортання, як правило, надають засоби керування релізами, які дають можливість відкату до попередньої версії. Наприклад, інструмент розгортання [Capistrano](https://github.com/capistrano/capistrano/wiki) зберігає релізи в підкаталог з назвою `releases`, де поточний реліз є символічним посиланням на каталог поточного релізу. Команда Capistrano `rollback` дає можливість швидко виконати відкат до попередньої версії. + +Кожен реліз повинен завжди мати унікальний ідентифікатор, наприклад, мітку часу релізу (наприклад, `2011-04-06-20:32:17`) або номер, що зростає (наприклад, `v100`). Релізи можуть тільки додаватися, неможливо змінити реліз після його створення. Будь-які зміни мають створювати новий реліз. + +Збірка ініцюється розробником застосунку щоразу при розгортанні нового коду. Запуск етапу виконання, навпаки, може відбуватися автоматично в таких випадках, як перезавантаження сервера або перезапуск процесу, шо впав, менеджером процесів. Таким чином, етап виконання має бути максимально технічно простим, бо проблеми, які заважають застосунку запуститися, можуть призвести до його зупинки посеред ночі, коли розробників немає на місці. Етап збірки може бути більш складним, бо можливі помилки завжди видимі розробнику, який запустив процес розгортання. \ No newline at end of file diff --git a/content/uk/codebase.md b/content/uk/codebase.md new file mode 100644 index 000000000..75e86bf68 --- /dev/null +++ b/content/uk/codebase.md @@ -0,0 +1,17 @@ +## I. Кодова база +### Одна кодова база, що відслідковується в системі контролю версій та має багато розгортань + +Застосунок дванадцяти факторів завжди відслідковуються в системі контролю версій, такій як [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/) або [Subversion](http://subversion.apache.org/). Копія бази даних відстеження ревізій називається *репозиторій коду (code repository)*, що часто скорочується до *code repo* або просто *repo*. + +*Кодова база* — це один репозиторій (в централізованих системах контролю версій, як Subversion), або декілька репозиторіїв, які мають спільний початковий комміт (в децентралізованих системах контролю версій, як Git). + +![Одна кодова база — багатьо розгортань](/images/codebase-deploys.png) + +Завжди існує однозначна відповідність між кодовою базою і застосунком: + +* За наявності кількох баз коду, це не застосунок, це — розподілена система. Кожен компонент в розподіленій системі є застосунком, і кожен з них може окремо дотримуватися дванадцяти факторів. +* Кілька різних застосунків, що спільно використовують загальну базу коду, є порушенням дванадцяти факторів. Рішенням в даній ситуації є виділення загального коду в бібліотеки, які можуть бути підключені через [менеджер залежностей](./dependencies). + +Існує тільки одна кодова база для кожного застосунку, але може бути багато розгортань одного і того самого застосунку. *Розгортанням (deploy)* є запущений екземпляр застосунку. Це, як правило, production-сайт і один або більше staging-сайтів (проміжних розгортань). Крім того, розробник має копію застосунку, запущеного в його локальному середовищі розробки. Кожну з таких копій також можна кваліфікувати як розгортання (deploy). + +Кодова база має бути єдина для всіх розгортань, хоча в кожному розгортанні можуть бути активні різні її версії. Наприклад, розробник може мати деякі зміни у коді, які ще не додані в staging-розгортання; staging-розгортання може мати деякі зміни, які ще не додані в production-розгортання. Але всі вони використовують одну і ту саму кодову базу, таким чином можна їх ідентифікувати як різні розгортання одного і того ж застосунку. \ No newline at end of file diff --git a/content/uk/concurrency.md b/content/uk/concurrency.md new file mode 100644 index 000000000..8c67be772 --- /dev/null +++ b/content/uk/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Конкурентність +### Масштабуйте застосунок за допомогою процесів + +Будь-яка комп'ютерна програма після запуску представлена одним або декількома процесами. Веб-додатки мають різні форми виконання процесів. Наприклад, PHP-процеси виконуються як дочірні процеси Apache, які запускаються в разі потреби в залежності від навантаження. Java-процеси використовують протилежний підхід: JVM забезпечує один масивний мета-процес, який резервує велику кількість системних ресурсів (процесора і пам'яті) під час його запуску, і керує конкурентністю всередині себе за допомогою потоків виконання (threads). В обох випадках запущені процеси видимі для розробників застосунку мінімально. + +![Масштабування виражається у вигляді запущених процесів, різноманітність навантаження виражається в типах процесів.](/images/process-types.png) + +**В застосунку дванадцяти факторів, процеси є сутностями першого класу.** Процеси в застосунку дванадцяти факторів взяли сильні сторони від [моделі процесів UNIX для запуску сервісів](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Використовуючи цю модель, розробник може спроектувати свій застосунок таким чином, що для обробки різних робочих навантажень необхідно призначити кожному виду робіт свій *тип процесу*. Наприклад, HTTP-запити можуть бути оброблені за допомогою веб-процесу (web process), а тривалі фонові завдання оброблені робочим процесом (worker process). + +Це не виключає можливості використання індивідуального мультиплексування для окремих процесів через потоки виконання віртуальної машини або асинхронні/подієві моделі в таких інструментах, як [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) або [Node.js](http://nodejs.org/). Але індивідуальна віртуальна машина може масшабуватися тільки обмежено (вертикальне масшабування), тому застосунок також повинен мати можливість бути запущеним як декілька процесів на декількох фізичних машинах. + +Модель, побудована на процесах, дійсно показує себе з найкращого боку, коли постає необхідність масштабування. [Відсутність розділених даних і горизонтальне розділення процесів застосунку дванадцяти факторів](./processes) означає, що додавання більшої конкурентності є простою і надійною операцією. Масив типів процесів і кількість процесів кожного типу називається *формацією процесів*. + +Процеси застосунку дванадцяти факторів [ніколи не мають демонізуватися](http://dustin.github.com/2010/02/28/running-processes.html) та записувати PID-файли. Замість цього вони мають покладатися на менеджер процесів операційної системи (наприклад, [Upstart](http://upstart.ubuntu.com/), розподілений менеджер процесів на хмарній платформі, або в процесі розробки на такий інструмент, як [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)) для керування [потоком виведення](./logs), реагування на падіння процесів і обробку ініційованих користувачем перезавантаження чи завершення роботи. \ No newline at end of file diff --git a/content/uk/config.md b/content/uk/config.md new file mode 100644 index 000000000..8205ba784 --- /dev/null +++ b/content/uk/config.md @@ -0,0 +1,22 @@ +## III. Конфігурація +### Зберігайте конфігурацію в середовищі виконання + +*Конфігурація* застосунку — це все, що може змінюватися між [розгортаннями](./codebase) (staging-розгортання, production-розгортання, локальне середовище розробника тощо). Це включає: + +* Параметри підключення до бази даних, Memcached і інших [сторонніх сервісів](./backing-services); +* Реєстраційні дані для підключення до зовнішніх сервісів, таких як Amazon S3 або Twitter; +* Значення, що залежать від середовища розгортання, такі як канонічне ім'я хосту. + +Застосунки іноді зберігають конфігурації як константи в коді. Це є порушенням методології дванадцяти факторів, яка вимагає **обов'язкового відокремлення конфігурації від коду**. Конфігурації застосунку в розгортаннях суттєво відрізняються, код — однаковий. + +Лакмусовим папірцем того, чи правильно розділені конфігурація і код, є можливість в будь-який момент відкрити вихідний код застосунку у вільний доступ, при цьому не оприлюднюючи будь-яких приватних даних. + +Зверніть увагу, що визначення "конфігурації" **не включає** в себе внутрішні налаштування застосунку, такі як `сonfig/routes.rb` в Rails, або [як пов'язані основні модулі](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) в [Spring](http://spring.io/). Ці налаштування не змінюються між розгортаннями, і тому краще місце для них — саме в коді. + +Іншим підходом до конфігурації є використання конфігураційних файлів, що не зберігаються в систему контролю версій, таких як `сonfig/database.yml` в Rails. Це перевага у порівнянні з використанням констант в коді, але все ж таки має суттєві недоліки: є ймовірність помилково зберегти файл конфігурації в репозиторій; існує тенденція коли конфігураційні файли розкидані в різних місцях і в різних форматах, і стає важко передивлятися всі налаштування і керувати ними в одному місці. Крім того, формати цих файлів, як правило, специфічні для конкретної мови програмування чи фреймворку. + +**Застосунок дванадцати факторів зберігає конфігурацію в *змінних оточення*** (часто скорочується до *env vars* або *env*). Значення змінних оточення легко змінити між розгортаннями без зміни коду; на відміну від конфігураційних файлів, менш ймовірно випадково зберегти їх в репозиторій коду; і на відміну від конфігураційних файлів або інших механізмів конфігурації, таких як Java System Properties, вони є стандартом, незалежним від мови програмування чи фреймворку. + +Іншим аспектом керування конфігурацією є групування. Іноді застосунки об'єднують конфігурації в іменовані групи (які часто називаються "оточеннями"), які називаються в залежності від конкретного розгортання, наприклад, `development`, `test` і `production` оточення в Rails. Цей метод погано масштабується: чим більше створюється різних розгортань застосунку, тим більше необхідно нових імен оточень, наприклад, `staging` або `qa`. При подальшому рості проекту розробники можуть додавати свої власні спеціальні оточення, наприклад, `joes-staging`, що призводить до комбінаторного вибуху конфігурації, який робить керування розгортанням застосунку нестабільним. + +У застосунку дванадцяти факторів змінні оточення є незв'язаними між собою засобами керування. Кожна змінна повністю незалежна від інших. Вони ніколи не групуються разом в "оточення", керування ними здійснюється незалежно для кожного розгортання. Ця модель добре масштабується разом з появою більшої кількості розгортань застосунку протягом його експлуатації. \ No newline at end of file diff --git a/content/uk/dependencies.md b/content/uk/dependencies.md new file mode 100644 index 000000000..64dde9f30 --- /dev/null +++ b/content/uk/dependencies.md @@ -0,0 +1,12 @@ +## II. Залежності +### Явно оголошуйте та ізолюйте залежності + +Більшість мов програмування мають системи пакунків для розповсюдження бібліотек, такі як [CPAN](http://www.cpan.org/) для Perl або [Rubygems](http://rubygems.org/) для Ruby. Бібліотеки, встановлені через систему пакунків, можуть бути доступними для всієї системи (так звані "site-packages") або встановлені в каталог застосунку (так звані "vendoring" або "bundling"). + +**Застосунок дванадцяти факторів ніколи не залежить від неявно існуючих, досупних всій системі пакунків.** Застосунок повно і точно вказує всі свої залежності за допомогою маніфесту *оголошення залежностей*. Крім того, він використовує інструмент *ізоляції залежністей* під час виконання, щоб гарантувати, що ніякі неявні залежності не "просочилися" з зовнішньої системи. Повна і явна специфікація залежностей використовується однаково як при розробці, так і в production. + +Наприклад, [Bundler](https://bundler.io/) в Ruby використовує `Gemfile` як формат маніфесту для оголошення залежностей і `bundle exec` для ізоляції залежностей. В Python є два окремі інструменти для цих задач - [Pip](http://www.pip-installer.org/en/latest/) використовується для оголошення і [Virtualenv](http://www.virtualenv.org/en/latest/) для ізоляції. Навіть C має [Autoconf](http://www.gnu.org/s/autoconf/) для оголошення залежностей, а статичне зв'язування може забезпечити ізоляцію залежностей. Який би не використовувався набір інструментів, оголошення і ізоляція залежностей завжди мають використовуватися разом — тільки одне або інше не є достатньою умовою для задоволення дванадцяти факторів. + +Однією з переваг явного оголошення залежностей є те, що це спрощує налаштування застосунку для нових розробників. Новий розробник може скопіювати кодову базу застосунку на свою машину, необхідними вимогами для якої є тільки наявність середовища виконання мови програмування та наявність менеджера залежностей. Все необхідне для запуску коду застосунку може бути налаштоване за допомогою визначеної *команди збірки*. Наприклад, команда збірки для Ruby/Bundler є `bundle install`, а для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) це `lein deps`. + +Застосунок дванадцяти факторів також ніколи не залежить від неявно існуючих будь-яких системних інструментів. Прикладом може бути запуск застосунком таких системних інструментів, як ImageMagick або `curl`. У той час, як ці інструменти можуть бути встановлені на багатьох або навіть більшості систем, немає жодної гарантії, що вони будуть встановлені на всіх системах, де застосунок може запускатися в майбутньому, або версія інструменту, встановлена в системі, буде сумісна з застосунком. Якщо застосунку потрібно запускати певні системні інструменти, то такі інструменти мають бути включені в сам застосунок. \ No newline at end of file diff --git a/content/uk/dev-prod-parity.md b/content/uk/dev-prod-parity.md new file mode 100644 index 000000000..a9a668302 --- /dev/null +++ b/content/uk/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod паритет +### Прагніть максимальної ідентичності development, staging та production середовищ + +Історично склалося, що є суттєві відмінності між development середовищем (розробник вносить живі зміни в [локально розгорнутий](./codebase) застосунок) і production середовищем (до якого мають доступ кінцеві користувачі). Ці відмінності проявляються в трьох областях: + +* **Різниця в часі**: Розробник може працювати над кодом, який потрапить у production через дні, тижні або навіть місяці; +* **Різниця в персоналі**: Розробники пишуть код, Ops-інженери розгортають його; +* **Різниця в інструментах**: Розробники можуть використовувати стек технологій такий, як Nginx, SQLite та OS X, в той час як на production використовується Apache, MySQL та Linux. + +**Застосунок дванадцяти факторів проектується для [безперервного розгортання](http://www.avc.com/a_vc/2011/02/continuous-deployment.html), завдяки мінімізації різниці між production і development середовищами.** Розглянемо три відмінності, описані вище: + +* Зменшити різницю в часі: розробник може написати код і він буде розгорнутий через декілька годин або навіть хвилин; +* Зменшити різницю в персоналі: розробники, які писали код, беруть активну участь в його розгортанні і спостерігають за його поведінкою на production; +* Зменшити різницю в інструментах: тримати development та production середовища максимально ідентичними. + +Резюмуючи сказане вище в таблицю: + + + + + + + + + + + + + + + + + + + + + + +
Традиційний застосунокЗастосунок дванадцати факторів
Час між розгортаннямиТижніГодини
Автор коду/той хто розгортаєРізні людиТі ж люди
Dev/Prod розгортанняРізніМаксимально ідентичні
+ +[Сторонні служби](./backing-services), такі як бази даних, системи черг повідомлень або кеш, є однією з областей, де dev/prod паритет має важливе значення. Багато мов програмування мають бібліотеки, які спрощують доступ до сторонніх служб, в тому числі, *адаптери* для різних видів сервісів. Деякі приклади наведені в таблиці нижче. + + + + + + + + + + + + + + + + + + + + + + + + + + +
ТипМоваБібліотекаАдаптери
База данихRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
Черга повідомленьPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
КешRuby/RailsActiveSupport::CacheПам'ять, файлова система, Memcached
+ +Іноді розробники бачать переваги у використанні "легких" сторонніх служб в їхньому локальному середовищі, в той час як більш серйозні і надійні сторонні служби будуть використовуватися у production. Наприклад, локально використовують SQLite, а на production PostgreSQL; або локально пам'ять процесу для кешування, а на production Memcached. + +**Розробник застосунку дванадцяти факторів уникає використання різних сторонніх служб в development і production середовищах**, навіть якщо адаптери теоретично абстраговані від будь-яких відмінностей у сторонніх службах. Відмінності між сторонніми службами означають, що може виникнути крихітна несумісність, в результаті чого код, який працював і пройшов тестування в development та staging середовищах, після розгортання не працює в production середовищі. Такий тип помилок створює перешкоди, які нівелюють переваги безперервного розгортання. Ціна цих перешкод і подальшого відновлення безперервного розгортання надзвичайно висока, якщо розглядати в сукупності за весь час експлуатації застосунку. + +Встановлення локально "легких" сторонніх сервісів вже не є таким привабливим, як було раніше. Сучасні надійні сторонні сервіси, такі як Memcached, PostgreSQL і RabbitMQ, досить легко встановити і запустити завдяки сучасним менеджерам пакунків, таким як [Homebrew](http://mxcl.github.com/homebrew/) і [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Крім того, декларативні інструменти підготовки середовища, такі як [Chef](http://www.opscode.com/chef/) і [Puppet](http://docs.puppetlabs.com/), у поєднанні з "легким" віртуальним середовищем, таким як [Vagrant](http://vagrantup.com/), дозволяють розробникам запускати локальні середовища, які наближені до production. Ціна встановлення і використання цих систем є низькою у порівнянні з користю dev/prod паритету і безперервного розгортання. + +Адаптери для різних сторонніх сервісів все ж корисні, тому що вони роблять перенесення застосунку для використання з іншими сторонніми сервісами відносно безболісним. Але всі розгортання застосунку (development, staging та production середовища) мають використовувати один і той самий тип і версію кожного зі сторонніх сервісів. \ No newline at end of file diff --git a/content/uk/disposability.md b/content/uk/disposability.md new file mode 100644 index 000000000..8e6fc6d6d --- /dev/null +++ b/content/uk/disposability.md @@ -0,0 +1,12 @@ +## IX. Утилізовуваність +### Підвищуйте надійність за допомогою швидкого запуску і коректного вимкнення + +**[Процеси](./processes) застосунку дванадцати факторів є *утилізовуваними*, тобто вони можуть бути запущені або зупинені в будь-який момент.** Це сприяє гнучкому масштабуванню, швидкому розгортанню [коду](./codebase) або змінам [конфігурації](./config) і надійності production-розгортання. + +Слід намагатися **мінімізувати час запуску процесів**. В ідеалі час між моментом виконання команди запуску процесу і моментом, коли процес готовий приймати запити чи задачі, має тривати лише пару секунд. Короткий час запуску забезпечує більшу гнучкість для [релізу](./build-release-run) і масштабування. Крім того, це підвищує стійкість, оскільки менеджер процесів може легко переміщувати процеси на нові фізичні машини у разі необхідності. + +Процеси мають **коректно завершувати свою роботу, коли вони отримують [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал від диспетчеру процесів. Для веб-процесу коректне завершення роботи досягається завдяки припиненню прослуховування порту, до якого він прив'язаний (що означає відмову від отримання будь-яких нових запитів), завершенню обробки будь-яких поточних запитів та зупинці самого процесу. В цій моделі передбачається, що HTTP-запити короткі (не більше ніж кілька секунд), а у разі довгих запитів (long polling) клієнт має намагатися відновити з'єднання у разі його втрати. + +Для процесу, що виконує фонові задачі (worker), коректне завершення роботи досягається за рахунок повернення поточного завдання назад у чергу задач. Наприклад, в [RabbitMQ](http://www.rabbitmq.com/) робочий процес може надіслати команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) завдання повертається в чергу автоматично щоразу, коли процес втрачає з'єднання. Системи, що використовують блокування, такі як [Delayed Job](https://github.com/collectiveidea/delayed_job#readme), мають бути повідомлені, щоб звільнити блокування задачі. В цій моделі передбачається, що всі задачі є [повторно вхідними](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), що зазвичай досягається шляхом обертання результатів їхньої роботи в транзакції або шляхом використання [ідемпотентних](http://en.wikipedia.org/wiki/Idempotence) операцій. + +Процеси також мають бути **стійкі до раптової зупинки** в разі відмови апаратних засобів, на яких вони запущені. Хоча це менш ймовірна подія, ніж коректне завершення роботи за допомогою сигналу `SIGTERM`, вона все ж таки може статися. Рекомендованим підходом є використання надійних черг завдань, таких як Beanstalkd, які повертають завдання в чергу задач, коли клієнти втрачають з'єднання або від'єднуються по тайм-ауту. У будь-якому випадку, застосунок дванадцяти факторів має проектуватися таким чином, щоб обробляти несподівані та некоректні вимкнення. Прикладом вдалої реалізації [архітектури "тільки аварійного вимкнення" (Crash-only design)](http://lwn.net/Articles/191059/) є [СouchDB](http://docs.couchdb.org/en/latest/intro/overview.html). \ No newline at end of file diff --git a/content/uk/intro.md b/content/uk/intro.md new file mode 100644 index 000000000..736e89c77 --- /dev/null +++ b/content/uk/intro.md @@ -0,0 +1,12 @@ +Вступ +===== + +У наш час програмне забезпечення зазвичай поставляється у вигляді сервісів, що називаються *веб-застосунки* (web-apps) або *software-as-a-service* (SaaS). Застосунок дванадцяти факторів — це методологія для створення SaaS-застосунків, які: + +* Використовують **декларативний** формат для автоматизації встановлення та налаштування, що зводить до мінімуму витрати часу і коштів для нових розробників, що приєднуються до проекту; +* Мають **угоду** з операційною системою, пропонуючи **максимальну переносимість** між середовищами виконання; +* Придатні для **розгортання** на сучасних **хмарних платформах**, що усуває необхідність у серверах та їх системному адмініструванні; +* **Мінімізують різницю** між середовищем розробки і production середовищем, що дозволяє **безперервне розгортання** (continuous deployment) для забезпечення максимальної спритності розробки (agility); +* Можуть **масштабуватися** без значних змін в інструментах, архітектурі і практиці розробки. + +Методологію дванадцяти факторів можна використати для застосунків, що написані будь-якою мовою програмування та використовують будь-яку комбінацію із сторонніх служб (бази даних, черги, кеш-пам'ять тощо). \ No newline at end of file diff --git a/content/uk/logs.md b/content/uk/logs.md new file mode 100644 index 000000000..3ce24c6f2 --- /dev/null +++ b/content/uk/logs.md @@ -0,0 +1,16 @@ +## XI. Журналювання +### Сприймайте журналювання (logs) як потоки подій + +*Журналювання* забезпечує наочне уявлення про поведінку запущеного застосунку. Зазвичай у серверних середовищах журнали записуються у файл на диску ("logfile"), але це лише один з форматів виведення. + +Журнал — це [потік](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) агрегованих, впорядкованих за часом подій, зібраних з потоків виведення всіх запущених процесів і сторонніх сервісів. Журнал в сирому вигляді, як правило, має текстовий формат з однією подією на кожен рядок (хоча трасування винятків можуть займати кілька рядків). Журнали не мають фіксованого початку і кінця, потік безперервний поки працює застосунок. + +**Застосунок дванадцяти факторів ніколи не займається маршрутизацію і зберіганням свого потоку виведення.** Застосунок не повинен записувати журнал у файл або керувати файлами журналів. Замість цього кожен запущений процес записує свій потік подій без буферизації в стандартне виведення `stdout`. В development середовищі розробник має можливість переглядати цей потік в терміналі, щоб спостерігати за поведінкою застосунку. + +В staging та production розгортаннях потік виведення кожного процесу перехоплюється середовищем виконання, збирається разом з усіма іншими потоками виведення застосунку і спрямовується до одного або кількох кінцевих пунктів призначення для перегляду і довгострокового архівування. Ці кінцеві пункти призначення не видимі для застосунку і не налаштовуються ним, вони керуються середовищем виконання. Для цього можуть бути використані маршрутизатори журналів з відкритим вихідним кодом (наприклад, [Logplex](https://github.com/heroku/logplex) та [Fluent](https://github.com/fluent/fluentd)). + +Потік подій застосунку може бути направлений у файл або переглянутий у терміналі в режимі реального часу. Найважливішим є те, що потік може бути направлений у систему індексування і аналізу журналів, таку як [Splunk](http://www.splunk.com/), або систему зберігання даних загального призначення, таку як [Hadoop/Hive](http://hive.apache.org/). Ці системи мають широкі можливості і гнучкість для детального аналізу поведінки застосунку протягом тривалого часу, в тому числі: + +* Виявлення конкретних подій у минулому; +* Побудова графіків трендів (наприклад, кількість запитів за хвилину); +* Активне оповіщення відповідно до визначених користувачем евристичних правил (наприклад, попередження, коли кількість помилок за хвилину перевищує певний поріг). \ No newline at end of file diff --git a/content/uk/port-binding.md b/content/uk/port-binding.md new file mode 100644 index 000000000..99ae00cb7 --- /dev/null +++ b/content/uk/port-binding.md @@ -0,0 +1,14 @@ +## VII. Прив'язка портів +### Експортуйте сервіси за допомогою прив'язки портів (port binding) + +Веб-застосунки іноді запускаються всередині контейнера веб-сервера. Наприклад, PHP-застосунок може бути запущений як модуль всередині [Apache HTTPD](http://httpd.apache.org/) або Java-застосунок може бути запущений всередині [Tomcat](http://tomcat.apache.org/). + +**Застосунок дванадцяти факторів є повністю автономним** і в процесі виконання, щоб створити веб-сервіс, доступний через web, не покладається на ін'єкцію веб-сервера в середовище виконання. Веб-застосунок **експортує HTTP-сервіс шляхом прив'язки до порту** і прослуховує запити, що надходять на цей порт. + +У локальному development середовищі розробник відвідує URL-адресу вигляду `http://localhost:5000/` для доступу до сервісу, що експортується застосунком. При розгортанні рівень маршрутизації обробляє запити до загальнодоступного хосту і перенаправляє їх до порту, до якого прив'язано веб-процес. + +Як правило, це реалізується за допомогою [оголошення залежностей] (./dependencies) шляхом додавання бібліотеки веб-сервера до застосунку, наприклад, [Tornado](http://www.tornadoweb.org/) для Python, [Thin](http://code.macournoyer.com/thin/) для Ruby або [Jetty](http://www.eclipse.org/jetty/) для Java та інших мов на основі JVM. Це відбувається повністю в *просторі користувача*, тобто в коді застосунку. Прив'язка до порту для обробки запитів є "угодою" із середовищем виконання. + +HTTP — не єдиний сервіс, який може бути експортований шляхом прив'язки до порту. Майже будь-який вид серверного програмного забезпечення може бути запущений, прив'язаний до порту і може очікувати вхідні запити. Прикладами є [ejabberd](http://www.ejabberd.im/) (використовує [XMPP](http://xmpp.org/)) і [Redis](http://redis.io/) (використовує [протокол Redis](http://redis.io/topics/protocol)). + +Також зверніть увагу, що підхід прив'язки до портів означає, що застосунок може виступати як [стороння служба](./backing-services) для іншого застосунку, надаючи свою URL-адресу як ресурс в [конфігурації](./config) застосунку-споживача. \ No newline at end of file diff --git a/content/uk/processes.md b/content/uk/processes.md new file mode 100644 index 000000000..be4a0b338 --- /dev/null +++ b/content/uk/processes.md @@ -0,0 +1,14 @@ +## VI. Процеси +### Запускайте застосунок як один або декілька процесів без збереження внутрішньго стану (stateless) + +Застосунок запускається в середовищі виконання у вигляді одного або декількох *процесів*. + +У найпростішому випадку код є окремим скриптом, середовище виконання — ноутбук розробника зі встановленим середовищем виконання мови програмування, а процес запускається за допомогою командного рядка (наприклад, `python my_script.py`). В іншому випадку, це може бути production-розгортання складного застосунку, яке може використовувати багато [типів процесів, кожен з яких запущений у необхідній кількості екземплярів](./concurrency). + +**Процеси застосунку дванадцяти факторів не зберігають внутрішній стан (stateless) і [не розділяють ресурси](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Будь-які дані, що підлягають збереженню, мають зберігатися в [сторонній службі](./backing-services) зі збереженням внутрішнього стану (stateful) (як правило, в базі даних). + +Пам'ять та файлова система процесу можуть бути використані як короткостроковий кеш. Наприклад, завантаження, обробка і збереження великого файлу в базі даних. Застосунок дванадцяти факторів ніколи не припускає, що щось, закешоване в пам'яті або на диску, буде доступне при наступному запиті — за наявності багатьох запущених процесів різних типів є велика ймовірність, що наступний запит буде оброблений іншим процесом. Навіть при роботі тільки одного процесу перезапуск (викликаний розгортанням, змінами конфігурації або переміщенням процесу в інше фізичне місце розташування середовищем виконання), як правило, призведе до знищення всіх локальних (у пам'яті і файловій системі) станів. + +Пакувальники ресурсів (наприклад, [Jammit](http://documentcloud.github.com/jammit/) або [django-compressor](http://django-compressor.readthedocs.org/)) використовують файлову систему як кеш для скомпільованих ресурсів. Застосунок дванадцяти факторів надає перевагу здійсненню такої компіляції під час [етапу збірки](./build-release-run), наприклад, як в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не під час виконання. + +Деякі веб-системи покладаються на ["липкі сесії"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) — тобто кешують дані сесії користувача в пам'яті процесу застосунку і очікують, що наступні запити від того ж самого користувача будуть спрямовані до того ж самого процесу. Липкі сесії є порушенням дванадцяти факторів і їх ніколи не слід використовувати та покладатися на них. Дані сесії користувача є хорошим кандидатом для сховища даних, яке надає функцію обмеження терміну зберігання, наприклад, [Memcached](http://memcached.org/) або [Redis](http://redis.io/). \ No newline at end of file diff --git a/content/uk/toc.md b/content/uk/toc.md new file mode 100644 index 000000000..b9f5cb23e --- /dev/null +++ b/content/uk/toc.md @@ -0,0 +1,38 @@ +Дванадцять факторів +=================== + +## [I. Кодова база](./codebase) +### Одна кодова база, що відслідковується в системі контролю версій та має багато розгортань + +## [II. Залежності](./dependencies) +### Явно оголошуйте та ізолюйте залежності + +## [III. Конфігурація](./config) +### Зберігайте конфігурацію в середовищі виконання + +## [IV. Сторонні служби](./backing-services) +### Вважайте сторонні служби (backing services) підключеними ресурсами + +## [V. Збірка, реліз, виконання](./build-release-run) +### Суворо відокремлюйте етапи збірки та виконання + +## [VI. Процеси](./processes) +### Запускайте застосунок як один або декілька процесів без збереження внутрішньго стану (stateless) + +## [VII. Прив'язка портів](./port-binding) +### Експортуйте сервіси за допомогою прив'язки портів (port binding) + +## [VIII. Конкурентність](./concurrency) +### Масштабуйте застосунок за допомогою процесів + +## [IX. Утилізовуваність](./disposability) +### Підвищуйте надійність за допомогою швидкого запуску і коректного вимкнення + +## [X. Dev/prod паритет](./dev-prod-parity) +### Прагніть максимальної ідентичності development, staging та production середовищ + +## [XI. Журналювання](./logs) +### Сприймайте журналювання (logs) як потоки подій + +## [XII. Задачі адміністрування](./admin-processes) +### Виконуйте задачі адміністрування/керування за допомогою разових процесів \ No newline at end of file diff --git a/content/uk/who.md b/content/uk/who.md new file mode 100644 index 000000000..2041a0c75 --- /dev/null +++ b/content/uk/who.md @@ -0,0 +1,4 @@ +Кому слід читати цей документ? +============================== + +Розробникам, які створюють SaaS-застосунки. Ops-інженерам, які виконують розгортання і керування такими застосунками. \ No newline at end of file diff --git a/locales/uk.yml b/locales/uk.yml new file mode 100644 index 000000000..77a1b9c6b --- /dev/null +++ b/locales/uk.yml @@ -0,0 +1,7 @@ +uk: + # Name of language listed in locales menu + language: "Українська (uk)" + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "(Переклад українською)" From a57cc4d630c7dbb7e01d3d2b431aeff8f5f0a58e Mon Sep 17 00:00:00 2001 From: Oleksandr Sergiienko Date: Mon, 13 Feb 2017 05:20:20 +0200 Subject: [PATCH 324/472] Fix broken links --- content/de/backing-services.md | 2 +- content/de/codebase.md | 2 +- content/de/port-binding.md | 2 +- content/en/backing-services.md | 2 +- content/en/codebase.md | 2 +- content/en/port-binding.md | 2 +- content/es/backing-services.md | 2 +- content/es/codebase.md | 2 +- content/es/port-binding.md | 2 +- content/fr/backing-services.md | 2 +- content/fr/codebase.md | 2 +- content/fr/port-binding.md | 2 +- content/it/backing-services.md | 2 +- content/it/codebase.md | 2 +- content/it/port-binding.md | 2 +- content/ja/backing-services.md | 2 +- content/ja/codebase.md | 2 +- content/ja/port-binding.md | 2 +- content/ko/backing-services.md | 2 +- content/ko/codebase.md | 2 +- content/ko/port-binding.md | 2 +- content/pl/backing-services.md | 2 +- content/pl/codebase.md | 2 +- content/pl/port-binding.md | 2 +- content/pt_br/backing-services.md | 2 +- content/pt_br/codebase.md | 2 +- content/pt_br/port-binding.md | 2 +- content/ru/backing-services.md | 2 +- content/ru/codebase.md | 2 +- content/ru/port-binding.md | 2 +- content/zh_cn/backing-services.md | 2 +- content/zh_cn/codebase.md | 2 +- content/zh_cn/port-binding.md | 2 +- 33 files changed, 33 insertions(+), 33 deletions(-) diff --git a/content/de/backing-services.md b/content/de/backing-services.md index c3f1d0dbf..7a4790207 100644 --- a/content/de/backing-services.md +++ b/content/de/backing-services.md @@ -3,7 +3,7 @@ Ein *unterstützender Dienst* ist jeder Dienst, den die App über das Netzwerk im Rahmen ihrer normalen Arbeit konsumiert. Beispiele sind Datenspeicher (wie [MySQL](http://dev.mysql.com/) oder [CouchDB](http://couchdb.apache.org/)), Messaging/Queueing-Systeme (wie [RabbitMQ](http://www.rabbitmq.com/) oder [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP-Dienste für das Senden von Mail (wie [Postfix](http://www.postfix.org/)), und Cache-Systeme (wie [Memcached](http://memcached.org/)). -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)). +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](https://developers.google.com/maps/), 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. diff --git a/content/de/codebase.md b/content/de/codebase.md index a6a3f7012..88dc49eeb 100644 --- a/content/de/codebase.md +++ b/content/de/codebase.md @@ -1,7 +1,7 @@ ## I. Codebase ### Eine im Versionsmanagementsystem verwaltete Codebase, viele Deployments -Eine Zwölf-Faktor-App wird immer in einem Versionsmanagementsystem verwaltet, wie zum Beispiel [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) oder [Subversion](http://subversion.apache.org/). Eine Kopie der Versionsdatenbank wird *Code Repository* genannt, kurz *Code Repo* oder auch nur *Repo*. +Eine Zwölf-Faktor-App wird immer in einem Versionsmanagementsystem verwaltet, wie zum Beispiel [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/) oder [Subversion](http://subversion.apache.org/). Eine Kopie der Versionsdatenbank wird *Code Repository* genannt, kurz *Code Repo* oder auch nur *Repo*. Eine *Codebase* ist jedes einzelne Repo (in einem zentralisierten Versionsmanagementsystem wie Subversion) oder jede Menge von Repos, die einen ursprünglichen Commit teilen (in dezentralisierten Versionsmanagementsystemen wie git). diff --git a/content/de/port-binding.md b/content/de/port-binding.md index aa9be0f1d..71666fa67 100644 --- a/content/de/port-binding.md +++ b/content/de/port-binding.md @@ -7,7 +7,7 @@ Web-Apps laufen manchmal in einem Webserver als Container. Zum Beispiel laufen P 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. +Ü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://www.eclipse.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. HTTP ist nicht der einzige Dienst, der durch Portbindung exportiert werden kann. Fast jede Server-Software kann betrieben werden, indem ein Prozess an einen Port gebunden wird und auf ankommende Requests wartet. Einige Beispiele sind [ejabberd](http://www.ejabberd.im/) (spricht [XMPP](http://xmpp.org/)) und [Redis](http://redis.io/) (spricht das [Redis-Protokoll](http://redis.io/topics/protocol)). diff --git a/content/en/backing-services.md b/content/en/backing-services.md index 2f8551947..dff7c7dcb 100644 --- a/content/en/backing-services.md +++ b/content/en/backing-services.md @@ -3,7 +3,7 @@ A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). +Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). **The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. diff --git a/content/en/codebase.md b/content/en/codebase.md index 94a62f41e..234ad6725 100644 --- a/content/en/codebase.md +++ b/content/en/codebase.md @@ -1,7 +1,7 @@ ## I. Codebase ### One codebase tracked in revision control, many deploys -A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. +A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). diff --git a/content/en/port-binding.md b/content/en/port-binding.md index 8b3a0407e..b12de8b15 100644 --- a/content/en/port-binding.md +++ b/content/en/port-binding.md @@ -7,7 +7,7 @@ Web apps are sometimes executed inside a webserver container. For example, PHP In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. -This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://www.eclipse.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). diff --git a/content/es/backing-services.md b/content/es/backing-services.md index c707b9ed1..7b14e5b27 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -3,7 +3,7 @@ Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). -Tradicionalmente, los "backing services" (como las bases de datos) han sido gestionadas por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros, como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). +Tradicionalmente, los "backing services" (como las bases de datos) han sido gestionadas por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros, como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). **El código de una aplicación "twelve-factor" no hace distinciones entre servicios locales y de terceros.** Para la aplicación, ambos son recursos conectados, accedidos mediante una URL u otro localizador o credencial almacenado en la [config](./config). Un [despliegue](./codebase) de una aplicación "twelve-factor" debería ser capaz de reemplazar una base de datos local MySQL por una gestionada por un tercero (como [Amazon RDS](http://aws.amazon.com/rds/)) sin ningún cambio en el código de la aplicación. Igualmente, un servidor SMTP local se podría cambiar por un servicio de terceros (como Postmark) sin modificaciones en el código. En ambos casos, solo el manejador del recurso necesita cambiar en la configuración. diff --git a/content/es/codebase.md b/content/es/codebase.md index e0d6ec784..7a34788ed 100644 --- a/content/es/codebase.md +++ b/content/es/codebase.md @@ -1,7 +1,7 @@ ## I. Código base (Codebase) ### Un código base sobre el que hacer el control de versiones y multiples despliegues -Una aplicación "twelve-factor" se gestiona siempre con un sistema de control de versiones, como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). A la copia de la base de datos de seguimiento de versiones se le conoce como un *repositorio de código*, a menudo abreviado como *repo de código* o simplemente *repo*. +Una aplicación "twelve-factor" se gestiona siempre con un sistema de control de versiones, como [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), o [Subversion](http://subversion.apache.org/). A la copia de la base de datos de seguimiento de versiones se le conoce como un *repositorio de código*, a menudo abreviado como *repo de código* o simplemente *repo*. El *código base* es cualquier repositorio (en un sistema de control de versiones centralizado como Subversion), o cualquier conjunto de repositorios que comparten un commit raíz (en un sistema de control de versiones descentralizado como Git). diff --git a/content/es/port-binding.md b/content/es/port-binding.md index ff2b451d4..5f0e22e69 100644 --- a/content/es/port-binding.md +++ b/content/es/port-binding.md @@ -7,7 +7,7 @@ Las aplicaciones web se ejecutan a menudo mediante contenedores web. Por ejemplo En los entornos de desarrollo, los desarrolladores usan una URL del servicio (por ejemplo `http://localhost:5000/`), para acceder al servicio que ofrece la aplicación. En la fase de despliegue, existe una capa de enrutamiento que se encarga de que las peticiones que llegan a una dirección pública se redirijan hacia el proceso web que tiene asignado su puerto correspondiente. -Esto se implementa, normalmente, usando una [declaración de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) para Java y otros lenguajes basados en la Máquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. +Esto se implementa, normalmente, usando una [declaración de dependencias](./dependencies) donde se incluyen librerías de las aplicaciones web, como [Tornado](http://www.tornadoweb.org/) para Python, [Thin](http://code.macournoyer.com/thin/) para Ruby, o [Jetty](http://www.eclipse.org/jetty/) para Java y otros lenguajes basados en la Máquina Virtual de Java (JVM). Esto ocurre totalmente en el *entorno del usuario*, es decir, dentro del código de la aplicación. El contrato con el entorno de ejecución obliga al puerto a servir las peticiones. HTTP no es el único servicio que usa asignación de puertos. La verdad, es que cualquier servicio puede ejecutarse mediante un proceso al que se le asigna un puerto y queda a la espera de peticiones. Entre otros ejemplos podemos encontrar [ejabberd](http://www.ejabberd.im/) (que usa [XMPP](http://xmpp.org/)), y [Redis](http://redis.io/) (que usa [el protocolo Redis](http://redis.io/topics/protocol)). diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md index 37cd5d2fc..36b824cf9 100644 --- a/content/fr/backing-services.md +++ b/content/fr/backing-services.md @@ -3,7 +3,7 @@ Un *service externe* (backing service) correspond à tout service que l'application utilise à travers le réseau pour son fonctionnement nominal. Cela concerne par exemple les bases de données (tel que [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), les systèmes de messages/files (tel que [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), les services SMTP pour l'envoi d'email (comme [Postfix](http://www.postfix.org/)), ainsi que les systèmes de cache (comme [Memcached](http://memcached.org/)). -Les *services externes* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). +Les *services externes* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), ou [Last.fm](http://www.last.fm/api)). **Le code d'une application 12 facteurs ne fait pas de distinction entre les services locaux et les services tiers**. Pour l'application, ce sont tous les deux des ressources attachées, accessibles via une URL ou un autre système de localisation et d'authentification stockée dans la [configuration](./config). Un [déploiement](./codebase) d'une application 12 facteurs doit pouvoir remplacer une base de données MySQL locale par une autre gérée par des tiers ([Amazon RDS](http://aws.amazon.com/rds/), par exemple) sans le moindre changement dans le code de l'application. De la même manière, un serveur SMTP local doit pouvoir être remplacé par un service tiers (Postmark, par exemple) sans changements dans le code. Dans les deux cas, seules les informations de configurations doivent changer. diff --git a/content/fr/codebase.md b/content/fr/codebase.md index 56030f7d5..e50c048c9 100644 --- a/content/fr/codebase.md +++ b/content/fr/codebase.md @@ -1,7 +1,7 @@ ## I. Base de code ### Une base de code suivie avec un système de contrôle de version, plusieurs déploiements -Une application 12 facteurs est toujours suivie dans un système de contrôle de version, tel que [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Une copie de la base de données de suivi des révisions est appelée *dépôt de code*, souvent raccourci en *dépôt*. Le terme anglais *code repository*, raccourci en *repository* et *repo* est également utilisé. +Une application 12 facteurs est toujours suivie dans un système de contrôle de version, tel que [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), ou [Subversion](http://subversion.apache.org/). Une copie de la base de données de suivi des révisions est appelée *dépôt de code*, souvent raccourci en *dépôt*. Le terme anglais *code repository*, raccourci en *repository* et *repo* est également utilisé. Une *base de code* correspond à chaque dépôt (dans un système de contrôle de version centralisé tel que Subversion), ou tout ensemble de dépôts qui partage un commit racine (dans un système de contrôle de version décentralisé comme Git). diff --git a/content/fr/port-binding.md b/content/fr/port-binding.md index 9fb28e089..d480d5542 100644 --- a/content/fr/port-binding.md +++ b/content/fr/port-binding.md @@ -7,7 +7,7 @@ Les applications web sont parfois exécutées à l'intérieur d'un container de 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://jetty.codehaus.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. +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)). diff --git a/content/it/backing-services.md b/content/it/backing-services.md index 0a8ee8109..fbde27ef9 100644 --- a/content/it/backing-services.md +++ b/content/it/backing-services.md @@ -3,7 +3,7 @@ Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](http://kr.github.com/beanstalkd/)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). -Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), ed anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), o [Last.fm](http://www.last.fm/api)). +Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), ed anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). **Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). Ad un qualsiasi [deploy](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale ad uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. diff --git a/content/it/codebase.md b/content/it/codebase.md index e4f2c4bf3..61b63e66b 100644 --- a/content/it/codebase.md +++ b/content/it/codebase.md @@ -1,7 +1,7 @@ ## I. Codebase ### Una sola codebase sotto controllo di versione, tanti deploy -Un'app conforme alla metodologia twelve-factor è sempre sotto un sistema di controllo di versione, sia essa [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), o [Subversion](http://subversion.apache.org/). Una copia della codebase è detta *code repository*, oppure più in breve *code repo* o *repo*. +Un'app conforme alla metodologia twelve-factor è sempre sotto un sistema di controllo di versione, sia essa [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), o [Subversion](http://subversion.apache.org/). Una copia della codebase è detta *code repository*, oppure più in breve *code repo* o *repo*. Una *codebase* è quindi un singolo repository (in un sistema centralizzato come Subversion), oppure un set di repo che condividono una root commit (in un sistema di controllo decentralizzato come Git). diff --git a/content/it/port-binding.md b/content/it/port-binding.md index 536c2c071..c37d9f0a4 100644 --- a/content/it/port-binding.md +++ b/content/it/port-binding.md @@ -7,7 +7,7 @@ Normalmente, le applicazioni web sono qualcosa di eseguito all'interno di un ser In un ambiente di sviluppo locale, lo sviluppatore accede al servizio tramite un URL come `http://localhost:5000/`. In fase di deploy, invece, un layer di routing gestisce le richieste da un hostname pubblico alla specifica porta desiderata. -Tale funzionalità viene, frequentemente, implementata tramite [dichiarazione delle opportune dipendenze](./dependencies), aggiungendo una libreria webserver all'applicazionecome [Tornado](http://www.tornadoweb.org/) per Python, [Thin](http://code.macournoyer.com/thin/) per Ruby, o [Jetty](http://jetty.codehaus.org/jetty/) per Java ed altri linguaggi basati su JVM. L'evento, nella sua interezza, "ha luogo" nello spazio dell'utente, nel codice dell'applicazione. +Tale funzionalità viene, frequentemente, implementata tramite [dichiarazione delle opportune dipendenze](./dependencies), aggiungendo una libreria webserver all'applicazionecome [Tornado](http://www.tornadoweb.org/) per Python, [Thin](http://code.macournoyer.com/thin/) per Ruby, o [Jetty](http://www.eclipse.org/jetty/) per Java ed altri linguaggi basati su JVM. L'evento, nella sua interezza, "ha luogo" nello spazio dell'utente, nel codice dell'applicazione. HTTP non è l'unico servizio che può essere esportato tramite port binding. In realtà quasi ogni tipo di software può essere eseguito tramite uno specifico binding tra processo e porta dedicata. Alcuni esempi includono [ejabberd](http://www.ejabberd.im/) (a tal proposito, leggere su [XMPP](http://xmpp.org/)), e [Redis](http://redis.io/) (a proposito del [protoccolo Redis](http://redis.io/topics/protocol)). diff --git a/content/ja/backing-services.md b/content/ja/backing-services.md index ee195336d..eb5b918bc 100644 --- a/content/ja/backing-services.md +++ b/content/ja/backing-services.md @@ -3,7 +3,7 @@ *バックエンドサービス* はアプリケーションが通常の動作の中でネットワーク越しに利用するすべてのサービスを言う。例としては、データストア(例:[MySQL](http://dev.mysql.com/) や [CouchDB](http://couchdb.apache.org/))、メッセージキューイングシステム(例:[RabbitMQ](http://www.rabbitmq.com/) や [Beanstalkd](http://kr.github.com/beanstalkd/))、電子メールを送信するためのSMTPサービス(例:[Postfix](http://www.postfix.org/))、キャッシュシステム(例:[Memcached](http://memcached.org/))などがある。 -従来、データストアなどのバックエンドサービスは、デプロイされたアプリケーションと同じシステム管理者によって管理されていた。このようなローカルで管理されるサービスに加えて、サードパーティによって提供、管理されるサービスを利用することもある。例としては、SMTP サービス(例:[Postmark](http://postmarkapp.com/))、メトリクス収集システム(例:[New Relic](http://newrelic.com/) や [Loggly](http://www.loggly.com/))、ストレージサービス(例:[Amazon S3](http://aws.amazon.com/s3/))、APIアクセス可能な消費者向けサービス(例:[Twitter](http://dev.twitter.com/)や[Google Maps](http://code.google.com/apis/maps/index.html)、[Last.fm](http://www.last.fm/api))などがある。 +従来、データストアなどのバックエンドサービスは、デプロイされたアプリケーションと同じシステム管理者によって管理されていた。このようなローカルで管理されるサービスに加えて、サードパーティによって提供、管理されるサービスを利用することもある。例としては、SMTP サービス(例:[Postmark](http://postmarkapp.com/))、メトリクス収集システム(例:[New Relic](http://newrelic.com/) や [Loggly](http://www.loggly.com/))、ストレージサービス(例:[Amazon S3](http://aws.amazon.com/s3/))、APIアクセス可能な消費者向けサービス(例:[Twitter](http://dev.twitter.com/)や[Google Maps](https://developers.google.com/maps/)、[Last.fm](http://www.last.fm/api))などがある。 **Twelve-Factor Appのコードは、ローカルサービスとサードパーティサービスを区別しない。** アプリケーションにとっては、どちらもアタッチされたリソースであり、[設定](./config)に格納されたURLやその他のロケーター、認証情報でアクセスする。Twelve-Factor Appの[デプロイ](./codebase)は、アプリケーションのコードに変更を加えることなく、ローカルで管理されるMySQLデータベースをサードパーティに管理されるサービス([Amazon RDS](http://aws.amazon.com/rds/)など)に切り替えることができるべきである。同様に、ローカルのSMTPサーバーも、コードを変更することなくサードパーティのSMTPサービス(Postmarkなど)に切り替えることができるべきである。どちらの場合も、変更が必要なのは設定の中のリソースハンドルのみである。 diff --git a/content/ja/codebase.md b/content/ja/codebase.md index 5bc86cb93..75fc9d961 100644 --- a/content/ja/codebase.md +++ b/content/ja/codebase.md @@ -1,7 +1,7 @@ ## I. コードベース ### バージョン管理されている1つのコードベースと複数のデプロイ -Twelve-Factor Appは[Git](http://git-scm.com/)や[Mercurial](http://mercurial.selenic.com/)、[Subversion](http://subversion.apache.org/)などのバージョン管理システムで常に変更を追跡している。リビジョン追跡データベースのコピーは *コードリポジトリ* と言われ、単に *リポジトリ* とも言われる。 +Twelve-Factor Appは[Git](http://git-scm.com/)や[Mercurial](https://www.mercurial-scm.org/)、[Subversion](http://subversion.apache.org/)などのバージョン管理システムで常に変更を追跡している。リビジョン追跡データベースのコピーは *コードリポジトリ* と言われ、単に *リポジトリ* とも言われる。 *コードベース* は、単一のリポジトリ(Subversionのような集中バージョン管理システムの場合)またはルートコミットを共有する複数のリポジトリ(Gitのような分散バージョン管理システムの場合)である。 diff --git a/content/ja/port-binding.md b/content/ja/port-binding.md index 7e2116376..18b20ae40 100644 --- a/content/ja/port-binding.md +++ b/content/ja/port-binding.md @@ -7,7 +7,7 @@ WebアプリケーションはWebサーバーコンテナの内部で実行さ ローカルの開発環境では、開発者はアプリケーションによって公開されたサービスにアクセスするために、`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://jetty.codehaus.org/jetty/)などがある。これは *ユーザー空間* すなわちアプリケーションのコード内で完結する。リクエストを処理するための実行環境との契約は、ポートをバインドすることである。 +これは一般に、[依存関係宣言](./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)を話す)などがある。 diff --git a/content/ko/backing-services.md b/content/ko/backing-services.md index cec356f47..bb805b556 100644 --- a/content/ko/backing-services.md +++ b/content/ko/backing-services.md @@ -3,7 +3,7 @@ *백엔드 서비스*는 애플리케이션 정상 동작 중 네트워크를 통해 이용하는 모든 서비스입니다. 예를 들어, 데이터 저장소(예: [MySQL](http://dev.mysql.com/), [CouchDB](http://couchdb.apache.org/)), 메시지 큐잉 시스템(예: [RabbitMQ](http://www.rabbitmq.com/), [Beanstalkd](http://kr.github.com/beanstalkd/)), 메일을 보내기 위한 SMTP 서비스 (예: [Postfix](http://www.postfix.org/)), 캐시 시스템(예: [Memcached](http://memcached.org/)) 등이 있습니다. -데이터베이스와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))등이 있습니다. +데이터베이스와 같은 백엔드 서비스들은 통상적으로 배포된 애플리케이션과 같은 시스템 관리자에 의해서 관리되고 있었습니다. 애플리케이션은 이런 로컬에서 관리하는 서비스 대신, 서드파티에 의해서 제공되고 관리되는 서비스를 이용할 수 있습니다. 예를 들어, SMTP 서비스 (예: [Postmark](http://postmarkapp.com/)), 지표 수집 서비스 (예: [New Relic](http://newrelic.com/), [Loggly](http://www.loggly.com/)), 스토리지 서비스 (예: [Amazon S3](http://aws.amazon.com/s3/)), API로 접근 가능한 소비자 서비스 (예: [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), [Last.fm](http://www.last.fm/api))등이 있습니다. **Twelve-Factor App의 코드는 로컬 서비스와 서드파티 서비스를 구별하지 않습니다.** 애플리케이션에게는 양 쪽 모두 연결된 리소스이며, [설정](./config)에 있는 URL 혹은 다른 로케이터와 인증 정보를 사용해서 접근 됩니다. Twelve-Factor App의 [배포](./codebase)는 애플리케이션 코드를 수정하지 않고 로컬에서 관리되는 MySQL DB를 서드파티에서 관리되는 DB(예: [Amazon RDS](http://aws.amazon.com/rds/))로 전환할 수 있어야 합니다. 마찬가지로, 로컬 SMTP 서버는 서드파티 SMTP 서비스(예: Postmark)로 코드 수정 없이 전환이 가능해야 합니다. 두 경우 모두 설정에 있는 리소스 핸들만 변경하면 됩니다. diff --git a/content/ko/codebase.md b/content/ko/codebase.md index fc4e4ae17..25942dabf 100644 --- a/content/ko/codebase.md +++ b/content/ko/codebase.md @@ -1,7 +1,7 @@ ## I. 코드베이스 ### 버전 관리되는 하나의 코드베이스와 다양한 배포 -Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/) 같은 버전 컨트롤 시스템을 사용하여 변화를 추적하며, 버전 추적 데이터베이스의 사본을 *코드 저장소*, 줄여서 *저장소*라고 부른다. +Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), [Subversion](http://subversion.apache.org/) 같은 버전 컨트롤 시스템을 사용하여 변화를 추적하며, 버전 추적 데이터베이스의 사본을 *코드 저장소*, 줄여서 *저장소*라고 부른다. *코드베이스*는 단일 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우) 일수도 있고, 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)일수도 있다. diff --git a/content/ko/port-binding.md b/content/ko/port-binding.md index db9c49c6c..f1ae94487 100644 --- a/content/ko/port-binding.md +++ b/content/ko/port-binding.md @@ -7,7 +7,7 @@ 로컬 개발 환경에서는 `http://localhost:5000`과 같은 주소를 통해 개발자가 애플리케이션 서비스에 접근할 수 있습니다. 배포에서는 라우팅 레이어가 외부에 공개된 호스트명으로 들어온 요청을 포트에 바인딩된 웹 프로세스에 전달 합니다. -이는 일반적으로 [종속선 선언](./dependency)에 웹서버 라이브러리를 추가함으로써 구현됩니다. 예를 들어, 파이썬의 [Tornado](http://www.tornadoweb.org/)나 루비의 [Thin](http://code.macournoyer.com/thin/)이나 자바와 JVM 기반 언어들을 위한 [Jetty](http://jetty.codehaus.org/jetty/)가 있습니다. 이것들은 전적으로 *유저 스페이스* 즉, 애플리케이션의 코드 내에서 처리됩니다. 실행 환경과의 규약은 요청을 처리하기 위해 포트를 바인딩하는 것입니다. +이는 일반적으로 [종속선 선언](./dependency)에 웹서버 라이브러리를 추가함으로써 구현됩니다. 예를 들어, 파이썬의 [Tornado](http://www.tornadoweb.org/)나 루비의 [Thin](http://code.macournoyer.com/thin/)이나 자바와 JVM 기반 언어들을 위한 [Jetty](http://www.eclipse.org/jetty/)가 있습니다. 이것들은 전적으로 *유저 스페이스* 즉, 애플리케이션의 코드 내에서 처리됩니다. 실행 환경과의 규약은 요청을 처리하기 위해 포트를 바인딩하는 것입니다. 포트 바인딩에 의해 공개되는 서비스는 HTTP 뿐만이 아닙니다. 거의 모든 종류의 서버 소프트웨어는 포트를 바인딩하고 요청이 들어오길 기다리는 프로세스를 통해 실행될 수 있습니다. 예를 들면, [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/)을 따름)나 [Redis](http://redis.io/) ([Redis protocol](http://redis.io/topics/protocol)을 따름) 등이 있습니다. diff --git a/content/pl/backing-services.md b/content/pl/backing-services.md index fb0b67bb1..12a58637a 100644 --- a/content/pl/backing-services.md +++ b/content/pl/backing-services.md @@ -3,7 +3,7 @@ Usługą wspierającą jest każda, z której aplikacja korzysta przez sieć jako część normalnego działania. Zaliczamy do nich np. magazyny danych (takie jak [MySQL](http://dev.mysql.com/) albo [CouchDB](http://couchdb.apache.org/)), systemy wysyłania/kolejkowania wiadomości (takie jak [RabbitMQ](http://www.rabbitmq.com/) czy [Beanstalkd](http://kr.github.com/beanstalkd/)), usługi SMTP do zewnętrznej wysyłki emaili (np. [Postfix](http://www.postfix.org/)) oraz systemy cachowania pamięci (np. [Memcached](http://memcached.org/)). -Usługa wspierająca taka jak baza danych jest zazwyczaj zarządzana przez tych samych programistów, którzy zajmują się wdrażaniem aplikacji. Dodatkowo aplikacja może również korzystać z usług oferowanych przez osoby trzecie. Do przykładów zaliczają się usługi SMTP ([Postmark](http://postmarkapp.com/)),usługi zbierające metryki ([New Relic](http://newrelic.com/) czy [Loggly](http://www.loggly.com/)), usługi przechowywania danych (takie jak [Amazon S3](http://aws.amazon.com/s3/)), czy również usługi dostępne przez publiczne API (jak np. [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), lub [Last.fm](http://www.last.fm/api)). +Usługa wspierająca taka jak baza danych jest zazwyczaj zarządzana przez tych samych programistów, którzy zajmują się wdrażaniem aplikacji. Dodatkowo aplikacja może również korzystać z usług oferowanych przez osoby trzecie. Do przykładów zaliczają się usługi SMTP ([Postmark](http://postmarkapp.com/)),usługi zbierające metryki ([New Relic](http://newrelic.com/) czy [Loggly](http://www.loggly.com/)), usługi przechowywania danych (takie jak [Amazon S3](http://aws.amazon.com/s3/)), czy również usługi dostępne przez publiczne API (jak np. [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), lub [Last.fm](http://www.last.fm/api)). **Aplikacje 12factor nie rozróżniają usług lokalnych od zewnętrznych.** Dla aplikacji wszystkie są załączonymi zasobami, dostepnymi przez adres URL lub inny standard zdefiniowany w [konfiguracji](./config). Przy [wdrożeniu](./codebase) aplikacji nie może być problemów ze zmianą lokalnej bazy MySQL na oferowaną przez zewnętrznego usługodawcę (np. [Amazon RDS](http://aws.amazon.com/rds/)) bez żadnych zmian w kodzie aplikacji. Podobnie lokalny serwer SMTP może być zamieniony na zewnętrzną usługę SMTP (taką jak Postmark) bez zmian kodu. W obu przypadkach zmiana powinna wystąpić jedynie w konfiguracji aplikacji. diff --git a/content/pl/codebase.md b/content/pl/codebase.md index 8586f044f..aefb378d8 100644 --- a/content/pl/codebase.md +++ b/content/pl/codebase.md @@ -1,7 +1,7 @@ ## I. Codebase ### Jedno źródło kodu śledzone systemem kontroli wersji, wiele wdrożeń -Aplikacja 12factor napisana jest zawsze zarządzania w systemie kontroli wersji takim jak [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), czy [Subversion](http://subversion.apache.org/). Miejsce, w którym trzymany i rewizjonowany jest kod nazywane jest *repozytorium kodu źródłowego*, często skracane do samego *code repo*, albo po prostu *repo*. +Aplikacja 12factor napisana jest zawsze zarządzania w systemie kontroli wersji takim jak [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), czy [Subversion](http://subversion.apache.org/). Miejsce, w którym trzymany i rewizjonowany jest kod nazywane jest *repozytorium kodu źródłowego*, często skracane do samego *code repo*, albo po prostu *repo*. *Codebase* (baza kodu) jest więc niczym innym jak pojedynczym repo (w przypadku zcentralizowanego systemu kontroli wersji jak Subversion), albo zestawem repozytoriów, które współdzielą tzw. root commit. (w przypadku zdecentralizowanego systemu jak Git). diff --git a/content/pl/port-binding.md b/content/pl/port-binding.md index 55c1ddb69..9a5ec8f70 100644 --- a/content/pl/port-binding.md +++ b/content/pl/port-binding.md @@ -7,7 +7,7 @@ Zdarza się, że aplikacje internetowe uruchamiane są w ramach serwera web. Nap 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://jetty.codehaus.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. +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)). diff --git a/content/pt_br/backing-services.md b/content/pt_br/backing-services.md index efb86fce6..6937c2d22 100644 --- a/content/pt_br/backing-services.md +++ b/content/pt_br/backing-services.md @@ -3,7 +3,7 @@ Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados (como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). -Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ou [Last.fm](http://www.last.fm/api)). +Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), ou [Last.fm](http://www.last.fm/api)). **O código para um app doze-fatores não faz distinção entre serviços locais e de terceiros.** Para o app, ambos são recursos anexados, acessíveis via uma URL ou outro localizador/credenciais na [config](./config). Um [deploy](./codebase) do app doze-fatores deve ser capaz de trocar um banco de dados MySQL por um gerenciado por terceiros (tais como [Amazon RDS](http://aws.amazon.com/rds/)) sem realizar quaisquer mudanças no código do app. Da mesma forma, um servidor local SMTP poderia ser trocado por um serviço de terceiros (tais como Postmark) sem as mudanças em código. Em ambos os casos, apenas o identificador de recurso precisa mudar. diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index 66181a436..26a6a75da 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -1,7 +1,7 @@ ## I. Base de Código ### Uma base de código com rastreamento utilizando controle de revisão, muitos deploys -Uma aplicação 12 fatores é sempre rastreada em um sistema de controle de versão, como [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), ou [Subversion](http://subversion.apache.org/). Uma cópia da base de dados do rastreamento de revisões é conhecido como *repositório de código*, normalmente abreviado como *repositório* ou *repo*. +Uma aplicação 12 fatores é sempre rastreada em um sistema de controle de versão, como [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), ou [Subversion](http://subversion.apache.org/). Uma cópia da base de dados do rastreamento de revisões é conhecido como *repositório de código*, normalmente abreviado como *repositório* ou *repo*. Uma *base de código* é um único repo (em um sistema de controle de versão centralizado como Subversion), ou uma série de repositórios que compartilham um registro raiz. diff --git a/content/pt_br/port-binding.md b/content/pt_br/port-binding.md index ae3e0bf26..f2b291cf5 100644 --- a/content/pt_br/port-binding.md +++ b/content/pt_br/port-binding.md @@ -7,7 +7,7 @@ Apps web as vezes são executadas dentro de container de servidor web. Por exemp 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://jetty.codehaus.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. +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)). diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 19341fa74..68e53c205 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -3,7 +3,7 @@ *Сторонняя служба*-- это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Например, хранилища данных (например, [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например, [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например, [Postfix](http://www.postfix.org/)) и кэширующие системы (например, [Memcached](http://memcached.org/)). -Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (например, [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html) и [Last.fm](http://www.last.fm/api)). +Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (например, [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) и [Last.fm](http://www.last.fm/api)). **Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развертывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. diff --git a/content/ru/codebase.md b/content/ru/codebase.md index 439820d8a..af31a3cf5 100644 --- a/content/ru/codebase.md +++ b/content/ru/codebase.md @@ -1,7 +1,7 @@ ## I. Кодовая база ### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развертываний -Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* +Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* *Кодовая база* -- это один репозиторий (в централизованных системах контроля версий, как Subversion) или множество репозиториев, имеющих общие начальные коммиты (в децентрализованных системах контроля версий, как Git). diff --git a/content/ru/port-binding.md b/content/ru/port-binding.md index ec61c5e41..0ce9490a8 100644 --- a/content/ru/port-binding.md +++ b/content/ru/port-binding.md @@ -7,7 +7,7 @@ Во время локальной разработки разработчик переходит по URL-адресу вида `http://localhost:5000/`, чтобы получить доступ к сервису, предоставляемым его приложением. При развертывании слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. -Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению такой, как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://jetty.codehaus.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. +Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению такой, как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://www.eclipse.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. HTTP -- это не единственный сервис, который может быть экспортирован посредством привязки порта. Почти любой тип серверного ПО может быть запущен как процесс, привязанный к порту и ожидающий входящих запросов. Примеры этого включают [ejabberd](http://www.ejabberd.im/) (предоставляет [XMPP протокол](http://xmpp.org/)) и [Redis](http://redis.io/) (предоставляет [Redis протокол](http://redis.io/topics/protocol)). diff --git a/content/zh_cn/backing-services.md b/content/zh_cn/backing-services.md index 16d5fc550..69051a2d3 100644 --- a/content/zh_cn/backing-services.md +++ b/content/zh_cn/backing-services.md @@ -3,7 +3,7 @@ *后端服务*是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 -类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/)),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), [Last.fm](http://www.last.fm/api))。 +类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/)),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), [Last.fm](http://www.last.fm/api))。 **12-Factor 应用不会区别对待本地或第三方服务。** 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 [配置](./config) 中的服务定位/服务证书来获取数据。12-Factor 应用的任意 [部署](./codebase) ,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 [Amazon RDS](http://aws.amazon.com/rds/))。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换。上述 2 个例子中,仅需修改配置中的资源地址。 diff --git a/content/zh_cn/codebase.md b/content/zh_cn/codebase.md index 40af32cca..5cc3b90eb 100644 --- a/content/zh_cn/codebase.md +++ b/content/zh_cn/codebase.md @@ -1,7 +1,7 @@ ## I. 基准代码 ### 一份基准代码(*Codebase*),多份部署(*deploy*) -12-Factor应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库*(code repository, code repo, repo)。 +12-Factor应用(译者注:应该是说一个使用本文概念来设计的应用,下同)通常会使用版本控制系统加以管理,如[Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), [Subversion](http://subversion.apache.org/)。一份用来跟踪代码所有修订版本的数据库被称作 *代码库*(code repository, code repo, repo)。 在类似 SVN 这样的集中式版本控制系统中,*基准代码* 就是指控制系统中的这一份代码库;而在 Git 那样的分布式版本控制系统中,*基准代码* 则是指最上游的那份代码库。 diff --git a/content/zh_cn/port-binding.md b/content/zh_cn/port-binding.md index 045d8a164..3002de3ee 100644 --- a/content/zh_cn/port-binding.md +++ b/content/zh_cn/port-binding.md @@ -7,7 +7,7 @@ 本地环境中,开发人员通过类似`http://localhost:5000/`的地址来访问服务。在线上环境中,请求统一发送至公共域名而后路由至绑定了端口的网络进程。 -通常的实现思路是,将网络服务器类库通过 [依赖声明](./dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://jetty.codehaus.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 +通常的实现思路是,将网络服务器类库通过 [依赖声明](./dependencies) 载入应用。例如,Python 的 [Tornado](http://www.tornadoweb.org/), Ruby 的[Thin](http://code.macournoyer.com/thin/) , Java 以及其他基于 JVM 语言的 [Jetty](http://www.eclipse.org/jetty/)。完全由 *用户端* ,确切的说应该是应用的代码,发起请求。和运行环境约定好绑定的端口即可处理这些请求。 HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis 协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 From e0cb2769fd6688339d9a2e319bcdff6b14e13f72 Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Mon, 13 Feb 2017 08:33:50 +0000 Subject: [PATCH 325/472] add @sigerello for the Ukranian translation --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 7ae53c700..394435735 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott) and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: [@sigerello](https://github.com/sigerello), [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott) and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From 67b9eb7f2cd96f9d89448028c32de3ab09928847 Mon Sep 17 00:00:00 2001 From: melikeyurtoglu Date: Mon, 20 Feb 2017 23:28:48 +0300 Subject: [PATCH 326/472] Turkish Translation Signed-off-by: melikeyurtoglu --- content/tr/background.md | 9 +++++++++ content/tr/codebase.md | 18 ++++++++++++++++++ content/tr/dependencies.md | 12 ++++++++++++ content/tr/intro.md | 11 +++++++++++ content/tr/toc.md | 38 ++++++++++++++++++++++++++++++++++++++ content/tr/who.md | 4 ++++ 6 files changed, 92 insertions(+) create mode 100644 content/tr/background.md create mode 100644 content/tr/codebase.md create mode 100644 content/tr/dependencies.md create mode 100644 content/tr/intro.md create mode 100644 content/tr/toc.md create mode 100644 content/tr/who.md diff --git a/content/tr/background.md b/content/tr/background.md new file mode 100644 index 000000000..aa472d841 --- /dev/null +++ b/content/tr/background.md @@ -0,0 +1,9 @@ +Arkaplan +========== + +Bu belgeye katkıda bulunan kişiler, yüzlerce uygulamanın geliştirilmesi ve dağıtılmasında doğrudan yer almış, ve dolaylı olarak Heroku platformundaki üzerinde çalıştığımız yüz binlerce uygulamanın geliştirilmesi, çalıştırılması ve ölçeklendirilmesine tanık olmuştur. + +Bu belge, çok çeşitli yazılım servislerinin, yabancı ortamdaki deneyim ve gözlemlerini birleştirir. +Bu uygulama geliştirimindeki uygun, ideal uygulamalarda bir üçgenleştirme vardır; uygulamanın zamanla olan doğal gelişmesinin, büyümesinin temel etmenlerine dikkat etmek, uygulamanın kod tabanında çalışan yazılımcıların arasındaki işbirliğinin önemli noktaları ve yazılım erozyonunun getirdiği ücretten kaçmak. + +Bizim motivasyonumuz, modern uygulama geliştirmesinde gördüğümüz bazı sistemik problemlerin farkındalığını arttırmak, terimlerle birlikte geniş kavramsal çözüm setleri sağlamak ve bu problemleri tartışmak için ortak bir kelime sunmakdır. Martin Fowler'ın kitabları *Patterns of Enterprise Application Architecture* ve *Refactoring'den* ilham alınmıştır. diff --git a/content/tr/codebase.md b/content/tr/codebase.md new file mode 100644 index 000000000..73d68b7c3 --- /dev/null +++ b/content/tr/codebase.md @@ -0,0 +1,18 @@ +## I. Kod Tabanı +### Bir çok dağıtım kod tabanı gözden geçirme kontrolünde izlenmeli + +On iki faktör bir uygulama her zaman [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) veya [Subversion](http://subversion.apache.org/) gibi bir sürüm takip sistemiyle izlenir. VEritabanının gözden geçirme sisteminin bir kopyası *kod deposu* olarak bilinir. *kod repo* ya da sadece *repo* olarak kısaltılır. + +Bir *kod tabanı* herhangi tek bir depo(Subversion gibi merkezi gözden geçirme kontrol sistemi) ya da kök işleyicini paylaşan bir takım repodur(Git gibi merkezi olmayan gözden geçirme kontrol sistemi). + +![Bir kod tabanı bir çok dağıtımla eşlenir](/images/codebase-deploys.png) + +Kod tabanı ve uygulama arasında bire-bir ilişki her zaman vardır: + +* Eğer birden fazla kod tabanı varsa bu bir uygulama değil, dağıtık sistemdir. Dağıtık sistemdeki her bileşen bir uygulamadır ve her biri on iki faktörle bireysel olarak uyumlu olmalıdır. +* Aynı kodu paylaşan birden fazla uygulama, on iki faktörü ihlal eder. Burada çözüm, paylaşılan kodun [bağımlılık yöneticisi](./dependencies) aracılığıyla dahil edilebilecek kütüphanelere dönüştürülmesidir. + + +Uygulamanın sadece bir kod tabanı vardır fakat birden fazla dağıtımı olacaktır. Bir *dağıtım*, uygulamanın çalışan bir örneğidir. Ayrıca her geliştiricinin kendi yerel geliştirme ortamında çalışan bir kopyası vardır ve bunların her biri aynı zamanda dağıtım olarak nitelendirilirler. + +Sürümler her bir dağıtımda etkin olabilir fakat kod temeli tüm dağıtımlarda aynıdır. Örneğin, geliştiricilerin henüz uygulamaya eklenmemiş commitleri olabilir. Bu nedenle hepsi ayrı dağıtım olarak tanımlanır ama kod tabanı aynıdır. diff --git a/content/tr/dependencies.md b/content/tr/dependencies.md new file mode 100644 index 000000000..05c5482f0 --- /dev/null +++ b/content/tr/dependencies.md @@ -0,0 +1,12 @@ +## II. Bağımlıklar +### Bağımlıkları açık bir şekilde açıklama ve ayırma + +Çoğu programlama dili destek kitaplıklarını dağıtmak için bir paketleme sistemi sunar, Perl için [CPAN](http://www.cpan.org/), Ruby için [Rubygems](http://rubygems.org/). Bir paketleme sistemi aracılığıyla yüklenen kütüphaneler, sistem genelinde ("site paketleri" olarak bilinir) yüklenebilir veya uygulamanın bulunduğu dizine ("sağlayıcı" veya "paketleme" olarak bilinir) dahil edilebilir. + +**On iki faktör bir uygulama asla sistem çapında paketlerin gizli var olmasına dayanmaz.** Bir *bağımlılık bildirimi* ile tüm bağımlılıkları tamamen ve eksiksiz olarak bildirir. Üstelik bağımlılıkların çevredeki sistemden sızmamasını sağlamak için yürütme sırasında bir *bağımlılık yalıtım* aracı kullanılır. Tam ve açık bağımlılık belirtimi hem üretim hem de geliştirme için eşit olarak uygulanmaktadır. + +Örneğin, Ruby için [Bundler](https://bundler.io/), bağımlılık bildirimi için `Gemfile` manifest formatını ve bağımlılık yalıtımı için `bundle exec`'i önerir. Python'da bu adımlar için iki ayrı araç bulunur: [Pip](http://www.pip-installer.org/en/latest/), bildirimde ve [Virtualenv'de](http://www.virtualenv.org/en/latest/) yalıtımda kullanılır. C bile bağımlılık bildirimi için [Autoconf'a](http://www.gnu.org/s/autoconf/) sahiptir ve bağımlılık yalıtımı statik link ile sağlanır. Ne olursa olsun birbiriyle uyumlu çalışan yazılım uygulaması, bağımlılık bildirimi ve bağımlılık yalıtımı birlikte kullanılmalıdır, sadece herhangi birinin olması on iki faktör için yeterli değildir. + +Açık bağımlılık bildiriminin bir faydası da uygulamaya yeni olan geliştiriciler için kurulumu kolaylaştırır. Yeni geliştirici geliştirme aracında uygulamanın kod tabanını kontrol edebilir, ön koşul olarak dil çalıştırma platformu ve bağımlılık yöneticisinin yüklenmiş olmasını ister. Rastgele olmayan *derleme komutları* ile birlikte uygulama kodunun çalışması için ihtiyaç duyulan her şeyi yükleyebilecekler. Örneğin, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) için `lein deps` iken, Ruby/Bundler için `bundle install`'dir. + +On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. (bir cümle eksik). Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. diff --git a/content/tr/intro.md b/content/tr/intro.md new file mode 100644 index 000000000..b6c51b9ae --- /dev/null +++ b/content/tr/intro.md @@ -0,0 +1,11 @@ +Giriş +========== + +Modern çağda yazılımlar yaygın olarak servis olarak sunulur;*web uygulamaları* ya da *yazılım hizmetleri*. On iki faktörlü uygulama, aşağıdaki gibi bir yazılım hizmeti oluşturmak için bir yöntemdir: + +* Projeye katılan yeni geliştiriciler için zaman ve maliyeti en aza indirmek için ayar otomasyonu için **bildirim** biçimleri kullanılır; +* Çalışma ortamları arasında maksimum taşınabilirlik sunan temel işletim sistemi ile **şifresiz sözleşmesi** vardır +* Sunucu ve sistem yönetimine olan ihtiyacı ortadan kaldıran modern **bulut platformlarına kurulum** için uygundur; +* İşlem, mimari veya geliştirme uygulamalarında önemli değişiklikler olmaksızın **ölçek büyültülebilir**. + +On iki faktör uygulaması herhangi bir programlama dili ile yazılmış uygulamalara uygulanabilir ve destek servislerinin herhangi bir kombinasyonu kullanılabilir (Veritabanı, kuyruk, önbellek vb.). diff --git a/content/tr/toc.md b/content/tr/toc.md new file mode 100644 index 000000000..b9fee8fd2 --- /dev/null +++ b/content/tr/toc.md @@ -0,0 +1,38 @@ +On İki Faktör +============= + +## [I. Kod Tabanı](./codebase) +### Bir çok dağıtım kod tabanı gözden geçirme kontrolünde izleme + +## [II. Bağımlıklar](./dependencies) +### Bağımlıkları açık bir şekilde açıklama ve ayırma + +## [III. Yapılandırma](./config) +### Ortamda yapılandırma depolama + +## [IV. Destek servisi](./backing-services) +### Destek servislerine ekli kaynak olarak davranma + +## [V. Derleme, Sürüm, Çalışma](./build-release-run) +### Derleme ve çalışma aşamalarını tam olarak ayırma + +## [VI. Süreç](./processes) +### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma + +## [VII. Port Bağlama](./port-binding) +### Port bağlama yolu üzerinden dışarı aktarma + +## [VIII. Eş Zamanlılık](./concurrency) +### Süreç modeli yardımıyla dağıtıklaştırma + +## [IX. Kullanıma Hazır Olma Durumu](./disposability) +### Hızlı başlangıç ve otomatik zararsız kapama ile sağlamlığı üst düzeye çıkarma + +## [X.Geliştirme/Üretim Eşitliği](./dev-prod-parity) +### Gelişim, evreleme ve üretimi olabildikçe benzer tutma + +## [XI. Günlükler](./logs) +### Günlüklere olay akışı gibi davranma + +## [XII. Yönetici Süreci](./admin-processes) +### Yönetici/yönetim görevlerini tek seferlik işlem olarak çalıştırma diff --git a/content/tr/who.md b/content/tr/who.md new file mode 100644 index 000000000..c87b0edca --- /dev/null +++ b/content/tr/who.md @@ -0,0 +1,4 @@ +Bu belgeyi kim okumalı? +======================= + +Herhangi bir çalışan uygulama geliştirenler. Bu tür uygulamaları dağıtan ve yöneten Ops mühendisleri. From 34cbea367750adef63ddc6ab17f1ba86b9e575b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Wo=C5=BAniak?= Date: Sat, 25 Feb 2017 22:45:12 +0100 Subject: [PATCH 327/472] fix typos in polish translation --- content/pl/admin-processes.md | 2 +- content/pl/background.md | 2 +- content/pl/codebase.md | 2 +- content/pl/concurrency.md | 2 +- content/pl/dependencies.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/pl/admin-processes.md b/content/pl/admin-processes.md index c894c734f..c0273dbfa 100644 --- a/content/pl/admin-processes.md +++ b/content/pl/admin-processes.md @@ -4,7 +4,7 @@ [Formacja](./concurrency) jest zestawem procesów używanych przez aplikację podczas jej działania (np. obsługi zapytań z sieci). Do często wykonywanych zadań administracyjnych należą: * Wykonanie migracji bazy danych (np. `manage.py migrate` w Django, `rake db:migrate` w Railsach). -* Uruchomienie konsoli (znanej również jako powłoka [REPL](http://pl.wikipedia.org/wiki/REPL)) by wykonać frament kodu lub podejrzeć modele działającej bazy danych. Większość środowisk języków programowania udostępnia REPL poprzez wywołanie interpretera bez dodatkowych argumentów (np. `python` lub `perl`). W innych przypadkach przeznaczone są do tego osobne polecenia (np. `irb` w Ruby, `rails console` w Railsach). +* Uruchomienie konsoli (znanej również jako powłoka [REPL](http://pl.wikipedia.org/wiki/REPL)) by wykonać fragment kodu lub podejrzeć modele działającej bazy danych. Większość środowisk języków programowania udostępnia REPL poprzez wywołanie interpretera bez dodatkowych argumentów (np. `python` lub `perl`). W innych przypadkach przeznaczone są do tego osobne polecenia (np. `irb` w Ruby, `rails console` w Railsach). * Wykonywanie pojedynczych skryptów znajdujących się w repozytorium kodu aplikacji (np. `php scripts/fix_bad_records.php`). Pojedyncze zadania powinny być uruchamiane w identycznym środowisku jak [długoterminowe procesy](./processes) aplikacji. Działają w ramach tego samego [wdrożenia](./build-release-run), używając tego samego [kodu](./codebase) i [konfiguracji](./config) jak każdy inny działający proces. Kod zadania administracyjnego musi zostać dołączony do kodu aplikacji by uniknąć problemów z synchronizacją. diff --git a/content/pl/background.md b/content/pl/background.md index aac752d74..0a6af3bda 100644 --- a/content/pl/background.md +++ b/content/pl/background.md @@ -5,6 +5,6 @@ Kontrybutorzy tego dokumentu byli bezpośrednio zaangażowani w tworzenie i wdra Ten dokument jest podsumowaniem całego naszego doświadczenia i obserwacji szerokiej gamy aplikacji SaaS. Jest on połączeniem idealnych praktyk developmentu, zwracania szczególnej uwagi na naturalny rozrost aplikacji w czasie, dynamiki współpracy developerów pracujących nad jednym codebase'm, oraz [unikania kosztów gnijącego oprogramowania](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). -Naszym celem jest podniesienie poziomu świadomości o podstawowych problemach, które dostrzegliśmy przy tworzeniu nowoczesnych aplikacji, zapewnienie wspólnego słownictwa dp rozmowy o tych problemach oraz zaoferowanie ogólnych rozwiązań dla tych problemów wraz z towarzyszącą terminologią. Format dokumentu jest inspirowany książkami Martina Fowlera +Naszym celem jest podniesienie poziomu świadomości o podstawowych problemach, które dostrzegliśmy przy tworzeniu nowoczesnych aplikacji, zapewnienie wspólnego słownictwa do rozmowy o tych problemach oraz zaoferowanie ogólnych rozwiązań dla tych problemów wraz z towarzyszącą terminologią. Format dokumentu jest inspirowany książkami Martina Fowlera *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* oraz *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. diff --git a/content/pl/codebase.md b/content/pl/codebase.md index aefb378d8..0217667d6 100644 --- a/content/pl/codebase.md +++ b/content/pl/codebase.md @@ -1,7 +1,7 @@ ## I. Codebase ### Jedno źródło kodu śledzone systemem kontroli wersji, wiele wdrożeń -Aplikacja 12factor napisana jest zawsze zarządzania w systemie kontroli wersji takim jak [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), czy [Subversion](http://subversion.apache.org/). Miejsce, w którym trzymany i rewizjonowany jest kod nazywane jest *repozytorium kodu źródłowego*, często skracane do samego *code repo*, albo po prostu *repo*. +Aplikacja 12factor zawsze jest zarządzana w systemie kontroli wersji takim jak [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), czy [Subversion](http://subversion.apache.org/). Miejsce, w którym trzymany i rewizjonowany jest kod nazywane jest *repozytorium kodu źródłowego*, często skracane do samego *code repo*, albo po prostu *repo*. *Codebase* (baza kodu) jest więc niczym innym jak pojedynczym repo (w przypadku zcentralizowanego systemu kontroli wersji jak Subversion), albo zestawem repozytoriów, które współdzielą tzw. root commit. (w przypadku zdecentralizowanego systemu jak Git). diff --git a/content/pl/concurrency.md b/content/pl/concurrency.md index 8e3714ea8..0a20d01d3 100644 --- a/content/pl/concurrency.md +++ b/content/pl/concurrency.md @@ -1,7 +1,7 @@ ## VIII. Współbieżność ### Skaluj przez odpowiednio dobrane procesy -Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jeden lub więcej procesów. Aplikacje internetowe mogą być uruchamiane w różnorodny sposób. Dla przykładu - procesy PHP uruchamiane są na żądanie (w zależności od potrzeby obsługi odpowiednio dużej liczby zapytań) się jako podrzędne procesy Apache'a. W Javie procesy obsługiwane są zupełnie inaczej, z JVM zapewniającym jeden nadrzędny proces, który rezerwuje zasoby systemu (CPU oraz pamięć) na starcie oraz współbieżnością zarządzaną wewnętrznie i opartą na wątkach. Dla developerów aplikacji różnica jednak nie będzie szczególnie odczuwalna. +Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jeden lub więcej procesów. Aplikacje internetowe mogą być uruchamiane w różnorodny sposób. Dla przykładu - procesy PHP uruchamiane są na żądanie (w zależności od potrzeby obsługi odpowiednio dużej liczby zapytań) jako podrzędne procesy Apache'a. W Javie procesy obsługiwane są zupełnie inaczej, z JVM zapewniającym jeden nadrzędny proces, który rezerwuje zasoby systemu (CPU oraz pamięć) na starcie oraz współbieżnością zarządzaną wewnętrznie i opartą na wątkach. Dla developerów aplikacji różnica jednak nie będzie szczególnie odczuwalna. ![Skala wyrażana jest przez działające procesy, natomiast różnorodność obciążenia wyrażana jest w typach procesów](/images/process-types.png) diff --git a/content/pl/dependencies.md b/content/pl/dependencies.md index 4b0dd0cd4..eec6b8aa1 100644 --- a/content/pl/dependencies.md +++ b/content/pl/dependencies.md @@ -9,4 +9,4 @@ Np. [Bundler](https://bundler.io/) dla Ruby'ego używa pliku `Gemfile` dla dekla 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łąćzone. +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. From dff8fc65c364066f32c696f075f2c15438743362 Mon Sep 17 00:00:00 2001 From: melikeyurtoglu Date: Sun, 26 Feb 2017 04:05:01 +0300 Subject: [PATCH 328/472] Turkish translation --- content/tr/admin-processes.md | 14 ++++++ content/tr/backing-services.md | 14 ++++++ content/tr/build-release-run.md | 18 ++++++++ content/tr/concurrency.md | 14 ++++++ content/tr/config.md | 22 ++++++++++ content/tr/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/tr/disposability.md | 12 ++++++ content/tr/logs.md | 16 +++++++ content/tr/port-binding.md | 14 ++++++ content/tr/processes.md | 14 ++++++ content/tr/toc.md | 4 +- 11 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 content/tr/admin-processes.md create mode 100644 content/tr/backing-services.md create mode 100644 content/tr/build-release-run.md create mode 100644 content/tr/concurrency.md create mode 100644 content/tr/config.md create mode 100644 content/tr/dev-prod-parity.md create mode 100644 content/tr/disposability.md create mode 100644 content/tr/logs.md create mode 100644 content/tr/port-binding.md create mode 100644 content/tr/processes.md diff --git a/content/tr/admin-processes.md b/content/tr/admin-processes.md new file mode 100644 index 000000000..74b1e6bae --- /dev/null +++ b/content/tr/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Yönetici Süreci +### Yönetici/yönetim görevlerini tek seferlik işlem olarak çalıştırma + +[Süreç oluşumu](./concurrency) uygulama çalışırken uygulamanın sıradan işlerini (web isteklerini idare etmek gibi) yapmakta kullanılan süreçlerin bir dizisidir. Ayrı olarak, geliştiriciler çoğunlukla uygulamanın bir kereye mahsus yönetimsel veya bakım görevlerini yapmayı dileyecekler, şunun gibi: + +* Veri tabanı göçü çalıştırmak (Django'da `manage.py migrate`, Rails'de `rake db:migrate`). +* Konsolu ([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) kabuğu olarakta bilinir), rastgele kodu çalıştırmak veya canlı veritabanına karşılık uygulamanın modellerini denetlemek için çalıştırmak. Çoğu dil hiç bir arguman olmadan (`python` veya `perl`), yorumlayıcı veya bazı durumlarda ayrı komutlarla (Ruby için `irb`, Rails için `rails console`) çalıştırarak bir REPL sağlar. +* Uygulamanın deposuna commit'lenmiş betikleri çalıştırmak (`php scripts/fix_bad_records.php`). + +Bir kerelik yönetici süreçleri uygulamanın sıradan [uzun çalışan süreçleri](./processes) gibi aynı ortamlarda çalışmalıdır. Onlar herhangi bir sürecin çalıştığı gibi [sürüme](./build-release-run) karşı aynı [kod tabanı](./codebase) ve [yapılandırmayı](./config) kullanarak çalışır. Yönetici uygulama kodunu senkronizasyon sorunundan kaçınmak için yüklemelidir. + +Aynı [bağımlılık yalıtımı](./dependencies) teknikleri bütün süreç yönetiminde kullanılmalıdır. Örneğin, eğer Ruby web süreçleri `bundle exec thin start` komutunu kullanıyorsa, veri tabanı göçü `bundle exec rake db:migrate` komutu kullanmalıdır. Aynı durumda, Virtualenv kullanan bir Python programı, Tornado web sunucusu ve herhangi bir `manage.py` yönetici süreçlerinin ikisini de çalıştırabilmek için `bin/python` kullanmalıdır. + +On iki faktör, REPL kabuğunu kural dışı sağlayan ve tek seferlik betikleri çalıştırmayı kolaylaştıran dilleri fazlasıyla destekler. Yerel dağıtımda, geliştiriciler uygulamanın kontrol dizinindeki açık kabuk komutuyla tek seferlik yönetici süreçlerini çalıştırır. Ürün dağıtımında, geliştiriciler bu gibi bir süreci çalıştırmak için ssh veya dağıtımın çalışma ortamı tarafından sağlanan diğer uzak komut çalıştırma mekanizmasını kullanabilir. diff --git a/content/tr/backing-services.md b/content/tr/backing-services.md new file mode 100644 index 000000000..d2dba0ae8 --- /dev/null +++ b/content/tr/backing-services.md @@ -0,0 +1,14 @@ +## IV. Destek servisi +### Destek servislerine ekli kaynak olarak davranma + +Bir *destek servisi* uygulamanın kendi normal işleminin bir parçası olarak ağ üzerinden tüketim yapan bir servistir. Örnekler veri deposu([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlama/kuyruklama sistemleri( [RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](http://kr.github.com/beanstalkd/)), giden email için SMTP servisi([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemleri([Memcached](http://memcached.org/) gibi) içerir. + +Destek servisleri, veri tabanı gibi, uygulamaların çalışma zamanlı dağıtımlarında olduğu gibi benzer sistem yöneticileri tarafından geleneksel olarak yönetilirler. Bu yerel yönetilen servislere ilave olarak, uygulama üçüncü parti uygulamalar tarafından onaylanmış ve yönetilmiş servislere sahip olabilirler. Örnekler SMTP servisleri([Postmark](http://postmarkapp.com/) gibi), Metrik toplama servisleri( [New Relic](http://newrelic.com/) veya [Loggly](http://www.loggly.com/) gibi), binary servisler([Amazon S3](http://aws.amazon.com/s3/) gibi) ve API-erişilebilir tüketici servisleri bile [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ve [Last.fm](http://www.last.fm/api) gibi) içerir. + +**On iki faktör uygulaması için bu kod, yerel ve üçüncü parti servisler arasında ayrım yapmaz.** Uygulamada, her ikiside ek kaynaktır, [yapılandırmada](./config) saklanmış yer belirleyici/kimlik bilgileri ve URL aracılığıyla erişilir. On iki faktör uygulamasının bir dağıtımı, uygulama kodunda hiçbir değişiklik olmadan üçüncü parti([Amazon RDS](http://aws.amazon.com/rds/) gibi) tarafından yönetilenle yerel MySQL veritabanı silebilmelidir. Aynı şekilde bir yerel SMTP servisi(Postmark gibi), kod değişikliksiz bir üçüncü parti SMTP servisiyle değiş tokuş yapılabilir. Her iki durumda da, kaynak sadece değişmesi gereken yapılandırmada ele alınır. + +Her bir belirgin destek servisi bir *kaynaktır*. Örneğin, bir MySQL veritabanı(Uygulama katmanında parçalanma için kullanılmış) bir kaynaktır; iki MySQL veritabanı iki belirgin kaynak olarak nitelendirilir. On iki faktör uygulaması veritabanlarına, bağlı oldukları dağıtımlara gevşek bağlaşımlarını belirten *ek kaynak* olarak davranır. + +A production deploy attached to four backing services. + +Kaynaklar dağıtımlara istenilen zamanda eklenilip çıkartılabilir. Örneğin, eğer uygulamanın veritabanı donanım sorununa göre yanlış davranıyorsa, uygulamanın yöneticisi son yedeklemeden geri yüklenmiş yeni bir veri tabanı sunucusunu döndürebilir. Şuanki veritabanı ekten çıkarılmış olabilir ve yeni veri tabanı eklenmiş olabilir, hiç bir kod değişikliği olmadan. diff --git a/content/tr/build-release-run.md b/content/tr/build-release-run.md new file mode 100644 index 000000000..3ba750c7a --- /dev/null +++ b/content/tr/build-release-run.md @@ -0,0 +1,18 @@ +## V. Derleme, Sürüm, Çalıştırma +### Derleme ve çalıştırma aşamalarını tam olarak ayırma + +Bir [kod tabanı](./codebase) üç aşamada dağıtıma dönüşebilir: + +* *Derleme aşaması* kod deposunun *derleme* olarak bilinen çalıştırılabilir pakette çeviren bir dönüşümdür.Dağıtım süreci tarafından belirlenen bir commit'deki kodun versiyonunu kullanırken, derleme aşaması sağlayıcı [bağımlılıkları](./dependencies) getirir ve binary'leri derler. +* *Sürüm aşaması*, derleme aşaması tarafından üretilmiş derlemeyi alır ve dağıtımı şu anki [yapılandırmasıyla](./config) birleştirir. Son durumda oluşan *sürüm* derleme ve yapılandırmanın ikisinide içerir ve çalışma ortamındaki doğrudan çalıştırma için hazırdır. +* *Çalıştırma evresi* (aynı zamanda "runtime" olarak bilinir) seçili sürümün karşılığındaki uygulamanın [süreçlerini](./processes) bazı setlerini başlatarak, çalıştırma ortamındaki uygulamayı çalıştırır. + +![Kod, sürüm oluşturmak için yapılandırmayla birleşmiş derlemeye dönüşür.](/images/release.png) + +**On iki faktör uygulamaları derleme,sürüm ve çalıştırma aşamaları arasında mutlak ayırmayı kullanır.** Örneğin, koddaki değişiklikleri derleme aşamasına geri döndürmenin bir yolu olmadığı için çalışma zamanında kodda değişiklik yapmak imkansızdır. + +Dağıtım araçları genel olarak sürüm yönetim araçlarını önerir, en dikkat çekeni bir önceki sürüme geri dönme yeteneğidir. Örneğin, [Capistrano](https://github.com/capistrano/capistrano/wiki) dağıtım aracı sürümleri, şu anki sürümün şimdiki sürüm dizinine bir sembolik link olduğu, `releases` adlı alt dizinde depolar. `rollback` komutu, bir önceki sürüme hızlı geri dönüşü kolaylaştırır. + +Her sürüm her zaman sürümlerin zaman damgası gibi (`2011-04-06-20:32:17` gibi) özel sürüm ID'sine veya artış numarasına (`v100` gibi) sahip olmalıdır. Sürümler yalnızca eklemeli bir defterdir ve bir kere oluşturulduğu zaman dönüştürülemez. Herhangi bir değişiklik yeni bir sürüm oluşturmalıdır. + +Derlemeler, herhangi bir zamanda yeni kod dağıtıldığında uygulama geliştiricileri tarafından başlatılır. Çalışma zamanı yürütmesi, kontras tarafından, sunucu tekrar çalıştırılması veya çökmüş süreçlerin süreç yöneticisi tarafından tekrar başlatılması gibi durumlarda otomatik olarak olabilir. Bunun sonucunda, çalıştırma evresi, gecenin bir yarısında çalışan geliştiriciler yokken uygulamanın çalışmasını engelleyen problemler uygulamanın bozulmasına yol açabildiği için, olabildiği kadar az sayıda hareketli bölüm olarak tutulmalıdır. Derleme evresinde, hatalar dağıtımı çalıştıran geliştiriciler için her zaman ön planda olduğu için daha fazla karış olabilir. diff --git a/content/tr/concurrency.md b/content/tr/concurrency.md new file mode 100644 index 000000000..1707ea635 --- /dev/null +++ b/content/tr/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Eş Zamanlılık +### Süreç modeli yardımıyla dağıtıklaştırma + +Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha fazla süreç tarafından temsil edilir. Web uygulamaları çeşitli süreç çalışma formlarını alır. Örneğin, Php süreçleri Apache'nin çocuk süreçleri olarak çalışır, istek üzerine talep hacmine tarafından ihtiyaç duyulduğunda başlatılır. Java süreçleri, karşıt yaklaşımı benimser; JVM, başlangıçta çok sayıda sistem kaynağı (CPU ve bellek) ayıran büyük bir uber işlemi sağlar ve eşzamanlılık iş parçacıkları aracılığıyla dahili olarak yönetilir. Her iki durumda, çalışan süreçler, uygulamanın geliştiricilerine yalnızca minimum düzeyde görünürdür. + +![Ölçek, çalışan süreçler olarak ifade edilir, iş yükü çeşitliliği, süreç tipi olarak tanımlanır.](/images/process-types.png) + +**On iki faktör uygulamasında, süreçler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki süreçler [arka planda çalışan servis programları için olan unix süreç modelinden](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) güçlü ipuçları alır. Bu modeli kullanarak geliştirici uygulamasını her bir tip işe bir *süreç tipi* atayarak, ayrı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web süreçleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi süreçler tarafından işlenir. + +Bu, bireysel süreçlerin kendi dahili çoklu işlemelerini içermiyor değil, çalışma zamanı içindeki iş parçacıkları aracılığıyla VM, veya [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron model. Fakat bireysel VM yalnızca çok aşırı büyüyebilir (dikey ölçekte), bu yüzden uygulama aynı zamanda çoklu fiziksel makinelerde çalışan çoklu süreçleri içerebilmelidir. + +Bu süreç modeli, konu ölçeklendirme zamanına geldiğinde gerçekten çok başarılıdır. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama süreçleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir işlem olduğu anlamına gelir. Süreç tipleri dizisi ve her bir tipin süreçlerinin numarası *süreç oluşumu* olarak bilinir. + +On iki faktör uygulama süreçleri [asla arka planda çalışmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyalarını yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş süreçlere cevap vermek, kullanıcı başlatımlı tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin süreç yöneticisine( [Upstart](http://upstart.ubuntu.com/) gibi bulut platformunda yayınlanmış süreç yöneticisi veya geliştirme sürecinde [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar ) dayanır. diff --git a/content/tr/config.md b/content/tr/config.md new file mode 100644 index 000000000..903672072 --- /dev/null +++ b/content/tr/config.md @@ -0,0 +1,22 @@ +## III. Yapılandırma +### Ortamda yapılandırma depolama + +Bir uygulamanın *yapılandırması* muhtemelen [dağıtımlar](./codebase) arasındaki değişikliktir(kademelendirme, ürün, geliştirici ortamları vb.). Bunları içerir: + +* Veri tabanını ele alan kaynaklar, önbellek ve diğer [destek servisleri](./backing-services) +* Amazon S3 ve Twitter gibi dış servisler için kimlik bilgileri +* Dağıtımlar için standart sunucu ismi gibi her dağıtım için değerler + +Uygulamalar bazen yapılandırmayı koddaki sabitler gibi saklar. Bu on iki faktörün, **yapılandırmayı koddan mutlak ayırmayı** gerektiren bir ihlalidir. Yapılandırma dağıtımlar arasında önemli derecede değişime uğrar, kod uğramaz. + +Bir uygulamanın tüm yapılandırmaları koddan doğru bir biçimde çıkarılıp çıkarılmadığına dair bir litot testi, herhangi bir kimlik bilgilerinden ödün vermeksizin kod tabanının her an açık kaynak yapıp yapamayacağına karar verir. + +Bu *yapılandırma* tanımlamasının, [Spring](http://spring.io/)'de [kod modullerinin bağlantısında](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) olduğu gibi ve Rails'de `config/routes.rb` gibi dahili uygulama yapılandırmasını **içermediğini** unutmayın. Bu tip yapılandırma dağıtımlar arasında değişiklik göstermez ve bu kod içinde en iyi şekilde gerçekleştirilmiştir. + +Yapılandırmaya diğer bir yaklaşım Rails'deki `config/database.yml` gibi gözden geçirme kontrolünde kontrol edilmemiş yapılandırma dosyalarının kullanımıdır. Bu kod deposundaki kontrol edilmiş sabitlerin kullanımındaki büyük bir gelişmedir, fakat hala zayıflıkları vardır: Depoda, yapılandırma dosyalarının kontrolünde hata kolay yapılabilir; Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması için bir eğilim vardır, bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Bu formatların özel dil veya framework olma eğilimi vardır. + +**On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir**(sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunda yanlışlıkla kontrol edilme şansı az; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. + +Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `üretim` ortamları gibi belirli dağıtımlardan sonra adlandırılmış, adlandrılmış guruplar içinde yapılandırılır(genellikle "environments" olarak adlandırılır). Bu method temiz bir ölçüm yapmaz: uygulamanın daha fazla dağıtımı oluştuğu sürece, yeni ortam isimleri gereklidir, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir, dağıtım yönetimini çok hassas yapan yapılandırmanın birleşimsel infilakıyla sonuçlanır. + +On iki faktör uygulamasında ortam değişkenleri granular control'dür, her biri diğer ortam değişkenlerine karşı tamamen orthogonaldir. Asla "environments" olarak beraber gruplandırılamaz, fakat onun yerine her bir dağıtım için bağımsız yönetilir. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca büyüten bir modeldir. diff --git a/content/tr/dev-prod-parity.md b/content/tr/dev-prod-parity.md new file mode 100644 index 000000000..46e868889 --- /dev/null +++ b/content/tr/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X.Geliştirme/Üretim Eşitliği +### Gelişim, evreleme ve üretimi olabildikçe benzer tutma + +Tarihsel olarak, geliştirme (bir geliştirici uygulamanın yerel [dağıtımına](./codebase) canlı düzenlemeler yapar) ve ürün (uygulamanın çalışan dağıtımı son kullanıcılar tarafından erişilmiştir) arasında önemli aralıklar vardır. Bu aralıklar üç alanda belirtilir: + +* **Zaman aralığı:** bir geliştirici kod üzerinde günler,haftalar hatta aylar boyunca bile ürünü oluşturmak için çalışabilir. +* **Eleman aralığı:** Geliştiriciler kod yazar, ops mühendisleri dağıtır. +* **Araçların aralığı:** Geliştiriciler ürün dağıtımı Apache, MySQL ve Linux kullanırken; Nginx, SQLite, ve OS X gibi yığınları kullanıyor olabilir. + +**On iki faktör uygulaması, geliştirme ve ürün aralığını küçük tutarak, [sürekli dağıtım](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) için tasarlanmıştır.** Yukarda tanımlanan üç aralığa bakarsak: + +* Zaman aralığını küçültme: bir geliştirici kod yazabilir ve bu kodu saatler veya hatta dakikalar sonra dağıtmış olabilir. +* Eleman aralığını küçültme: kodu yazan geliştiriciler, kodu dağıtmakla yakından ilişkilidir ve üründeki davranışını izler. +* Araçların aralığını küçültme: geliştirmeyi ve ürünü olabildiği kadar benzer tut. + +Üstekileri bir tablo olarak özetlersek: + + + + + + + + + + + + + + + + + + + + + + +
Geleneksel uygulamaOn iki faktör uygulaması
Dağıtımlar arasındaki zamanHaftalarSaatler
Kod yazarları ve kod dağıtımcılarıFarklı insanlarAynı insanlar
Geliştirme ve ürün ortamıFarklıOlabildiğince benzer
+ +[Destek servisler](./backing-services); uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi, geliştirme/üretim eşitliğinin önemli olduğu bir alandır. Bir çok dil, farklı tipteki servislerin *uyarlayıcılarını* içeren, destek servislerine ulaşımı kolaylaştıran kütüphanleri önerir. Bazı örnekler aşağıdaki tabloda vardır. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TipDilKütüphaneUyarlayıcı
VeritabanıRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
KuyrukPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
ÖnbellekRuby/RailsActiveSupport::CacheBellek, dosya sistemi, Memcached
+ +Geliştiriciler, üründe ciddi ve sağlam destek servisleri kullanırken, bazen kendi yerel ortamlarında önemsiz destek servislerini kullanmak için istek duyarlar. Örneğin, yerelde SQLite üründe PostgreSQL kullanılır veya geliştirmede depolama için yerel süreç belleği ve üründe de Memcached kullanılır. + +**On iki faktör geliştiricisi**, uyarlayıcılar teorik olarak destek servislerindeki herhangi bir farklılığı soyutladığı zaman bile **geliştirme ve ürün arasında faklı destek servisi kullanma isteğine karşı direnir.** Destek hizmetleri arasındaki farklılıklar, küçük uyumsuzlukların ortaya çıkması, kodun işe yaraması ve geliştirme aşamasında testlere geçilmesi veya üretimde başarısız olmaya neden olması anlamına gelir. Bu tür hatalar, sürekli dağıtımın etkisini azaltan bir sürtüşme yaratır. Bu sürtünme maliyeti ve sonraki devamlı dağıtımın azaltılması, bir uygulamanın ömrü süresince toplamda düşünüldüğünde oldukça yüksektir. + +Önemsiz yerel servisler bir zamanlar olduğundan daha zorlayıcıdır. Memcached, PostgreSQL ve RabbitMQ gibi modern destek servisleri, [Homebrew](http://mxcl.github.com/homebrew/) ve [apt-get](https://help.ubuntu.com/community/AptGet/Howto) gibi modern paket sistemleri sayesinde yüklemesi ve çalıştırılması zor değildir. Alternatif olarak, [Chef](http://www.opscode.com/chef/) ve [Puppet](http://docs.puppetlabs.com/) gibi bildiri sağlayıcı araçlar önemsiz sanal ortamlarla birleşir, [Vagrant](http://vagrantup.com/) gibi, geliştiricilerin yerel ortamda çalışmalarına izin verir, yaklaşık olarak ürün ortamına benzer. Bu sistemlerin yüklenmesi ve kullanımının maliyeti, geliştirme üretim eşitliği ve sürekli dağıtımın faydasıyla karşılaştırıldığında düşüktür. + +Farklı destek servislerinin uyarlayıcıları hala kullanışlıdır, çünkü yeni destek servislerine bağlanmayı nispeten zahmetsiz yapar. Ama uygulamanın bütün dağıtımları (geliştirme ortamları, evreleme, ürün) her bir destek servisinin aynı tip ve versiyonunu kullanmalıdır. diff --git a/content/tr/disposability.md b/content/tr/disposability.md new file mode 100644 index 000000000..f90c73693 --- /dev/null +++ b/content/tr/disposability.md @@ -0,0 +1,12 @@ +## IX. Kullanıma Hazır Olma Durumu +### Hızlı başlangıç ve otomatik zararsız kapama ile sağlamlığı üst düzeye çıkarma + +**On iki faktör uygulamalarını [süreçleri](./processes) *tek kullanımlıktır*, anlamı anlık uyarıda başlatılabilirler veya durdurulabilirler.** Bu hızlı esnek ölçeklemeyi, [kod](./codebase) ve [yapılandırma](./config) değişikliğinin hızlı dağıtımı ve üretim dağıtımının sağlamlığı kolaylaştırır. + +Süreçler **başlangıç zamanını küçültmeye* çabalamalıdır. İdeal olarak, bir süreç başlatma komutunun çalıştırılıp, sürecin ayağa kalkmış ve istek veya işleri almaya hazır olana kadar olan süre bir kaç saniye alır. Kısa başlama zamanı [sürüm](./build-release-run) süreci ve arttırım için daha fazla çabukluk sağlar; ve sağlamlığına yardımcı olur, çünkü süreç yöneticisi izin verildiğinde süreçleri yeni fiziksel makinelere daha kolay taşıyabilir. + +Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, incelikli kapanır.** Web süreci için incelikli kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), herhangi bir o anki isteklerin bitmesine izin verilmesi ve daha sonra çıkılmasıyla sonuçlanır. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. + +Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](http://kr.github.com/beanstalkd/)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. + +Süreçler esas donanımdaki hata durumlarında **ani kapanmaya karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile incelikli kapamadan daha az yaygın bir olay olduğu için hala olabilir. Önerilen yaklaşım sağlam arkaplan kuyruklama kullanımıdır, Beanstalkd gibi, istemciler oturumu kapattığı zaman veya süre dolduğu zaman işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması incelikli olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only dezaynı](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucunu](http://docs.couchdb.org/en/latest/intro/overview.html) alır. diff --git a/content/tr/logs.md b/content/tr/logs.md new file mode 100644 index 000000000..fe7011016 --- /dev/null +++ b/content/tr/logs.md @@ -0,0 +1,16 @@ +## XI. Günlükler +### Günlüklere olay akışı gibi davranma + +*Günlükler* çalışan bir uygulamanın davranışının görünür olmasını sağlar. Sunucu tabanlı ortamlarda genellikle diskteki bir dosyaya yazılırlar("logfile"); ama bu sadece çıktı formatındadır. + +Günlükler, bütün çalışan süreçler ve destek servislerinin çıktı akışlarından kümelenmiş, zaman sıralı olayların [akışıdır](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/). Günlükler ilk formda her bir satır için bir olay olacak şekilde yazı formatındadır(Bununla birlikte istisnalardaki geri dönüşleri birden fazla satırda ölçebilir). Günlükler başta ve sonda düzeltilmemiş ama akış, uygulama işlediği sürece devam eder. + +**On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Günlük dosyalarını yazma ve yönetme yapmamalıdır. Bunun yerine, her çalışan süreç kendi olay akışını tamponlamadan `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinin önplanında bu akışı inceleyecekler. + +Evreleme ve ürün dağıtımlarında herbir sürecin akışı çalışma ortamı tarafından yakalanmış diğer uygulamadaki, diğer bütün akışlarla birlikte sıralanmış, görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilmiş olacaklar. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, bunun yerine tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak günlük yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluent](https://github.com/fluent/fluentd) gibi) bu amaç için erişilebilirdir. + +Bir uygulama için olay akışı dosyaya yönlendirilebilir veya terminalden gerçek zamanlı kuyruklama aracılığla izlenebilir. En önemlisi, akış [Splunk](http://www.splunk.com/) gibi günlük numaralandırma ve analiz sistemine veya [Hadoop/Hive](http://hive.apache.org/) gibi genel amaçlı veri depolama sistemine gönderilebilir. Bu sistemler uygulamanın zamanla olan davranışlarında iç gözlem yapmak için büyük güç ve esnekliğe izin verir. Bunları içerir: + +* Geçmişteki özel olayları bulmak. +* Eğilimlerin geniş aralıklı grafikleri(her bir dakika için olan istekler gibi). +* Kullanıcı tanımlı kestirme yollara göre aktif uyarma(Bir dakikadaki hataların niceliği belirli bir alt sınırı geçtiği zaman olan uyarı gibi). diff --git a/content/tr/port-binding.md b/content/tr/port-binding.md new file mode 100644 index 000000000..294002371 --- /dev/null +++ b/content/tr/port-binding.md @@ -0,0 +1,14 @@ +## VII. Port Bağlama +### Port bağlama yolu üzerinden dışarı aktarma + +Web uygulamaları bazı zamanlar web sunucu konteynırları içinde çalıştırılırlar. Örneğin, PHP uygulamaları modül olarak [Apache HTTPD](http://httpd.apache.org/) içinde veya Java uygulamaları [Tomcat](http://tomcat.apache.org/) içinde çalıştırılabilirler. + +**On iki faktör uygulama tamamen bağımsız** ve web dönüştürme servisi oluşturmak için çalışma ortamı içindeki web sunucunun çalışma zamanlı enjeksiyonuna dayanmaz. Bu web uygulaması port bağlama tarafından HTTP'yi servis olarak dışa aktarır ve o porta gelen istekleri dinler. + +Yerel geliştirme ortamında, geliştiriciler `http://localhost:5000/` gibi servis URL'ini, onların duygulamaları tarafından dışa aktarılan servise erişmek için ziyaret ederler. Dağıtımda, yönlendirme katmanı public-facing makineadından port bağımlı web süreçlerine gelen yönlendirme isteklerini ele alır. + +Bu tipik olarak, uygulamaya web sunucusu kütüphanesi eklemek için bağımlılık tanımlaması kullanılarak geliştirilmiştir, Python için [Tornado](http://www.tornadoweb.org/), Ruby için [Thin](http://code.macournoyer.com/thin/) veya Java ve diğer JVM-tabanlı diller için [Jetty](http://jetty.codehaus.org/jetty/). Bu uygulamanın kodu içinde *kullanıcı alanında* gerçekleşir. Çalışma ortamıyla olan anlaşma isteklere hizmet veren bir porta bağlıdır. + +HTTP port bağlama ile dışarı aktarılabilen tek servis değildir. Nerdeyse herhangi bir sunucu yazılım tipi port için süreç bağlama aracılığıyla çalışır ve gelen istekleri bekler. Örnekler [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/) ile haberleşir) ve [Redis](http://redis.io/) ([Redis protocol](http://redis.io/topics/protocol) ile haberleşir) içerir. + +Port bağlama yaklaşımı bir uygulamanın,tüketici uygulama için yapılandırmadaki kaynak olanağı gibi destek uygulamasına URL sağlayarak diğer bir uygulamanın [destek servisi](./backing-services) olabileceği anlamına geldiğini de unutmayın. diff --git a/content/tr/processes.md b/content/tr/processes.md new file mode 100644 index 000000000..cefa6e703 --- /dev/null +++ b/content/tr/processes.md @@ -0,0 +1,14 @@ +## VI. Süreç +### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma + +Uygulama bir veya birden fazla *süreç* olarak çalıştırma ortamında çalıştırılır. + +En basit senaryoda, kod bağımsız bir betiktir, çalışma ortamı, dil çalışma zamanı yüklenmiş, geliştiricilerin yerel laptopudur ve süreç komut satırı aracılığıyla başlatılır (Örneğin, `python my_script.py`). Diğeri spekturumun sonunda, çok yönlü uygulamanın ürün dağıtımı birden fazla [süreç tipi kullanabilir, sıfır veya daha fazla çalışan süreci somutlaştırabilir](./concurrency). + +**On iki faktör süreçleri durumsuz ve [paylaşımsızdır](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Devamlılığa ihtiyaç duyan herhangi bir veri kapsamlı [destek servisinde](./backing-services) saklanmalıdır, genel olarak bir veri tabananında. + +Süreçlerin bellek uzayı ve dosya sistemi, kısa tek işlemli önbellek olarak kullanılabilir. Örneğin, büyük bir dosya indirirken, çalıştırırken, işlem sonuçlarını veri tabanında saklarken. On iki faktör uygulaması, bellek veya önbellekteki depolanmış hiçbir şeyin gelecekteki istek veya işlerde erişilebilir olacağını hiçbir zaman varsaymaz, çalışan her bir tipin bir çok süreciyle birlikte, gelecek isteğin farklı süreç tarafından sunulma şansı yüksektir. Sadece bir süreç çalıştırıldığında bile, tekrar başlatma (kod dağıtımı, yapılandırma değişikliği veya çalışma ortamı sürecin farklı fiziksel adrese tekrar yerleştirimi tarafından tetiklenir) genellikle bütün yerel (bellek ve dosya sistemi v.b gibi) durumları temizler. + +Varlık paketleyicileri ( [Jammit](http://documentcloud.github.com/jammit/) veya [django-compressor](http://django-compressor.readthedocs.org/) gibi), derlenmiş varlıklar için önbellek olarak dosya sistemi kullanılır. On iki faktör uygulaması [derleme aşaması](./build-release-run) boyunca, [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) gibi, bu derlemeyi yapmayı tercih eder, çalışma zamanında yapmaktansa. + +Bazı web sistemleri ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) dayanır, bu, kullanıcı oturum verisini uygulama sürecinin belleğinde saklar ve aynı sürece yönlendirilecek olan gelecek istekleri aynı ziyaretçiden bekler. Sticky sessions on iki faktörü ihlal eder ve asla kullanılmamalıdır veya buna güvenmemelidir. Oturum durum verisi [Memcached](http://memcached.org/) veya [Redis](http://redis.io/) gibi bitiş süresi öneren veri deposu için iyi bir adaydır. diff --git a/content/tr/toc.md b/content/tr/toc.md index b9fee8fd2..a5f5bc5c1 100644 --- a/content/tr/toc.md +++ b/content/tr/toc.md @@ -13,8 +13,8 @@ On İki Faktör ## [IV. Destek servisi](./backing-services) ### Destek servislerine ekli kaynak olarak davranma -## [V. Derleme, Sürüm, Çalışma](./build-release-run) -### Derleme ve çalışma aşamalarını tam olarak ayırma +## [V. Derleme, Sürüm, Çalıştırma](./build-release-run) +### Derleme ve çalıştırma aşamalarını tam olarak ayırma ## [VI. Süreç](./processes) ### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma From 33737e96c28f277798238ff3e651fa1069bb905a Mon Sep 17 00:00:00 2001 From: melikeyurtoglu Date: Tue, 28 Feb 2017 15:53:20 +0300 Subject: [PATCH 329/472] Turkish translation --- content/tr/config.md | 4 ++-- content/tr/dependencies.md | 2 +- content/tr/port-binding.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/tr/config.md b/content/tr/config.md index 903672072..37f39c1c7 100644 --- a/content/tr/config.md +++ b/content/tr/config.md @@ -13,10 +13,10 @@ Bir uygulamanın tüm yapılandırmaları koddan doğru bir biçimde çıkarıl Bu *yapılandırma* tanımlamasının, [Spring](http://spring.io/)'de [kod modullerinin bağlantısında](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) olduğu gibi ve Rails'de `config/routes.rb` gibi dahili uygulama yapılandırmasını **içermediğini** unutmayın. Bu tip yapılandırma dağıtımlar arasında değişiklik göstermez ve bu kod içinde en iyi şekilde gerçekleştirilmiştir. -Yapılandırmaya diğer bir yaklaşım Rails'deki `config/database.yml` gibi gözden geçirme kontrolünde kontrol edilmemiş yapılandırma dosyalarının kullanımıdır. Bu kod deposundaki kontrol edilmiş sabitlerin kullanımındaki büyük bir gelişmedir, fakat hala zayıflıkları vardır: Depoda, yapılandırma dosyalarının kontrolünde hata kolay yapılabilir; Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması için bir eğilim vardır, bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Bu formatların özel dil veya framework olma eğilimi vardır. +Yapılandırmaya diğer bir yaklaşım Rails'deki `config/database.yml` gibi gözden geçirme kontrolünde kontrol edilmemiş yapılandırma dosyalarının kullanımıdır. Bu kod deposundaki kontrol edilmiş sabitlerin kullanımındaki büyük bir gelişmedir, fakat hala zayıflıkları vardır: Depoda, yapılandırma dosyalarının kontrolünde hata kolay yapılabilir; Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması için bir eğilim vardır, bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Bu formatların özel dil veya çatı olma eğilimi vardır. **On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir**(sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunda yanlışlıkla kontrol edilme şansı az; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `üretim` ortamları gibi belirli dağıtımlardan sonra adlandırılmış, adlandrılmış guruplar içinde yapılandırılır(genellikle "environments" olarak adlandırılır). Bu method temiz bir ölçüm yapmaz: uygulamanın daha fazla dağıtımı oluştuğu sürece, yeni ortam isimleri gereklidir, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir, dağıtım yönetimini çok hassas yapan yapılandırmanın birleşimsel infilakıyla sonuçlanır. -On iki faktör uygulamasında ortam değişkenleri granular control'dür, her biri diğer ortam değişkenlerine karşı tamamen orthogonaldir. Asla "environments" olarak beraber gruplandırılamaz, fakat onun yerine her bir dağıtım için bağımsız yönetilir. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca büyüten bir modeldir. +On iki faktör uygulamasında ortam değişkenleri parçacıklı kontrol edilirler, her biri diğer ortam değişkenlerine karşı suffix/prefix olarak gelmez ayrı tanımlanır. Asla "environments" olarak beraber gruplandırılamaz, fakat onun yerine her bir dağıtım için bağımsız yönetilir. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca büyüten bir modeldir. diff --git a/content/tr/dependencies.md b/content/tr/dependencies.md index 05c5482f0..bd01e73e6 100644 --- a/content/tr/dependencies.md +++ b/content/tr/dependencies.md @@ -9,4 +9,4 @@ Açık bağımlılık bildiriminin bir faydası da uygulamaya yeni olan geliştiriciler için kurulumu kolaylaştırır. Yeni geliştirici geliştirme aracında uygulamanın kod tabanını kontrol edebilir, ön koşul olarak dil çalıştırma platformu ve bağımlılık yöneticisinin yüklenmiş olmasını ister. Rastgele olmayan *derleme komutları* ile birlikte uygulama kodunun çalışması için ihtiyaç duyulan her şeyi yükleyebilecekler. Örneğin, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) için `lein deps` iken, Ruby/Bundler için `bundle install`'dir. -On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. (bir cümle eksik). Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. +On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. Örnekler ImageMagick or `curl` kullanımını içerir. Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. diff --git a/content/tr/port-binding.md b/content/tr/port-binding.md index 294002371..f21bbbc28 100644 --- a/content/tr/port-binding.md +++ b/content/tr/port-binding.md @@ -5,7 +5,7 @@ Web uygulamaları bazı zamanlar web sunucu konteynırları içinde çalıştır **On iki faktör uygulama tamamen bağımsız** ve web dönüştürme servisi oluşturmak için çalışma ortamı içindeki web sunucunun çalışma zamanlı enjeksiyonuna dayanmaz. Bu web uygulaması port bağlama tarafından HTTP'yi servis olarak dışa aktarır ve o porta gelen istekleri dinler. -Yerel geliştirme ortamında, geliştiriciler `http://localhost:5000/` gibi servis URL'ini, onların duygulamaları tarafından dışa aktarılan servise erişmek için ziyaret ederler. Dağıtımda, yönlendirme katmanı public-facing makineadından port bağımlı web süreçlerine gelen yönlendirme isteklerini ele alır. +Yerel geliştirme ortamında, geliştiriciler `http://localhost:5000/` gibi servis URL'ini, onların duygulamaları tarafından dışa aktarılan servise erişmek için ziyaret ederler. Dağıtımda, yönlendirme katmanı dışa bakan makine adından port bağımlı web süreçlerine gelen yönlendirme isteklerini ele alır. Bu tipik olarak, uygulamaya web sunucusu kütüphanesi eklemek için bağımlılık tanımlaması kullanılarak geliştirilmiştir, Python için [Tornado](http://www.tornadoweb.org/), Ruby için [Thin](http://code.macournoyer.com/thin/) veya Java ve diğer JVM-tabanlı diller için [Jetty](http://jetty.codehaus.org/jetty/). Bu uygulamanın kodu içinde *kullanıcı alanında* gerçekleşir. Çalışma ortamıyla olan anlaşma isteklere hizmet veren bir porta bağlıdır. From b73786593ef61584c7964dbeb6887b275f95b99e Mon Sep 17 00:00:00 2001 From: melikeyurtoglu Date: Tue, 28 Feb 2017 16:01:56 +0300 Subject: [PATCH 330/472] create tr.yml Signed-off-by: melikeyurtoglu --- locales/tr.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/tr.yml diff --git a/locales/tr.yml b/locales/tr.yml new file mode 100644 index 000000000..cf9bd46d3 --- /dev/null +++ b/locales/tr.yml @@ -0,0 +1,7 @@ +tr: + # Name of language listed in locales menu + language: Turkish (tr) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. +translation: "Türkçe çeviri" From 41b6c3134c6129eef0c9542690b1fd93abb0058a Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Wed, 1 Mar 2017 12:46:06 +0200 Subject: [PATCH 331/472] fix tr.yml indentation --- locales/tr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/tr.yml b/locales/tr.yml index cf9bd46d3..ee1dbcd3e 100644 --- a/locales/tr.yml +++ b/locales/tr.yml @@ -4,4 +4,4 @@ tr: # A text to make known that the article is a translation not an original. # Empty for English, original. -translation: "Türkçe çeviri" + translation: "Türkçe çeviri" From 94ec0eeea663b50b21175ff11f260042d729cd3b Mon Sep 17 00:00:00 2001 From: Jon Mountjoy Date: Wed, 1 Mar 2017 12:47:20 +0200 Subject: [PATCH 332/472] add @melikeyurtoglu as a translator --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 394435735..b32af74c2 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: [@sigerello](https://github.com/sigerello), [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott) and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: [@sigerello](https://github.com/sigerello), [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott), [@melikeyurtoglu](https://github.com/melikeyurtoglu) and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: http://www.opensource.org/licenses/mit-license.php From 7031f8f094d6bdc5e85f61b2063f0febe2002523 Mon Sep 17 00:00:00 2001 From: Sangkon Han Date: Tue, 14 Mar 2017 14:43:15 +0900 Subject: [PATCH 333/472] Fix link to Korean --- content/ko/codebase.md | 2 +- content/ko/concurrency.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/codebase.md b/content/ko/codebase.md index 25942dabf..86461b7f9 100644 --- a/content/ko/codebase.md +++ b/content/ko/codebase.md @@ -10,7 +10,7 @@ Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](https://www. 코드베이스와 앱 사이에는 항상 1대1 관계가 성립된다. * 코드베이스가 여러개 있는 경우, 앱이 아니라 분산 시스템으로 봐야한다. 분산 시스템의 개별 구성요소가 앱이 되며, 개별 앱이 Twelve-Factor를 따른다. -* 여러개 앱이 동일한 코드를 공유한다면 Twelve-Factor를 위반하는것이다. 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](/dependencies)로 관리한다. +* 여러개 앱이 동일한 코드를 공유한다면 Twelve-Factor를 위반하는것이다. 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](./dependencies)로 관리한다. 앱의 코드베이스는 한개여야 하지만, 앱 배포는 여러개가 될수 있다. *배포*는 앱의 실행중인 인스턴스를 가리킨다. 보통 운영 사이트와 여러 스테이징 사이트가 여기에 해당한다. 모든 개발자는 자신의 로컬 개발 환경에 실행되는 앱을 가지고 있는데, 이것 역시 하나의 배포로 볼 수 있다. diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md index 2603057f8..d16e24179 100644 --- a/content/ko/concurrency.md +++ b/content/ko/concurrency.md @@ -9,6 +9,6 @@ 이는 런타임 VM 내부의 쓰레드나 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. -프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](.processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. +프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](./processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [Upstart](http://upstart.ubuntu.com/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. From e580b6eaed67dac79217834d76cb1fc7b3084634 Mon Sep 17 00:00:00 2001 From: Sangkon Han Date: Tue, 14 Mar 2017 14:43:41 +0900 Subject: [PATCH 334/472] Fix typo error --- content/ko/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/disposability.md b/content/ko/disposability.md index cf64a9b2c..fc50abf84 100644 --- a/content/ko/disposability.md +++ b/content/ko/disposability.md @@ -5,7 +5,7 @@ 프로세스는 **시작 시간을 최소화**하도록 노력해야합니다. 이상적으로, 프로세스는 실행 커맨드가 실행된 뒤 몇 초만에 요청이나 작업을 받을 수 있도록 준비 됩니다. 짧은 실행 시간은 [릴리즈](./build-release-run) 작업과 확장(scale up)이 더 민첩하게 이루어질 수 있게 합니다. 또한 프로세스 매니저가 필요에 따라 쉽게 프로세스를 새로운 머신으로 프로세스를 옮길 수 있기 때문에 안정성도 높아집니다. -프로세스는 프로세스 매니저로부터 **[SIGTERM]((http://en.wikipedia.org/wiki/SIGTERM)) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다. ** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. +프로세스는 프로세스 매니저로부터 **[SIGTERM]((http://en.wikipedia.org/wiki/SIGTERM) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다. ** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](http://kr.github.com/beanstalkd/)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [idempotent](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. From add2fe47ba643aeb06cb916e5ae402c1dc004b6a Mon Sep 17 00:00:00 2001 From: Luca Falasco Date: Wed, 22 Mar 2017 11:08:57 +0100 Subject: [PATCH 335/472] fix webpage link not working --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index b32af74c2..804b36250 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ The Twelve-Factor App ===================== -Source for the content app running at: https://www.12factor.net/ +Source for the content app running at: https://12factor.net/ Development ----------- From d4602a2b1578a4d75394d4796c1d94148a24846b Mon Sep 17 00:00:00 2001 From: Pavel Voronin Date: Thu, 30 Mar 2017 00:36:05 +0300 Subject: [PATCH 336/472] Update dev-prod-parity.md Mistake fix --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index e2bad32e3..0d575f601 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -10,7 +10,7 @@ **Приложение двенадцати факторов спроектировано для [непрерывного развертывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: * Сделать различие во времени небольшим: разработчик может написать код, и он будет развёрнут через несколько часов или даже минут. -* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывание и наблюдет за его поведением во время работы приложения. +* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывании и наблюдет за его поведением во время работы приложения. * Сделать различия инструментов небольшими: держать окружение разработки и работы приложения максимально похожими. Резюмируя сказанное выше в таблицу: From 020d3443924612e37a1aa459188b540bd10445f7 Mon Sep 17 00:00:00 2001 From: Alexander Sokolov Date: Thu, 20 Apr 2017 07:50:30 +0300 Subject: [PATCH 337/472] Update disposability.md --- content/ru/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/disposability.md b/content/ru/disposability.md index 80af68412..1664e6c69 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -1,5 +1,5 @@ ## IX. Утилизируемость (Disposability) -### Максимизируйте надежность с помощью быстрого запуска и корректного завершение работы +### Максимизируйте надежность с помощью быстрого запуска и корректного завершения работы **[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановлены в любой момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. From c2fbcde977abdd1d42f1bf75ca8198981405f8ad Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 21:55:12 +0300 Subject: [PATCH 338/472] [RU] dev-prod-parity.md fix typo --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 0d575f601..894eccfe6 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -10,7 +10,7 @@ **Приложение двенадцати факторов спроектировано для [непрерывного развертывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: * Сделать различие во времени небольшим: разработчик может написать код, и он будет развёрнут через несколько часов или даже минут. -* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывании и наблюдет за его поведением во время работы приложения. +* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывании и наблюдает за его поведением во время работы приложения. * Сделать различия инструментов небольшими: держать окружение разработки и работы приложения максимально похожими. Резюмируя сказанное выше в таблицу: From fb391be08112308fd4f30dbdfea2f393728740ec Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:09:37 +0300 Subject: [PATCH 339/472] admin-processes.md fix yo --- content/ru/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/admin-processes.md b/content/ru/admin-processes.md index abe5579ff..6e317c094 100644 --- a/content/ru/admin-processes.md +++ b/content/ru/admin-processes.md @@ -4,11 +4,11 @@ [Формирование процессов](./concurrency) является некоторым набором процессов, которые необходимы для выполнения регулярных задач приложения (таких как обработка веб-запросов), когда оно исполняется. В дополнение к этому, разработчикам периодически необходимо выполнять разовые задачи администрирования и обслуживания приложения, такие как: * Запуск миграции базы данных (например `manage.py migrate` в Django, `rake db:migrate` в Rails). -* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путем запуска интерпретатора без каких-либо аргументов (например, `python` или `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). +* Запуск консоли (также известной как оболочка [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)), чтобы запустить произвольный код или проверить модели приложения с действующей базой данных. Большинство языков предоставляют REPL путём запуска интерпретатора без каких-либо аргументов (например, `python` или `perl`), а в некоторых случаях имеют отдельную команду (например `irb` в Ruby, `rails console` в Rails). * Запуск разовых скриптов, хранящихся в репозитории приложения (например, `php scripts/fix_bad_records.php`). Разовые процессы администрирования следует запускать в среде идентичной регулярным [длительным процессам](./processes) приложения. Они запускаются на уровне [релиза](./build-release-run), используя те же [кодовую базу](./codebase) и [конфигурацию](./config), как и любой другой процесс, выполняющий этот релиз. Код администрирования должен поставляться вместе с кодом приложения, чтобы избежать проблем синхронизации. Те же самые методы [изоляции зависимостей](./dependencies) должны быть использованы для всех типов процессов. Например, если веб-процесс Ruby использует команду `bundle exec thin start`, то для миграции базы данных следует использовать `bundle exec rake db:migrate`. Аналогичным образом для программы на Python с использованием Virtualenv следует использовать поставляемый `bin/python` как для запуска веб-сервера Tornado, так и для запуска любых `manage.py` процессов администрирования. -Методология двенадцати факторов отдаёт предпочтение языкам, которые предоставляют REPL оболочки из коробки, и которые позволяют легко выполнять разовые скрипты. В локальном развертывании разработчики выполняют разовый процесс администрирования с помощью консольной команды внутри каталога с приложением. В рабочем развертывании разработчики могут использовать ssh или другой механизм выполнения удаленной команды, предоставленный средой выполнения, для запуска такого процесса. +Методология двенадцати факторов отдаёт предпочтение языкам, которые предоставляют REPL оболочки из коробки, и которые позволяют легко выполнять разовые скрипты. В локальном развёртывании разработчики выполняют разовый процесс администрирования с помощью консольной команды внутри каталога с приложением. В рабочем развёртывании разработчики могут использовать ssh или другой механизм выполнения удалённой команды, предоставленный средой выполнения, для запуска такого процесса. From 8ce2e68a39969739b26526ca30507419efc446e0 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:09:51 +0300 Subject: [PATCH 340/472] backing-services.md fix yo --- content/ru/backing-services.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 68e53c205..48295ceca 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -5,10 +5,10 @@ Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (например, [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) и [Last.fm](http://www.last.fm/api)). -**Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развертывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. +**Код приложения двенадцати факторов не делает различий между локальными и сторонними сервисами.** Для приложения каждый из них является подключаемым ресурсом, доступным по URL-адресу или по другой паре расположение/учётные данные, хранящимися в [конфигурации](./config). Каждое [развёртывание](./codebase) приложения двенадцати факторов должно иметь возможность заменить локальную базу данных MySQL на любую управляемую третьей стороной (например [Amazon RDS](http://aws.amazon.com/rds/)) без каких либо изменений кода приложения. Аналогичным образом, локальный SMTP сервер может быть заменён сторонним (например Postmark) без изменения кода. В обоих случаях необходимо изменить только идентификатор ресурса в конфигурации. -Каждая различная сторонняя служба является *ресурсом*. Например, база данных MySQL является ресурсом, две базы данных MySQL (используются для фрагментации на уровне приложения) квалифицируются как два отдельных ресурса. Приложение двенадцати факторов считает эти базы данных *подключенными ресурсами*, что указывает на их слабое связывание с развертыванием, в котором они подключены. +Каждая различная сторонняя служба является *ресурсом*. Например, база данных MySQL является ресурсом, две базы данных MySQL (используются для фрагментации на уровне приложения) квалифицируются как два отдельных ресурса. Приложение двенадцати факторов считает эти базы данных *подключёнными ресурсами*, что указывает на их слабое связывание с развёртыванием, в котором они подключены. -Рабочее развёртывание приложения, подключенного к 4 сторонним сервисам. +Рабочее развёртывание приложения, подключённого к 4 сторонним сервисам. Ресурсы можно по необходимости подключать к развёртыванию и отключать от развёртывания. Например, если база данных приложения функционирует некорректно из-за аппаратных проблем, администратор может запустить новый сервер базы данных, восстановленный из последней резервной копии. Текущая рабочая база данных может быть отключена, а новая база данных подключена -- всё это без каких-либо изменений кода. From 9347f3bdc46cad64d4b2765ed0076476302f2328 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:07 +0300 Subject: [PATCH 341/472] build-release-run.md fix yo --- content/ru/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/build-release-run.md b/content/ru/build-release-run.md index 5c08d6993..7e8b4aafd 100644 --- a/content/ru/build-release-run.md +++ b/content/ru/build-release-run.md @@ -11,7 +11,7 @@ **Приложение двенадцати факторов использует строгое разделение между этапами сборки, релиза и выполнения.** Например, невозможно внести изменения в код во время выполнения, так как нет способа распространить эти изменения обратно на этап сборки. -Инструменты развертывания, как правило, представляют собой инструменты управления релизами, и что немаловажно, дают возможность отката к предыдущему релизу. Например инструмент развертывания [Capistrano](https://github.com/capistrano/capistrano/wiki) сохраняет релизы в подкаталогах каталога с именем `releases`, где текущий релиз является символической ссылкой на каталог текущего релиза. Команда Capistrano `rollback` даёт возможность быстро откатится к предыдущему релизу. +Инструменты развёртывания, как правило, представляют собой инструменты управления релизами, и что немаловажно, дают возможность отката к предыдущему релизу. Например инструмент развёртывания [Capistrano](https://github.com/capistrano/capistrano/wiki) сохраняет релизы в подкаталогах каталога с именем `releases`, где текущий релиз является символической ссылкой на каталог текущего релиза. Команда Capistrano `rollback` даёт возможность быстро откатится к предыдущему релизу. Каждый релиз должен иметь уникальный идентификатор, такой как отметка времени релиза (например `2015-04-06-15:42:17`) или увеличивающееся число (например `v100`). Релизы могут только добавляться и каждый релиз невозможно изменить после его создания. Любые изменения обязаны создавать новый релиз. From 9f5811c645ab0a81677b3241cbb6dc98123bfee8 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:17 +0300 Subject: [PATCH 342/472] codebase.md fix yo --- content/ru/codebase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ru/codebase.md b/content/ru/codebase.md index af31a3cf5..27c0e1641 100644 --- a/content/ru/codebase.md +++ b/content/ru/codebase.md @@ -1,5 +1,5 @@ ## I. Кодовая база -### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развертываний +### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развёртываний Приложение двенадцати факторов всегда отслеживается в системе контроля версий, такой как [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/) или [Subversion](http://subversion.apache.org/). Копия базы данных отслеживаемых версий называется *репозиторием кода (code repository)*, что часто сокращается до *code repo* или просто до *репозиторий (repo)* @@ -9,9 +9,9 @@ Всегда есть однозначное соответствие между кодовой базой и приложением: -* Если есть несколько кодовых баз, то это не приложение — это распределенная система. Каждый компонент в распределенной системе является приложением и каждый компонент может индивидуально соответствовать двенадцати факторам. +* Если есть несколько кодовых баз, то это не приложение — это распределённая система. Каждый компонент в распределённой системе является приложением и каждый компонент может индивидуально соответствовать двенадцати факторам. * Факт того, что несколько приложений совместно используют тот же самый код, является нарушением двенадцати факторов. Решением в данной ситуации является выделение общего кода в библиотеки, которые могут быть подключены через [менеджер зависимостей](./dependencies). Существует только одна кодовая база для каждого приложения, но может быть множество развёртываний одного и того же приложения. *Развёрнутым приложением (deploy)* является запущенный экземпляр приложения. Как правило, это рабочее развёртывание сайта и одно или несколько промежуточных развёртываний сайта. Кроме того каждый разработчик имеет копию приложения, запущенного в его локальном окружении разработки, каждая из которых также квалифицируется как развёрнутое приложение (deploy). -Кодовая база обязана быть единой для всех развёртываний, однако разные версии одной кодовой базы могут выполняться в каждом из развертываний. Например разработчик может иметь некоторые изменения которые еще не добавлены в промежуточное развёртывание; промежуточное развёртывание может иметь некоторые изменения, которые еще не добавлены в рабочее развёртывание. Однако, все эти развёртывания используют одну и ту же кодовую базу, таким образом можно их идентифицировать как разные развертывания одного и того же приложения. +Кодовая база обязана быть единой для всех развёртываний, однако разные версии одной кодовой базы могут выполняться в каждом из развёртываний. Например разработчик может иметь некоторые изменения которые ещё не добавлены в промежуточное развёртывание; промежуточное развёртывание может иметь некоторые изменения, которые ещё не добавлены в рабочее развёртывание. Однако, все эти развёртывания используют одну и ту же кодовую базу, таким образом можно их идентифицировать как разные развёртывания одного и того же приложения. From cd4a9a321589096aa245cb334c05fd50c986ca8c Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:27 +0300 Subject: [PATCH 343/472] concurrency.md fix yo --- content/ru/concurrency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index 226da62e4..a610cdfc8 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -1,7 +1,7 @@ ## VIII. Параллелизм ### Масштабируйте приложение с помощью процессов -Любая компьютерная программа после запуска представляет собой один или несколько работающих процессов. Исторически веб-приложения принимали различные формы выполнения процессов. К примеру, PHP-процессы выполнятся как дочерние процессы Apache и запускаются по требованию в необходимом для обслуживания поступивших запросов количестве. Java-процессы используют противоположный подход, JVM представляет собой один монолитный мета-процесс, который резервирует большой объем системных ресурсов (процессор и память) при запуске и управляет параллельностью внутри себя с помощью нитей исполнения (threads). В обоих случаях запущенные процессы лишь минимально видны для разработчика приложения. +Любая компьютерная программа после запуска представляет собой один или несколько работающих процессов. Исторически веб-приложения принимали различные формы выполнения процессов. К примеру, PHP-процессы выполнятся как дочерние процессы Apache и запускаются по требованию в необходимом для обслуживания поступивших запросов количестве. Java-процессы используют противоположный подход, JVM представляет собой один монолитный мета-процесс, который резервирует большой объём системных ресурсов (процессор и память) при запуске и управляет параллельностью внутри себя с помощью нитей исполнения (threads). В обоих случаях запущенные процессы лишь минимально видны для разработчика приложения. ![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) @@ -11,4 +11,4 @@ Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. -Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого они должны полагаться на менеджер процессов операционной системы (например, [Upstart](http://upstart.ubuntu.com/), распределенный менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. +Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого они должны полагаться на менеджер процессов операционной системы (например, [Upstart](http://upstart.ubuntu.com/), распределённый менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. From 12454aa39736fa3dca7d67c6a6dde3320d27b751 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:36 +0300 Subject: [PATCH 344/472] config.md fix yo --- content/ru/config.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/ru/config.md b/content/ru/config.md index 2a413ad94..ea216d36f 100644 --- a/content/ru/config.md +++ b/content/ru/config.md @@ -1,13 +1,13 @@ ## III. Конфигурация ### Сохраняйте конфигурацию в среде выполнения -*Конфигурация* приложения -- это все, что может меняться между [развёртываниями](./codebase) (среда разработки, промежуточное и рабочее развёртывание). Это включает в себя: +*Конфигурация* приложения -- это всё, что может меняться между [развёртываниями](./codebase) (среда разработки, промежуточное и рабочее развёртывание). Это включает в себя: * Идентификаторы подключения к ресурсам типа базы данных, кэш-памяти и другим [сторонним службам](./backing-services) * Регистрационные данные для подключения к внешним сервисам, например, к Amazon S3 или Twitter * Значения зависимые от среды развёртывания такие, как каноническое имя хоста -Иногда приложения хранят конфигурации как константы в коде. Это нарушение методологии двенадцати факторов, которая требует **строгого разделения конфигурации и кода**. Конфигурация может существенно различаться между развертываниями, код не должен различаться. +Иногда приложения хранят конфигурации как константы в коде. Это нарушение методологии двенадцати факторов, которая требует **строгого разделения конфигурации и кода**. Конфигурация может существенно различаться между развёртываниями, код не должен различаться. Лакмусовой бумажкой того, правильно ли разделены конфигурация и код приложения, является факт того, что кодовая база приложения может быть в любой момент открыта в свободный доступ без компрометации каких-либо приватных данных. @@ -15,8 +15,8 @@ Другим подходом к конфигурации является использование конфигурационных файлов, которые не сохраняются в систему контроля версия, например 'config/database.yml' в Rails. Это огромное улучшение перед использованием констант, которые сохраняются в коде, но по-прежнему и у этого метода есть недостатки: легко по ошибке сохранить конфигурационный файл в репозиторий; существует тенденция когда конфигурационные файлы разбросаны в разных местах и в разных форматах, из за этого становится трудно просматривать и управлять всеми настройками в одном месте. Кроме того форматы этих файлов, как правило, специфичны для конкретного языка или фреймворка. -**Приложение двенадцати факторов хранит конфигурацию в *переменных окружения*** (часто сокращается до *env vars* или *env*). Переменные окружения легко изменить между развертываниями, не изменяя код; в отличие от файлов конфигурации, менее вероятно случайно сохранить их в репозиторий кода; и в отличие от пользовательских конфигурационных файлов или других механизмов конфигурации, таких как Java System Properties, они являются независимым от языка и операционной системы стандартом. +**Приложение двенадцати факторов хранит конфигурацию в *переменных окружения*** (часто сокращается до *env vars* или *env*). Переменные окружения легко изменить между развёртываниями, не изменяя код; в отличие от файлов конфигурации, менее вероятно случайно сохранить их в репозиторий кода; и в отличие от пользовательских конфигурационных файлов или других механизмов конфигурации, таких как Java System Properties, они являются независимым от языка и операционной системы стандартом. -Другим подходом к управлению конфигурациями является группировка. Иногда приложения группируют конфигурации в именованные группы (часто называемые "окружениями") названые по названию конкретного развертывания, например как `development`, `test` и `production` окружения в Rails. Этот метод не является достаточно масштабируемым: чем больше различных развертываний приложения создается, тем больше новых имён окружений необходимо, например `staging` и `qa`. При дальнейшем росте проекта, разработчики могут добавлять свои собственные специальные окружения, такие как `joes-staging`, в результате происходит комбинаторный взрыв конфигураций, который делает управление развертываниями приложения очень хрупким. +Другим подходом к управлению конфигурациями является группировка. Иногда приложения группируют конфигурации в именованные группы (часто называемые "окружениями") названые по названию конкретного развёртывания, например как `development`, `test` и `production` окружения в Rails. Этот метод не является достаточно масштабируемым: чем больше различных развёртываний приложения создаётся, тем больше новых имён окружений необходимо, например `staging` и `qa`. При дальнейшем росте проекта, разработчики могут добавлять свои собственные специальные окружения, такие как `joes-staging`, в результате происходит комбинаторный взрыв конфигураций, который делает управление развёртываниями приложения очень хрупким. -В приложении двенадцати факторов переменные окружения являются не связанными между собой средствами управления, где каждая переменная окружения полностью независима от других. Они никогда не группируются вместе в "окружения", а вместо этого управляются независимо для каждого развертывания. Эта модель которая масштабируется постепенно вместе с естественным появлением большего количества развёртываний приложения за время его жизни. +В приложении двенадцати факторов переменные окружения являются не связанными между собой средствами управления, где каждая переменная окружения полностью независима от других. Они никогда не группируются вместе в "окружения", а вместо этого управляются независимо для каждого развёртывания. Эта модель которая масштабируется постепенно вместе с естественным появлением большего количества развёртываний приложения за время его жизни. From ec4a222180ea6fb373e935200730c2b5a6bc17ca Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:48 +0300 Subject: [PATCH 345/472] dependencies.md fix yo --- content/ru/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dependencies.md b/content/ru/dependencies.md index a3149840d..caffb63d3 100644 --- a/content/ru/dependencies.md +++ b/content/ru/dependencies.md @@ -9,4 +9,4 @@ Одним из преимуществ явного объявления зависимостей является то, что это упрощает настройку приложения для новых разработчиков. Новый разработчик может скопировать кодовую базу приложения на свою машину, необходимыми требованиями для которой являются только наличие среды выполнения языка и менеджера пакетов. Всё необходимое для запуска кода приложения может быть настроено с помощью определённой *команды настройки*. Например, для Ruby/Bundler командой настройки является `bundle install`, для Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) это `lein deps`. -Приложение двенадцати факторов также не полагается на неявное существование любых инструментов системы. Примером является запуск программ ImageMagick и `curl`. Хотя эти инструменты могут присутствовать во многих или даже в большинстве систем, нет никакой гарантии, что они будут присутствовать на всех системах, где приложение может работать в будущем, или будет ли версия найденная в другой системе совместима с приложением. Если приложению необходимо запустить инструмент системы, то этот инструмент должен быть включен в приложение. +Приложение двенадцати факторов также не полагается на неявное существование любых инструментов системы. Примером является запуск программ ImageMagick и `curl`. Хотя эти инструменты могут присутствовать во многих или даже в большинстве систем, нет никакой гарантии, что они будут присутствовать на всех системах, где приложение может работать в будущем, или будет ли версия найденная в другой системе совместима с приложением. Если приложению необходимо запустить инструмент системы, то этот инструмент должен быть включён в приложение. From 470e036d1b6ea9ed915cc8a8b1dc5b2d80a50032 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:10:58 +0300 Subject: [PATCH 346/472] dev-prod-parity.md fix yo --- content/ru/dev-prod-parity.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 894eccfe6..50b61bd9d 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -1,16 +1,16 @@ ## X. Паритет разработки/работы приложения ### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими -Исторически существуют значительные различия между разработкой (разработчик делает живые изменения на локальном [развёртывании](./codebase) приложения) и работой приложения (развёртывание приложения с доступом к нему конечных пользователей). Эти различия проявляются в трех областях: +Исторически существуют значительные различия между разработкой (разработчик делает живые изменения на локальном [развёртывании](./codebase) приложения) и работой приложения (развёртывание приложения с доступом к нему конечных пользователей). Эти различия проявляются в трёх областях: * **Различие во времени:** разработчик может работать с кодом, который попадёт в рабочую версию приложения только через дни, недели или даже месяцы. * **Различие персонала**: разработчики пишут код, OPS инженеры разворачивают его. -* **Различие инструментов**: разработчики могут использовать стек технологий, такой как Nginx, SQLite, и OS X, в то время как при рабочем развертывании используются Apache, MySQL и Linux. +* **Различие инструментов**: разработчики могут использовать стек технологий, такой как Nginx, SQLite, и OS X, в то время как при рабочем развёртывании используются Apache, MySQL и Linux. -**Приложение двенадцати факторов спроектировано для [непрерывного развертывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: +**Приложение двенадцати факторов спроектировано для [непрерывного развёртывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: * Сделать различие во времени небольшим: разработчик может написать код, и он будет развёрнут через несколько часов или даже минут. -* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развертывании и наблюдает за его поведением во время работы приложения. +* Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развёртывании и наблюдает за его поведением во время работы приложения. * Сделать различия инструментов небольшими: держать окружение разработки и работы приложения максимально похожими. Резюмируя сказанное выше в таблицу: @@ -67,9 +67,9 @@ -Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьезные и надежные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кэширования при разработке и Memcached в рабочем окружении. +Иногда разработчики находят удобным использовать лёгкие сторонние службы в их локальном окружении, в то время как более серьёзные и надёжные сторонние сервисы будут использованы в рабочем окружении. Например используют SQLite локально и PostgreSQL в рабочем окружении; или память процесса для кэширования при разработке и Memcached в рабочем окружении. -**Разработчик приложения двенадцати факторов сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за все время существования приложения. +**Разработчик приложения двенадцати факторов сопротивляется искушению использовать различные сторонние сервисы при разработке и в рабочем окружении**, даже когда адаптеры теоретически абстрагированы от различий в сторонних сервисах. Различия в используемых сторонних сервисах означают, что может возникнуть крошечная несовместимость, которая станет причиной того, что код, который работал и прошёл тесты при разработке и промежуточном развёртывании не работает в рабочем окружении. Такой тип ошибок создаёт помехи, которые нивелируют преимущества непрерывного развёртывания. Стоимость этих помех и последующего восстановления непрерывного развёртывания является чрезвычайно высокой, если рассматривать в совокупности за всё время существования приложения. Установка локальных сервисов стала менее непреодолимой задачей, чем она когда-то была. Современные сторонние сервисы, такие как Memcached, PostgreSQL и RabbitMQ не трудно установить и запустить благодаря современным менеджерам пакетов, таким как [Homebrew](http://mxcl.github.com/homebrew/) и [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Кроме того, декларативные инструменты подготовки окружения, такие как [Chef](http://www.opscode.com/chef/) и [Puppet](http://docs.puppetlabs.com/) в сочетании с легковесным виртуальным окружением, таким как [Vagrant](http://vagrantup.com/) позволяют разработчикам запустить локальное окружение которое максимально приближено к рабочему окружению. Стоимость установки и использования этих систем ниже по сравнению с выгодой, получаемой от паритета разработки/работы приложения и непрерывного развёртывания. From 694d1b88abf7e02d7b1552b72f44aaa82cee936d Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:10 +0300 Subject: [PATCH 347/472] disposability.md fix yo --- content/ru/disposability.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/ru/disposability.md b/content/ru/disposability.md index 1664e6c69..60aa9cb39 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -1,12 +1,12 @@ ## IX. Утилизируемость (Disposability) -### Максимизируйте надежность с помощью быстрого запуска и корректного завершения работы +### Максимизируйте надёжность с помощью быстрого запуска и корректного завершения работы -**[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановлены в любой момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надежности рабочего развёртывания. +**[Процессы](./processes) приложения двенадцати факторов являются *утилизируемыми*, это означает, что они могут быть запущены и остановлены в любой момент.** Это способствует стабильному и гибкому масштабированию, быстрому развёртыванию изменений [кода](./codebase) и [конфигураций](./config) и надёжности рабочего развёртывания. -Процессы должны стараться **минимизировать время запуска**. В идеале процесс должен затратить всего несколько секунд от момента времени, когда выполнена команда запуска, и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет большую гибкость для [релиза](./build-release-run) и масштабирования. Кроме того, это более надежно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. +Процессы должны стараться **минимизировать время запуска**. В идеале процесс должен затратить всего несколько секунд от момента времени, когда выполнена команда запуска, и до того момента, когда процесс запущен и готов принимать запросы или задачи. Короткое время запуска предоставляет большую гибкость для [релиза](./build-release-run) и масштабирования. Кроме того, это более надёжно, так как менеджер процессов может свободно перемещать процессы на новые физические машины при необходимости. -Процессы должны **завершаться корректно, когда они получают [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал от диспетчера процессов. Для веб-процесса корректное завершение работы достигается путем прекращения прослушивания порта сервиса (таким образом, отказаться от каких-либо новых запросов), что позволяет завершить текущие запросы и затем завершиться. В этой модели подразумевается, что HTTP-запросы короткие (не более чем на несколько секунд), в случае длинных запросов клиент должен плавно попытаться восстановить подключение при потере соединения. +Процессы должны **завершаться корректно, когда они получают [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал от диспетчера процессов. Для веб-процесса корректное завершение работы достигается путём прекращения прослушивания порта сервиса (таким образом, отказаться от каких-либо новых запросов), что позволяет завершить текущие запросы и затем завершиться. В этой модели подразумевается, что HTTP-запросы короткие (не более чем на несколько секунд), в случае длинных запросов клиент должен плавно попытаться восстановить подключение при потере соединения. -Для процесса, выполняющего фоновые задачи (worker), корректное завершение работы достигается путем возвращения текущей задачи назад в очередь задач. Например, в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках такие, как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путем оборачивания результатов работы в транзакции или путем использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. +Для процесса, выполняющего фоновые задачи (worker), корректное завершение работы достигается путём возвращения текущей задачи назад в очередь задач. Например, в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках такие, как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путём оборачивания результатов работы в транзакции или путём использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. -Процессы также должны быть **устойчивыми к внезапной смерти** в случае отказа аппаратного обеспечения. Хотя это менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно все же может случиться. Рекомендуемым подходом является использование надежных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и неизящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). +Процессы также должны быть **устойчивыми к внезапной смерти** в случае отказа аппаратного обеспечения. Хотя это менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно всё же может случиться. Рекомендуемым подходом является использование надёжных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и неизящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). From 5a7b600a60872a3e0005717000acee983676ed7e Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:17 +0300 Subject: [PATCH 348/472] intro.md fix yo --- content/ru/intro.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ru/intro.md b/content/ru/intro.md index 0fcb1d772..ea294f3bb 100644 --- a/content/ru/intro.md +++ b/content/ru/intro.md @@ -3,10 +3,10 @@ В наши дни программное обеспечение обычно распространяется в виде сервисов, называемых *веб-приложения* (web apps) или *software-as-a-service* (SaaS). Приложение двенадцати факторов — это методология для создания SaaS-приложений, которые: -* Используют **декларативный** формат для описания процесса установки и настройки, что сводит к минимуму затраты времени и ресурсов для новых разработчиков, подключенных к проекту; +* Используют **декларативный** формат для описания процесса установки и настройки, что сводит к минимуму затраты времени и ресурсов для новых разработчиков, подключённых к проекту; * Имеют **соглашение** с операционной системой, предполагающее **максимальную переносимость** между средами выполнения; -* Подходят для **развертывания** на современных **облачных платформах**, устраняя необходимость в серверах и системном администрировании; -* **Сводят к минимуму расхождения** между средой разработки и средой выполнения, что позволяет использовать **непрерывное развертывание** (continuous deployment) для максимальной гибкости; +* Подходят для **развёртывания** на современных **облачных платформах**, устраняя необходимость в серверах и системном администрировании; +* **Сводят к минимуму расхождения** между средой разработки и средой выполнения, что позволяет использовать **непрерывное развёртывание** (continuous deployment) для максимальной гибкости; * И могут **масштабироваться** без существенных изменений в инструментах, архитектуре и практике разработки. Методология двенадцати факторов может быть применена для приложений, написанных на любом языке программирования и использующих любые комбинации сторонних служб (backing services) (базы данных, очереди сообщений, кэш-памяти, и т.д.). From 56b1b8f272a3915a9e53c8e2fc450db60a2ffe7a Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:25 +0300 Subject: [PATCH 349/472] logs.md fix yo --- content/ru/logs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/logs.md b/content/ru/logs.md index b7b955f46..273ed4320 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -7,10 +7,10 @@ **Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий без буферизации в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. -При промежуточном и рабочем развертывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. +При промежуточном и рабочем развёртывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. Поток событий приложения может быть перенаправлен в файл или просматриваться в терминале в режиме реального времени. Наиболее значимым является то, что поток событий может быть направлен в систему индексирования и анализа журналов, такую как [Splunk](http://www.splunk.com/), или систему хранения данных общего назначения, такую как [Hadoop/Hive](http://hive.apache.org/). Эти системы обладают большими возможностями и гибкостью для досконального анализа поведения приложение в течении времени, что включает в себя: * Поиск конкретных событий в прошлом. * Крупномасштабные графики трендов (например, запросов в минуту). -* Активные оповещения согласно эвристическим правилам, определяемых пользователем (например, оповещение, когда количество ошибок в минуту превышает определенный порог). +* Активные оповещения согласно эвристическим правилам, определяемых пользователем (например, оповещение, когда количество ошибок в минуту превышает определённый порог). From 1824498d5de93794478f478c7f41b5ea804df1fe Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:35 +0300 Subject: [PATCH 350/472] port-binding.md fix yo --- content/ru/port-binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/port-binding.md b/content/ru/port-binding.md index 0ce9490a8..2bd64d0a3 100644 --- a/content/ru/port-binding.md +++ b/content/ru/port-binding.md @@ -3,9 +3,9 @@ Иногда веб-приложения запускают внутри контейнера веб-сервера. Например, PHP-приложение может быть запущено как модуль внутри [Apache HTTPD](http://httpd.apache.org/), или Java-приложение может быть запущено внутри [Tomcat](http://tomcat.apache.org/). -**Приложение двенадцати факторов является полностью самодостаточным** и не полагается на инъекцию веб-сервера во время выполнения для того, чтобы создать веб-сервис. Веб-приложение **экспортирует HTTP-сервис путем привязки к порту** и прослушивает запросы, поступающих на этот порт. +**Приложение двенадцати факторов является полностью самодостаточным** и не полагается на инъекцию веб-сервера во время выполнения для того, чтобы создать веб-сервис. Веб-приложение **экспортирует HTTP-сервис путём привязки к порту** и прослушивает запросы, поступающих на этот порт. -Во время локальной разработки разработчик переходит по URL-адресу вида `http://localhost:5000/`, чтобы получить доступ к сервису, предоставляемым его приложением. При развертывании слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. +Во время локальной разработки разработчик переходит по URL-адресу вида `http://localhost:5000/`, чтобы получить доступ к сервису, предоставляемым его приложением. При развёртывании слой маршрутизации обрабатывает запросы к общедоступному хосту и перенаправляет их к привязанному к порту веб приложению. Это обычно реализуется с помощью [объявления зависимости](./dependencies) для добавления библиотеки веб-сервера к приложению такой, как [Tornado](http://www.tornadoweb.org/) в Python, [Thin](http://code.macournoyer.com/thin/) в Ruby, и [Jetty](http://www.eclipse.org/jetty/) в Java и других языках на основе JVM. Это происходит полностью в *пространстве пользователя*, то есть в коде приложения. Контрактом со средой исполнения является привязка приложения к порту для обработки запросов. From 0931e1c8de90b2d16dd323535a192261ed4448d4 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:46 +0300 Subject: [PATCH 351/472] processes.md fix yo --- content/ru/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/processes.md b/content/ru/processes.md index 6274dc21b..605c79837 100644 --- a/content/ru/processes.md +++ b/content/ru/processes.md @@ -7,7 +7,7 @@ **Процессы приложения двенадцати факторов не сохраняют внутреннее состояние (stateless) и [не имеют разделяемых данных (share-nothing)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Любые данные, которые требуется сохранить, должны быть сохранены в хранящей состояние [сторонней службе](./backing-services), обычно, в базе данных. -Память и файловая система процесса может быть использована в качестве временного кэша для одной транзакции. Например, загрузка, обработка и сохранение большого файла в базе данных. Приложение двенадцати факторов не предполагает, что что-либо закэшированное в памяти или на диске будет доступно следующим запросам или задачам -- с большим количеством разноплановых процессов высока вероятность, что следующий запрос будет обработан другим процессом. Даже с одним запущенным процессом перезапуск (вызванный развёртыванием, изменением конфигураций или переносом процесса на другое физическое устройство) приведет к уничтожению всех локальных (памяти, файловой системы) состояний. +Память и файловая система процесса может быть использована в качестве временного кэша для одной транзакции. Например, загрузка, обработка и сохранение большого файла в базе данных. Приложение двенадцати факторов не предполагает, что что-либо закэшированное в памяти или на диске будет доступно следующим запросам или задачам -- с большим количеством разноплановых процессов высока вероятность, что следующий запрос будет обработан другим процессом. Даже с одним запущенным процессом перезапуск (вызванный развёртыванием, изменением конфигураций или переносом процесса на другое физическое устройство) приведёт к уничтожению всех локальных (памяти, файловой системы) состояний. Упаковщики ресурсов (asset) (например, [Jammit](http://documentcloud.github.com/jammit/) или [django-compressor](http://django-compressor.readthedocs.org/)) используют файловую систему как кэш для скомпилированных ресурсов. Приложение двенадцати факторов предпочитает делать данную компиляцию во время [этапа сборки](./build-release-run), например, как в [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), а не во время выполнения. From d580785e5848bb79c423c04f1c723f495228e6d6 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Apr 2017 22:11:53 +0300 Subject: [PATCH 352/472] toc.md fix yo --- content/ru/toc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ru/toc.md b/content/ru/toc.md index 8e07f6436..000928d58 100644 --- a/content/ru/toc.md +++ b/content/ru/toc.md @@ -2,7 +2,7 @@ ================== ## [I. Кодовая база](./codebase) -### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развертываний +### Одна кодовая база, отслеживаемая в системе контроля версий, -- множество развёртываний ## [II. Зависимости](./dependencies) ### Явно объявляйте и изолируйте зависимости @@ -26,7 +26,7 @@ ### Масштабируйте приложение с помощью процессов ## [IX. Утилизируемость (Disposability)](./disposability) -### Максимизируйте надежность с помощью быстрого запуска и корректного завершения работы +### Максимизируйте надёжность с помощью быстрого запуска и корректного завершения работы ## [X. Паритет разработки/работы приложения](./dev-prod-parity) ### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими From 7bd4e3a97136276cbf085752f3fe39603b2b5613 Mon Sep 17 00:00:00 2001 From: Alexander Sokolov Date: Fri, 21 Apr 2017 08:55:35 +0300 Subject: [PATCH 353/472] Update dev-prod-parity.md --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 50b61bd9d..1590bf7c7 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -38,7 +38,7 @@ -[Сторонние службы](./backing-services), такие как базы данных, системы очередей сообщений и кэш, является одной из областей, где паритет при разработке и работе приложения имеет важное значение. Многие языки предоставляют библиотеки, которые упрощают доступ к сторонним службам, включая *адаптеры* для доступа к различных типам сервисов. Некоторые примеры, в таблице ниже. +[Сторонние службы](./backing-services), такие как базы данных, системы очередей сообщений и кэш, являются одной из областей, где паритет при разработке и работе приложения имеет важное значение. Многие языки предоставляют библиотеки, которые упрощают доступ к сторонним службам, включая *адаптеры* для доступа к различных типам сервисов. Некоторые примеры, в таблице ниже. From fca2e4bcb84244b886c6a262ec5510d78006ba43 Mon Sep 17 00:00:00 2001 From: Neri Junior Date: Sat, 22 Apr 2017 15:18:04 -0300 Subject: [PATCH 354/472] Fix pt-BR error in processes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Plural problem - Letters order incorrect at word “cantidato” --- content/pt_br/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/processes.md b/content/pt_br/processes.md index 217f644b5..39a472f00 100644 --- a/content/pt_br/processes.md +++ b/content/pt_br/processes.md @@ -11,4 +11,4 @@ O espaço de memória ou sistema de arquivos do processo pode ser usado como um Empacotadores de assets (como [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) usa o sistema de arquivos como um cache para assets compilados. Uma aplicação doze-fatores prefere fazer isto compilando durante a [fase de build](./build-release-run), tal como o [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), do que em tempo de execução. -Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuário na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão é um bom canditado para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). +Alguns sistemas web dependem de ["sessões persistentes"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- ou seja, fazem cache dos dados da sessão do usuário na memória do processo da aplicação, esperando futuras requisições do mesmo visitante para serem encaminhadas para o mesmo processo. Sessões persistentes são uma violação do doze-fatores e nunca devem ser utilizadas ou invocadas. Dados do estado da sessão são bons candidatos para um datastore que oferece tempo de expiração, tal como [Memcached](http://memcached.org/) ou [Redis](http://redis.io/). From 9b651a95a53bcba01bd06617fd44f50c54f64650 Mon Sep 17 00:00:00 2001 From: Dan Brubaker Horst Date: Tue, 9 May 2017 09:30:19 -0400 Subject: [PATCH 355/472] Updating URL to current format --- content/de/dev-prod-parity.md | 2 +- content/en/dev-prod-parity.md | 2 +- content/es/dev-prod-parity.md | 2 +- content/fr/dev-prod-parity.md | 2 +- content/it/dev-prod-parity.md | 2 +- content/ja/dev-prod-parity.md | 2 +- content/ko/dev-prod-parity.md | 2 +- content/pl/dev-prod-parity.md | 2 +- content/pt_br/dev-prod-parity.md | 2 +- content/ru/dev-prod-parity.md | 2 +- content/tr/dev-prod-parity.md | 2 +- content/uk/dev-prod-parity.md | 2 +- content/zh_cn/dev-prod-parity.md | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/content/de/dev-prod-parity.md b/content/de/dev-prod-parity.md index 6edaac5a6..bab87138a 100644 --- a/content/de/dev-prod-parity.md +++ b/content/de/dev-prod-parity.md @@ -7,7 +7,7 @@ Historisch gibt es große Lücken zwischen Entwicklung (wo ein Entwickler live a * **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://www.avc.com/a_vc/2011/02/continuous-deployment.html) indem sie die Lücke zwischen Entwicklung und Produktion klein hält.** Mit Blick auf die oben beschriebenen drei Lücken: +**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. diff --git a/content/en/dev-prod-parity.md b/content/en/dev-prod-parity.md index f6e573342..eb06e057a 100644 --- a/content/en/dev-prod-parity.md +++ b/content/en/dev-prod-parity.md @@ -7,7 +7,7 @@ Historically, there have been substantial gaps between development (a developer * **The personnel gap**: Developers write code, ops engineers deploy it. * **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. -**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: +**The twelve-factor app is designed for [continuous deployment](http://avc.com/2011/02/continuous-deployment/) by keeping the gap between development and production small.** Looking at the three gaps described above: * Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. * Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md index 7821774b9..a9900703e 100644 --- a/content/es/dev-prod-parity.md +++ b/content/es/dev-prod-parity.md @@ -7,7 +7,7 @@ Históricamente, han existido dos tipos de entorno muy diferenciados: desarrollo * **Diferencias de personal**: Los desarrolladores escriben el código y los ingenieros de operaciones lo despliegan. * **Diferencias de herramientas**: Los desarrolladores pueden usar una pila como Nginx, SQLite y OS X, mientras que en producción se usa Apache, MySQL y Linux. -** Las aplicaciones "twelve-factor" están diseñadas para hacer [despliegues continuos](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) que reducen las diferencias entre los entornos de desarrollo y producción.** Teniendo en cuenta las tres diferencias descritas anteriormente: +** Las aplicaciones "twelve-factor" están diseñadas para hacer [despliegues continuos](http://avc.com/2011/02/continuous-deployment/) que reducen las diferencias entre los entornos de desarrollo y producción.** Teniendo en cuenta las tres diferencias descritas anteriormente: * Reducir las diferencias de tiempo: Un desarrollador puede escribir código y tenerlo desplegado en tan solo unas horas, o incluso, minutos más tarde. * Reducir las diferencias de personal: Los desarrolladores que escriben el código están muy involucrados en el despliegue y observan su comportamiento en producción. diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index 1d9f85bbb..46db34050 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -7,7 +7,7 @@ Historiquement, il y a eu un fossé conséquent entre le développement (un dév * **Le fossé des personnes** : les développeurs écrivent le code, et d'autres personnes le déploient. * **Le fossé des outils** : les développeurs peuvent utiliser une pile comme Nginx, SQLite, et OS X, alors que le déploiement de production utilise Apache, MySQL, et Linux. -**Les applications 12 facteurs sont conçues pour le [déploiement continu (en)](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : +**Les applications 12 facteurs sont conçues pour le [déploiement continu (en)](http://avc.com/2011/02/continuous-deployment/) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : * Réduire le fossé temporel : un développeur peut écrire du code et le déployer quelques heures ou même juste quelques minutes plus tard. * Réduire le fossé des personnes : les personnes qui écrivent le code sont impliquées dans son déploiement et pour surveiller son comportement en production diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md index 94cd34ce1..a6fbd8b84 100644 --- a/content/it/dev-prod-parity.md +++ b/content/it/dev-prod-parity.md @@ -7,7 +7,7 @@ Storicamente, ci sono sempre state differenze sostanziali tra gli ambienti di sv * **Personale**: gli sviluppatori scrivono il codice, gli ops effettuano il deploy; * **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite ed OS X, mentre in produzione per il deploy verrebbero installati Apache, MySQL e Linux. -**Un'applicazione twelve-factor è progettata per il [rilascio continuo](http://www.avc.com/a_vc/2011/02/continuous-deployment.html), tenendo così queste differenze al minimo possibile.** A proposito di queste tre tipologie di differenze appena viste: +**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; diff --git a/content/ja/dev-prod-parity.md b/content/ja/dev-prod-parity.md index eda082101..cb92cd03c 100644 --- a/content/ja/dev-prod-parity.md +++ b/content/ja/dev-prod-parity.md @@ -7,7 +7,7 @@ * **人材のギャップ**: 開発者が書いたコードを、インフラエンジニアがデプロイする。 * **ツールのギャップ**: 本番デプロイではApache、MySQL、Linuxを使うのに、開発者がNginx、SQLite、OS Xのようなスタックを使うことがある。 -**Twelve-Factor Appでは、[継続的デプロイ](http://www.avc.com/a_vc/2011/02/continuous-deployment.html)しやすいよう開発環境と本番環境のギャップを小さく保つ。** 上で述べた3つのギャップを見る。 +**Twelve-Factor Appでは、[継続的デプロイ](http://avc.com/2011/02/continuous-deployment/)しやすいよう開発環境と本番環境のギャップを小さく保つ。** 上で述べた3つのギャップを見る。 * 時間のギャップを小さくする: 開発者が書いたコードは数時間後、さらには数分後にはデプロイされる。 * 人材のギャップを小さくする: コードを書いた開発者はそのコードのデプロイに深く関わり、そのコードの本番環境での挙動をモニタリングする。 diff --git a/content/ko/dev-prod-parity.md b/content/ko/dev-prod-parity.md index 0fb1be33a..531644e9d 100644 --- a/content/ko/dev-prod-parity.md +++ b/content/ko/dev-prod-parity.md @@ -7,7 +7,7 @@ * **담당자의 차이**: 개발자는 작성한 코드를 시스템 엔지니어가 배포합니다. * **툴의 차이**: production 배포는 아파치, MySQL, 리눅스를 사용하는데, 개발자는 Nginx, SQLite, OS X를 사용할 수 있습니다. -**Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://www.avc.com/a_vc/2011/02/continuous-deployment.html)가 가능하도록 디자인 되었습니다. 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. +**Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://avc.com/2011/02/continuous-deployment/)가 가능하도록 디자인 되었습니다. 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. * 시간의 차이을 최소화: 개발자가 작성한 코드는 몇 시간, 심지어 몇 분 후에 배포됩니다. * 담당자의 차이를 최소화: 코드를 작성한 개발자들이 배포와 production에서의 모니터링에 깊게 관여합니다. diff --git a/content/pl/dev-prod-parity.md b/content/pl/dev-prod-parity.md index c1d53da17..50e2234f4 100644 --- a/content/pl/dev-prod-parity.md +++ b/content/pl/dev-prod-parity.md @@ -7,7 +7,7 @@ Z doświadczenia wiadomo, że od zawsze istniały różnice pomiędzy środowisk * **Różnica odpowiedzialności**: Developer tworzy kod aplikacji, natomiast kto inny wdraża go do na produkcję. * **Różnica narzędzi**: Developer może używać narzędzi takich jak Nginx, SQLite i systemu OS X, natomiast wersja produkcyjna będzie opierać się na Apache, MySQL i systemie Linux. -**Aplikacja 12factor jest zaprojektowana tak by można ją było [bez przerwy wdrażać na produkcję](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) minimalizując różnice pomiędzy środowiskami.** Mając na uwadze powyższe różnice, można sobie z nimi radzić na różne sposoby: +**Aplikacja 12factor jest zaprojektowana tak by można ją było [bez przerwy wdrażać na produkcję](http://avc.com/2011/02/continuous-deployment/) minimalizując różnice pomiędzy środowiskami.** Mając na uwadze powyższe różnice, można sobie z nimi radzić na różne sposoby: * Zmniejsz czas deploymentu: czas wdrożenia kodu napisanego przez developera powinien być mierzony w godzinach, a nawet w minutach. * Przenieś odpowiedzialność: developer piszący kod powinien być zaangażowany we wdrożenia aplikacji na produkcję. diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index 945c4da82..946ddd9a3 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -7,7 +7,7 @@ Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvol * **A lacuna de pessoal:** Desenvolvedores escrevem código, engenheiros de operação fazem o deploy dele. * **A lacuna de ferramentas:** Desenvolvedores podem estar usando um conjunto como Nginx, SQLite, e OS X, enquanto o app em produção usa Apache, MySQL, e Linux. -**O App doze-fatores é projetado para [implantação contínua](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: +**O App doze-fatores é projetado para [implantação contínua](http://avc.com/2011/02/continuous-deployment/) deixando a lacuna entre desenvolvimento e produção pequena.** Olhando às três lacunas descritas acima: * Diminua a lacuna de tempo: um desenvolvedor pode escrever código e ter o deploy feito em horas ou até mesmo minutos depois. * Diminua a lacuna de pessoal: desenvolvedores que escrevem código estão proximamente envolvidos em realizar o deploy e acompanhar seu comportamento em produção. diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 1590bf7c7..3983385fa 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -7,7 +7,7 @@ * **Различие персонала**: разработчики пишут код, OPS инженеры разворачивают его. * **Различие инструментов**: разработчики могут использовать стек технологий, такой как Nginx, SQLite, и OS X, в то время как при рабочем развёртывании используются Apache, MySQL и Linux. -**Приложение двенадцати факторов спроектировано для [непрерывного развёртывания](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: +**Приложение двенадцати факторов спроектировано для [непрерывного развёртывания](http://avc.com/2011/02/continuous-deployment/) благодаря минимизации различий между разработкой и работой приложения. Рассмотрим три различия, описанных выше: * Сделать различие во времени небольшим: разработчик может написать код, и он будет развёрнут через несколько часов или даже минут. * Сделать небольшими различия персонала: разработчик который написал код, активно участвует в его развёртывании и наблюдает за его поведением во время работы приложения. diff --git a/content/tr/dev-prod-parity.md b/content/tr/dev-prod-parity.md index 46e868889..c20be1f2b 100644 --- a/content/tr/dev-prod-parity.md +++ b/content/tr/dev-prod-parity.md @@ -7,7 +7,7 @@ Tarihsel olarak, geliştirme (bir geliştirici uygulamanın yerel [dağıtımın * **Eleman aralığı:** Geliştiriciler kod yazar, ops mühendisleri dağıtır. * **Araçların aralığı:** Geliştiriciler ürün dağıtımı Apache, MySQL ve Linux kullanırken; Nginx, SQLite, ve OS X gibi yığınları kullanıyor olabilir. -**On iki faktör uygulaması, geliştirme ve ürün aralığını küçük tutarak, [sürekli dağıtım](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) için tasarlanmıştır.** Yukarda tanımlanan üç aralığa bakarsak: +**On iki faktör uygulaması, geliştirme ve ürün aralığını küçük tutarak, [sürekli dağıtım](http://avc.com/2011/02/continuous-deployment/) için tasarlanmıştır.** Yukarda tanımlanan üç aralığa bakarsak: * Zaman aralığını küçültme: bir geliştirici kod yazabilir ve bu kodu saatler veya hatta dakikalar sonra dağıtmış olabilir. * Eleman aralığını küçültme: kodu yazan geliştiriciler, kodu dağıtmakla yakından ilişkilidir ve üründeki davranışını izler. diff --git a/content/uk/dev-prod-parity.md b/content/uk/dev-prod-parity.md index a9a668302..d31c57991 100644 --- a/content/uk/dev-prod-parity.md +++ b/content/uk/dev-prod-parity.md @@ -7,7 +7,7 @@ * **Різниця в персоналі**: Розробники пишуть код, Ops-інженери розгортають його; * **Різниця в інструментах**: Розробники можуть використовувати стек технологій такий, як Nginx, SQLite та OS X, в той час як на production використовується Apache, MySQL та Linux. -**Застосунок дванадцяти факторів проектується для [безперервного розгортання](http://www.avc.com/a_vc/2011/02/continuous-deployment.html), завдяки мінімізації різниці між production і development середовищами.** Розглянемо три відмінності, описані вище: +**Застосунок дванадцяти факторів проектується для [безперервного розгортання](http://avc.com/2011/02/continuous-deployment/), завдяки мінімізації різниці між production і development середовищами.** Розглянемо три відмінності, описані вище: * Зменшити різницю в часі: розробник може написати код і він буде розгорнутий через декілька годин або навіть хвилин; * Зменшити різницю в персоналі: розробники, які писали код, беруть активну участь в його розгортанні і спостерігають за його поведінкою на production; diff --git a/content/zh_cn/dev-prod-parity.md b/content/zh_cn/dev-prod-parity.md index f7cf98c2a..70f668c7f 100644 --- a/content/zh_cn/dev-prod-parity.md +++ b/content/zh_cn/dev-prod-parity.md @@ -7,7 +7,7 @@ * **人员差异:** 开发人员编写代码,运维人员部署代码。 * **工具差异:** 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。 -**12-Factor 应用想要做到 [持续部署](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: +**12-Factor 应用想要做到 [持续部署](http://avc.com/2011/02/continuous-deployment/) 就必须缩小本地与线上差异。** 再回头看上面所描述的三个差异: * 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。 * 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。 From ddc2d2fe8d3307188e21abf636182fcf2f5950ff Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Mon, 17 Jul 2017 17:28:52 +0200 Subject: [PATCH 356/472] Update 'Last updated' date in footer --- views/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/layout.erb b/views/layout.erb index 643bd102e..b9ae5911a 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -38,7 +38,7 @@
<%= render_locales(@factor) %>
Written by Adam Wiggins
-
Last updated Jan 30, 2012
+
Last updated 2017
From 87b88d8350e39f7203c2f8fcd42dc3807f045588 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 19 Jul 2017 17:35:11 +0200 Subject: [PATCH 357/472] Add test section with an empty test for Heroku CI --- app.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index b59d77154..70e3f19a4 100644 --- a/app.json +++ b/app.json @@ -5,6 +5,12 @@ "env": { }, "addons": [ - - ] + ], + "environments": { + "test": { + "scripts": { + "test": "exit 0" + } + } + } } From 58e0bb9f7bafaf55c5b76f45a8bbc09edc4d1c1c Mon Sep 17 00:00:00 2001 From: James Mason Date: Tue, 8 Aug 2017 19:18:37 -0700 Subject: [PATCH 358/472] It's 2017: Replace unity with systemd The 'Concurrency' document references Ubuntu upstart as an example of an OS process manager, but Ubuntu has since replaced upstart with systemd[1], along with every other major Linux distribution[2]. Upstart has since become abandonware, with it's last stable release in 2014[3]. [1] https://lists.ubuntu.com/archives/ubuntu-devel-announce/2015-March/001130.html [2] https://en.wikipedia.org/wiki/Upstart#Adoption [3] http://upstart.ubuntu.com/ --- content/de/concurrency.md | 2 +- content/en/concurrency.md | 2 +- content/es/concurrency.md | 2 +- content/fr/concurrency.md | 2 +- content/it/concurrency.md | 2 +- content/ja/concurrency.md | 2 +- content/ko/concurrency.md | 2 +- content/pl/concurrency.md | 2 +- content/pt_br/concurrency.md | 2 +- content/ru/concurrency.md | 2 +- content/tr/concurrency.md | 2 +- content/uk/concurrency.md | 2 +- content/zh_cn/concurrency.md | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/content/de/concurrency.md b/content/de/concurrency.md index 2eba41db6..c5a76cc72 100644 --- a/content/de/concurrency.md +++ b/content/de/concurrency.md @@ -11,4 +11,4 @@ Dies hindert die einzelnen Prozesse nicht daran, ihr internes Multiplexing zu ve 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 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. +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 [systemd](https://www.freedesktop.org/wiki/Software/systemd/), 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/en/concurrency.md b/content/en/concurrency.md index 952778bcd..32c8dab02 100644 --- a/content/en/concurrency.md +++ b/content/en/concurrency.md @@ -11,4 +11,4 @@ This does not exclude individual processes from handling their own internal mult The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [systemd](https://www.freedesktop.org/wiki/Software/systemd/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/es/concurrency.md b/content/es/concurrency.md index 334c7d752..c1d0c7c96 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -11,4 +11,4 @@ Esto no exime a los procesos de gestionar su propia división interna mediante t El modelo de procesos muestra todo su potencial cuando llega el momento de escalar. La [naturaleza "share-nothing", divide horizontalmente los procesos de las aplicaciones "twelve-factor"](./processes) y se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *juego de procesos*. -Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) ni escribir ficheros de tipo PID. En su lugar, se debería confiar en un gestor de procesos del sistema operativo (como [Upstart](http://upstart.ubuntu.com/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [los historiales](./logs), responder a procesos que terminen inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. +Los procesos de las aplicaciones "twelve-factor" [nunca deberían ser demonios](http://dustin.github.com/2010/02/28/running-processes.html) ni escribir ficheros de tipo PID. En su lugar, se debería confiar en un gestor de procesos del sistema operativo (como [systemd](https://www.freedesktop.org/wiki/Software/systemd/), un gestor de procesos distribuido en una plataforma en la nube, o una herramienta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) en desarrollo) para gestionar [los historiales](./logs), responder a procesos que terminen inesperadamente, y gestionar los reinicios y apagados provocados por los usuarios. diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index 0b9123d8d..6d0081d8f 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -11,4 +11,4 @@ Chaque processus peut malgré tout et individuellement, gérer son propre multip Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et le nombre de processus de chaque type est appelée *formation de processus*. -Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. +Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[systemd](https://www.freedesktop.org/wiki/Software/systemd/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. diff --git a/content/it/concurrency.md b/content/it/concurrency.md index 79598ec21..727d83a8c 100644 --- a/content/it/concurrency.md +++ b/content/it/concurrency.md @@ -11,4 +11,4 @@ Questo non esclude che un certo processo, individualmente, possa gestire in modo Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice ed affidabile. L'array dei tipi di processo ed il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). -I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [Upstart](http://upstart.ubuntu.com/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. +I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [systemd](https://www.freedesktop.org/wiki/Software/systemd/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. diff --git a/content/ja/concurrency.md b/content/ja/concurrency.md index 8daf90366..be5755c1e 100644 --- a/content/ja/concurrency.md +++ b/content/ja/concurrency.md @@ -11,4 +11,4 @@ このプロセスモデルが真価を発揮するのは、スケールアウトが必要になったときである。[シェアードナッシングで水平分割可能なTwelve-Factor Appプロセスの性質](./processes)は、並行性を高める操作が単純かつ確実なものであることを意味する。プロセスタイプとそれぞれのタイプのプロセス数の配列は、 *プロセスフォーメーション* と言われる。 -Twelve-Factor Appのプロセスは[決してデーモン化するべきではないし](http://dustin.github.com/2010/02/28/running-processes.html)、PIDファイルを書き出すべきではない。その代わりに、OSのプロセスマネージャー(例:[Upstart](http://upstart.ubuntu.com/)、クラウドプラットフォームの分散プロセスマネージャー、あるいは開発環境における[Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)のようなツール)を頼ることで、[出力ストリーム](./logs)を管理し、プロセスのクラッシュに対応し、ユーザーによる再起動やシャットダウンを処理すべきである。 +Twelve-Factor Appのプロセスは[決してデーモン化するべきではないし](http://dustin.github.com/2010/02/28/running-processes.html)、PIDファイルを書き出すべきではない。その代わりに、OSのプロセスマネージャー(例:[systemd](https://www.freedesktop.org/wiki/Software/systemd/)、クラウドプラットフォームの分散プロセスマネージャー、あるいは開発環境における[Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)のようなツール)を頼ることで、[出力ストリーム](./logs)を管理し、プロセスのクラッシュに対応し、ユーザーによる再起動やシャットダウンを処理すべきである。 diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md index d16e24179..35b49e081 100644 --- a/content/ko/concurrency.md +++ b/content/ko/concurrency.md @@ -11,4 +11,4 @@ 프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](./processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. -Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [Upstart](http://upstart.ubuntu.com/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. +Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [systemd](https://www.freedesktop.org/wiki/Software/systemd/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. diff --git a/content/pl/concurrency.md b/content/pl/concurrency.md index 0a20d01d3..f30dcf955 100644 --- a/content/pl/concurrency.md +++ b/content/pl/concurrency.md @@ -11,4 +11,4 @@ Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku m Największa zaleta modelu procesów objawia się w momencie skalowania. [Niezależność oraz dzielenie się na podprocesy](./processes) umożliwia proste i bezproblemowe dodawanie wiekszej liczby równolegle działajacych procesów. Tablica typów procesów i liczba procesów nazywana jest ich *formacją*. -Procesy aplikacji 12factor [nigdy nie powinny być uruchamiane w tle](http://dustin.github.com/2010/02/28/running-processes.html) i nie mogą zapisywać plików PID. Zamiast tego opierają się na narzędziach systemu operacyjnego: do zarządzania procesami (np. [Upstart](http://upstart.ubuntu.com/), do zarządzania rozproszonymi procesami w chmurze, lub [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) w developmencie) do zarządzania [stumieniami wyjściowymi](./logs), do obsługi zatrzymanych procesów, restartu i zakończenia działań zainicjowanych przez użytkownika. +Procesy aplikacji 12factor [nigdy nie powinny być uruchamiane w tle](http://dustin.github.com/2010/02/28/running-processes.html) i nie mogą zapisywać plików PID. Zamiast tego opierają się na narzędziach systemu operacyjnego: do zarządzania procesami (np. [systemd](https://www.freedesktop.org/wiki/Software/systemd/), do zarządzania rozproszonymi procesami w chmurze, lub [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) w developmencie) do zarządzania [stumieniami wyjściowymi](./logs), do obsługi zatrzymanych procesów, restartu i zakończenia działań zainicjowanych przez użytkownika. diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index 8099c8574..c7b5b0a73 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -11,4 +11,4 @@ Isto não exclui processos individuais da manipulação de sua própria multiple O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação doze-fatores](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. -Processos de uma app doze-fatores [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [Upstart](http://upstart.ubuntu.com/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário. +Processos de uma app doze-fatores [nunca deveriam daemonizar](http://dustin.github.com/2010/02/28/running-processes.html) ou escrever arquivos PID. Em vez disso, confiar no gerente de processo do sistema operacional (como [systemd](https://www.freedesktop.org/wiki/Software/systemd/), um gerenciador de processos distribuídos em uma plataforma de nuvem, ou uma ferramenta como [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) em desenvolvimento) para gerenciar [fluxos de saída](./logs), responder a processos travados, e lidar com reinícios e desligamentos iniciados pelo usuário. diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index a610cdfc8..675c63bcd 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -11,4 +11,4 @@ Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. -Процессы приложения двенадцати факторов [никогда не должны демонизироваться](http://dustin.github.com/2010/02/28/running-processes.html) и записывать PID файлы. Вместо этого они должны полагаться на менеджер процессов операционной системы (например, [Upstart](http://upstart.ubuntu.com/), распределённый менеджер процессов на облачной платформе, или инструмент как [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) в процессе разработки) для управления [потоком вывода](./logs), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. +Процессы приложения двенадцати факторов [никогда не должны демонизироваться](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), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. diff --git a/content/tr/concurrency.md b/content/tr/concurrency.md index 1707ea635..972efde74 100644 --- a/content/tr/concurrency.md +++ b/content/tr/concurrency.md @@ -11,4 +11,4 @@ Bu, bireysel süreçlerin kendi dahili çoklu işlemelerini içermiyor değil, Bu süreç modeli, konu ölçeklendirme zamanına geldiğinde gerçekten çok başarılıdır. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama süreçleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir işlem olduğu anlamına gelir. Süreç tipleri dizisi ve her bir tipin süreçlerinin numarası *süreç oluşumu* olarak bilinir. -On iki faktör uygulama süreçleri [asla arka planda çalışmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyalarını yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş süreçlere cevap vermek, kullanıcı başlatımlı tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin süreç yöneticisine( [Upstart](http://upstart.ubuntu.com/) gibi bulut platformunda yayınlanmış süreç yöneticisi veya geliştirme sürecinde [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar ) dayanır. +On iki faktör uygulama süreçleri [asla arka planda çalışmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyalarını yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş süreçlere cevap vermek, kullanıcı başlatımlı tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin süreç yöneticisine( [systemd](https://www.freedesktop.org/wiki/Software/systemd/) gibi bulut platformunda yayınlanmış süreç yöneticisi veya geliştirme sürecinde [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar ) dayanır. diff --git a/content/uk/concurrency.md b/content/uk/concurrency.md index 8c67be772..e13f83b00 100644 --- a/content/uk/concurrency.md +++ b/content/uk/concurrency.md @@ -11,4 +11,4 @@ Модель, побудована на процесах, дійсно показує себе з найкращого боку, коли постає необхідність масштабування. [Відсутність розділених даних і горизонтальне розділення процесів застосунку дванадцяти факторів](./processes) означає, що додавання більшої конкурентності є простою і надійною операцією. Масив типів процесів і кількість процесів кожного типу називається *формацією процесів*. -Процеси застосунку дванадцяти факторів [ніколи не мають демонізуватися](http://dustin.github.com/2010/02/28/running-processes.html) та записувати PID-файли. Замість цього вони мають покладатися на менеджер процесів операційної системи (наприклад, [Upstart](http://upstart.ubuntu.com/), розподілений менеджер процесів на хмарній платформі, або в процесі розробки на такий інструмент, як [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)) для керування [потоком виведення](./logs), реагування на падіння процесів і обробку ініційованих користувачем перезавантаження чи завершення роботи. \ No newline at end of file +Процеси застосунку дванадцяти факторів [ніколи не мають демонізуватися](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), реагування на падіння процесів і обробку ініційованих користувачем перезавантаження чи завершення роботи. \ No newline at end of file diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index f3b0f7fee..89a5e4d4b 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -11,4 +11,4 @@ 上述进程模型会在系统急需扩展时大放异彩。 [12-Factor 应用的进程所具备的无共享,水平分区的特性](./processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 -12-Factor 应用的进程 [不需要守护进程](http://dustin.github.com/2010/02/28/running-processes.html) 或是写入 PID 文件。相反的,应该借助操作系统的进程管理器(例如 [Upstart](http://upstart.ubuntu.com/) ,分布式的进程管理云平台,或是类似 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 的工具),来管理 [输出流](/logs) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 +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) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 From a2b32f92718d7d152ffc9b9a866fb8fb8ef6dfc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0brahim=20ATAY?= Date: Wed, 16 Aug 2017 21:17:18 +0300 Subject: [PATCH 359/472] =?UTF-8?q?T=C3=BCrk=C3=A7e=20metin=20d=C3=BCzenle?= =?UTF-8?q?meleri=20yap=C4=B1ld=C4=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Bağımlılık Yönetimi" bölümünde bulunan ingilizce kalan "or" kelimesi "veya" olarak düzenlendi ve "Porta Bağlama" bölümünde bulunan "konteynırları" kelimesinin çevisinin "taşıyıcıları" olarak düzenlenmesi yapıldı. --- content/tr/dependencies.md | 2 +- content/tr/port-binding.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/tr/dependencies.md b/content/tr/dependencies.md index bd01e73e6..c85851f00 100644 --- a/content/tr/dependencies.md +++ b/content/tr/dependencies.md @@ -9,4 +9,4 @@ Açık bağımlılık bildiriminin bir faydası da uygulamaya yeni olan geliştiriciler için kurulumu kolaylaştırır. Yeni geliştirici geliştirme aracında uygulamanın kod tabanını kontrol edebilir, ön koşul olarak dil çalıştırma platformu ve bağımlılık yöneticisinin yüklenmiş olmasını ister. Rastgele olmayan *derleme komutları* ile birlikte uygulama kodunun çalışması için ihtiyaç duyulan her şeyi yükleyebilecekler. Örneğin, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) için `lein deps` iken, Ruby/Bundler için `bundle install`'dir. -On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. Örnekler ImageMagick or `curl` kullanımını içerir. Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. +On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. Örnekler `ImageMagick` yada `curl` kullanımını içerir. Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. diff --git a/content/tr/port-binding.md b/content/tr/port-binding.md index f21bbbc28..cf1cb1313 100644 --- a/content/tr/port-binding.md +++ b/content/tr/port-binding.md @@ -1,7 +1,7 @@ ## VII. Port Bağlama ### Port bağlama yolu üzerinden dışarı aktarma -Web uygulamaları bazı zamanlar web sunucu konteynırları içinde çalıştırılırlar. Örneğin, PHP uygulamaları modül olarak [Apache HTTPD](http://httpd.apache.org/) içinde veya Java uygulamaları [Tomcat](http://tomcat.apache.org/) içinde çalıştırılabilirler. +Web uygulamaları bazı zamanlar web sunucu taşıyıcıları içinde çalıştırılırlar. Örneğin, PHP uygulamaları modül olarak [Apache HTTPD](http://httpd.apache.org/) içinde veya Java uygulamaları [Tomcat](http://tomcat.apache.org/) içinde çalıştırılabilirler. **On iki faktör uygulama tamamen bağımsız** ve web dönüştürme servisi oluşturmak için çalışma ortamı içindeki web sunucunun çalışma zamanlı enjeksiyonuna dayanmaz. Bu web uygulaması port bağlama tarafından HTTP'yi servis olarak dışa aktarır ve o porta gelen istekleri dinler. From d6565a5f07c8cdf86167d32007f7748e36abe20b Mon Sep 17 00:00:00 2001 From: void Date: Thu, 17 Aug 2017 17:19:11 +0200 Subject: [PATCH 360/472] fixed typo in polish translation --- content/pl/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/codebase.md b/content/pl/codebase.md index 0217667d6..a0c59d8a8 100644 --- a/content/pl/codebase.md +++ b/content/pl/codebase.md @@ -10,7 +10,7 @@ Aplikacja 12factor zawsze jest zarządzana w systemie kontroli wersji takim jak Aplikacja powinna zawsze odzwierciedlać bazowy kod: * Jeśli istnieje wiele źródeł, z których pobierany jest kod, nie można mówić o aplikacji, a systemie rozproszonym. Każdy komponent w systemie rozproszonym będzie wtedy aplikacją i każdy z osobna może spełniać wszystkie zasady 12factor. -* Jeśli wiele aplikacji dzieli ten sami kod, mamy do czynienia z naruszeniem 12factor. Wyjściem z tej sytuacji może być wyizolowanie współdzielonego kodu do bibliotek, które będą dodane do aplikacji przez tzw. [dependency manager](./dependencies). +* Jeśli wiele aplikacji dzieli ten sam kod, mamy do czynienia z naruszeniem 12factor. Wyjściem z tej sytuacji może być wyizolowanie współdzielonego kodu do bibliotek, które będą dodane do aplikacji przez tzw. [dependency manager](./dependencies). Aplikacja może posiadać tylko jeden codebase, jednocześnie mając wiele wdrożeń. *Deploy* (z ang. wdrożenie) jest działającą instancją aplikacji. Zazwyczaj mówi się o wersji produkcyjnej i jednej lub więcej przedprodukcyjnych. Ponadto każdy developer pracujący nad aplikacją posiada jej kopię działającą w swoim lokalnym środowisku developerskim, co również kwalifikuje się jako osobne wdrożenie. From 1a478a195b77b47f46f6f0bb664660a9678cd87f Mon Sep 17 00:00:00 2001 From: void Date: Thu, 17 Aug 2017 17:25:31 +0200 Subject: [PATCH 361/472] fixed typo in polish translation --- content/pl/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/dependencies.md b/content/pl/dependencies.md index eec6b8aa1..93cb1ea12 100644 --- a/content/pl/dependencies.md +++ b/content/pl/dependencies.md @@ -5,7 +5,7 @@ Większość języków programowania oferuje narzędzia do dystrybucji dodatkowy **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ę zalenoż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. +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`. From de135835cccb2910e5f11d1b0ca954edeca0eb7d Mon Sep 17 00:00:00 2001 From: "COMMERCE21\\luke" Date: Fri, 18 Aug 2017 19:18:37 +0900 Subject: [PATCH 362/472] Fix typo error and improve Korean translation. --- content/ko/dev-prod-parity.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/content/ko/dev-prod-parity.md b/content/ko/dev-prod-parity.md index 531644e9d..1c4e952c8 100644 --- a/content/ko/dev-prod-parity.md +++ b/content/ko/dev-prod-parity.md @@ -4,17 +4,16 @@ 역사적으로, 개발 환경(애플리케이션의 개발자가 직접 수정하는 로컬의 [배포](./codebase))과 production 환경(최종 사용자가 접근하게 되는 실행 중인 배포) 사이에는 큰 차이가 있었습니다. 이러한 차이는 3가지 영역에 걸처 나타납니다. * **시간의 차이**: 개발자가 작업한 코드는 production에 반영되기까지 며칠, 몇주, 때로는 몇개월이 걸릴 수 있습니다. -* **담당자의 차이**: 개발자는 작성한 코드를 시스템 엔지니어가 배포합니다. +* **담당자의 차이**: 개발자가 작성한 코드를 시스템 엔지니어가 배포합니다. * **툴의 차이**: production 배포는 아파치, MySQL, 리눅스를 사용하는데, 개발자는 Nginx, SQLite, OS X를 사용할 수 있습니다. -**Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://avc.com/2011/02/continuous-deployment/)가 가능하도록 디자인 되었습니다. 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. +**Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://avc.com/2011/02/continuous-deployment/)가 가능하도록 디자인 되었습니다.** 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. * 시간의 차이을 최소화: 개발자가 작성한 코드는 몇 시간, 심지어 몇 분 후에 배포됩니다. * 담당자의 차이를 최소화: 코드를 작성한 개발자들이 배포와 production에서의 모니터링에 깊게 관여합니다. * 툴의 차이를 최소화: 개발과 production 환경을 최대한 비슷하게 유지합니다. 위의 내용을 표로 요약하면 아래와 같습니다. -Summarizing the above into a table:
@@ -40,32 +39,32 @@ Summarizing the above into a table:
-데이터베이스, 큐잉 시스템, 캐시와 같은 [백엔드 서비스](./backing-services)는 dev/prod 일치가 중요한 영역 중 하나 입니다. 많은 언어들은 다른 종류의 서비스에 대한 *어댑터*를 포함되어 있는 간단하게 백엔드 서비스에 접근할 수 있는 라이브러리들을 제공합니다. +데이터베이스, 큐잉 시스템, 캐시와 같은 [백엔드 서비스](./backing-services)는 dev/prod 일치가 중요한 영역 중 하나 입니다. 많은 언어들은 다른 종류의 서비스에 대한 *어댑터*를 포함하고 간단하게 백엔드 서비스에 접근할 수 있는 라이브러리들을 제공합니다. 아래의 표에 몇가지 예가 나와있습니다. - - - - + + + + - + - + - + - +
TypeLanguageLibraryAdapters종류언어라이브러리어댑터
Database데이터 베이스 Ruby/Rails ActiveRecord MySQL, PostgreSQL, SQLite
Queue큐(Queue) Python/Django Celery RabbitMQ, Beanstalkd, Redis
Cache캐쉬 Ruby/Rails ActiveSupport::CacheMemory, filesystem, Memcached메모리, 파일시스템, Memcached
From 66977a19ad9ef77a45c65735d754136d8b9dbbfe Mon Sep 17 00:00:00 2001 From: void Date: Fri, 18 Aug 2017 14:37:22 +0200 Subject: [PATCH 363/472] fixed typo in polish translation --- content/pl/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/processes.md b/content/pl/processes.md index c30b084fe..3f0dc2e18 100644 --- a/content/pl/processes.md +++ b/content/pl/processes.md @@ -3,7 +3,7 @@ Aplikacja jest uruchamiana w środowisku wykonawczym w postaci jednego lub kilku *procesów*. -W najprostszym przypadku kod aplikacji jest samodzielnym skryptem, środowiskiem wykonawczym jest laptop developera z wsparciem dla języka programowania a proces jest uruchamiany za pomocą linii komend (na przykład `python my_script.py`). Innym razem wdrożenie produkcyjne mocno rozwiniętej aplikacji może wymagać wiele [różnych rodzajów procesów](./concurrency). +W najprostszym przypadku kod aplikacji jest samodzielnym skryptem, środowiskiem wykonawczym jest laptop developera z wsparciem dla języka programowania, a proces jest uruchamiany za pomocą linii komend (na przykład `python my_script.py`). Innym razem wdrożenie produkcyjne mocno rozwiniętej aplikacji może wymagać wiele [różnych rodzajów procesów](./concurrency). **Wg zasad 12factor, procesy są bezstanowe i [nie-współdzielące](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Jakiekolwiek dane wymagające zapisu musza być zmagazynowane w "trwałej" [usłudze wspierającej](./backing-services), najczęściej będącą bazą danych. From 1847db71f5ec19da4e77a1abb66a10db4999d161 Mon Sep 17 00:00:00 2001 From: void Date: Fri, 18 Aug 2017 16:19:20 +0200 Subject: [PATCH 364/472] fixed typo in polish translation --- content/pl/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/disposability.md b/content/pl/disposability.md index 6d9673afb..007528b22 100644 --- a/content/pl/disposability.md +++ b/content/pl/disposability.md @@ -5,7 +5,7 @@ Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealnej sytuacji proces powinien potrzebować kilku sekund na to aby wystartować i być gotowym na przyjmowanie zapytań. Dzięki krótkiemu czasowi startu można szybciej wykonywać kolejne [wdrożenia](./build-release-run) oraz łatwiej skalować aplikację. Zwiększa to również zdolności aplikacji do radzenia sobie z problemami, ponieważ `process manager` może bezproblemowo przenieść je na nową maszynę fizyczną, gdy zajdzie taka potrzeba. -Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long poolingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie. +Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long pollingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie. Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](http://kr.github.com/beanstalkd/), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [indepotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). From 22859f9b5988493cff674a959f16ab3175a7ca26 Mon Sep 17 00:00:00 2001 From: Kamil Paszkowski Date: Tue, 12 Sep 2017 18:27:58 +0200 Subject: [PATCH 365/472] Fix typo in polish disposability translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace `indepotentną` with `idempotentną`. --- content/pl/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pl/disposability.md b/content/pl/disposability.md index 6d9673afb..54250f6ba 100644 --- a/content/pl/disposability.md +++ b/content/pl/disposability.md @@ -7,7 +7,7 @@ Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealn Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long poolingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie. -Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](http://kr.github.com/beanstalkd/), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [indepotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). +Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](http://kr.github.com/beanstalkd/), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [idempotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). Architektura aplikacji 12factor jest również zaprojektowana by działające procesy zostały poprawnie **zakończone w razie awarii** sprzętu. Podczas gdy taka sytuacja jest o wiele rzadsza niż otrzymanie sygnału `SIGTERM`, wciąż może mieć miejsce. Zalecanym podejściem w takich przypadkach jest stosowanie serwerowego systemu kolejkowania zadań, jak Beanstalkd, który zwróci zadanie do kolejki, gdy klient się rozłączy, bądź minie maksymalny czas obsługi pojedynczego zapytania. Architektura ["crash-only"](http://lwn.net/Articles/191059/) jest więc rozwinięciem takiego [konceptu](http://docs.couchdb.org/en/latest/intro/overview.html). From aab77285326db584f351b5224959302185d4c2f1 Mon Sep 17 00:00:00 2001 From: Webysther Nunes Date: Thu, 21 Sep 2017 16:36:31 -0300 Subject: [PATCH 366/472] =?UTF-8?q?Duplica=C3=A7=C3=A3o=20de=20letra?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/pt_br/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/disposability.md b/content/pt_br/disposability.md index b5d76a054..66a401f18 100644 --- a/content/pt_br/disposability.md +++ b/content/pt_br/disposability.md @@ -3,7 +3,7 @@ **Os [processos](./processos) de um app doze-fatores são *descartáveis*, significando que podem ser iniciados ou parados a qualquer momento.** Isso facilita o escalonamento elástico, rápido deploy de [código](./codebase) ou mudanças de [configuração](./config), e robustez de deploys de produção. -Processos devem empenhar-se em **minimizar o tempo de inicialização**. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de [release](./build-release-run) e de escalonamento; e ele adiciona robustez, pois o o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário. +Processos devem empenhar-se em **minimizar o tempo de inicialização**. Idealmente, um processo leva alguns segundos do tempo que o comando de inicialização é executado até o ponto que ele estará pronto para receber requisições ou tarefas. Períodos curtos de inicialização provém mais agilidade para o processo de [release](./build-release-run) e de escalonamento; e ele adiciona robustez, pois o gestor de processos pode mais facilmente mover processos para outras máquinas físicas quando necessário. Processos **desligam-se graciosamente quando recebem um sinal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** do seu gestor de processos. Para um processo web, desligamento gracioso é alcançado quando cessa de escutar à porta de serviço (consequentemente recusando quaisquer requisições novas), permitindo qualquer requisição em andamento terminar, e então desligando. Implícito neste modelo é que as requisições HTTP são curtas (não mais que alguns poucos segundos), ou no caso de um longo _polling_, o cliente deve ser capaz de transparentemente tentar se reconectar quando a conexão for perdida. From 4f02dedf97eeb1b953b6b18ad7139161d4b69126 Mon Sep 17 00:00:00 2001 From: Webysther Nunes Date: Thu, 21 Sep 2017 16:54:31 -0300 Subject: [PATCH 367/472] More clear about parity in portuguese --- content/pt_br/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index 946ddd9a3..184789d0c 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -1,4 +1,4 @@ -## X. Paridade entre desenv/produção +## X. Paridade entre desenvolvimento e produção ### Mantenha o desenvolvimento, homologação e produção o mais similares possível Historicamente, houveram lacunas substanciais entre desenvolvimento (um desenvolvedor editando código num [deploy](./codebase) local do app) e produção (um deploy acessado pelos usuários finais). Essas lacunas se manifestam em três áreas: From 1bbc3bffe824eb40a8c99e00045109ecd808e89f Mon Sep 17 00:00:00 2001 From: Webysther Nunes Date: Thu, 21 Sep 2017 16:58:40 -0300 Subject: [PATCH 368/472] Update dev-prod-parity.md --- content/pt_br/dev-prod-parity.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index 184789d0c..8cb0b6868 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -32,13 +32,13 @@ Resumindo o acima em uma tabela: Mesmas pessoas - Ambientes de desenv vs produção + Ambientes de desenvolvimento vs produção Divergente O mais similar possível -[Serviços de apoio](./backing-services), como o banco de dados do app, sistema de filas, ou cache, são uma área onde paridade entre desenv/produção é importante. Muitas linguagens oferecem diferentes bibliotecas que simplificam o acesso ao serviço de apoio, incluindo *adaptadores* para os diferentes tipos de serviços. Alguns exemplos na tabela abaixo. +[Serviços de apoio](./backing-services), como o banco de dados do app, sistema de filas, ou cache, são uma área onde paridade entre desenvolvimento e produção é importante. Muitas linguagens oferecem diferentes bibliotecas que simplificam o acesso ao serviço de apoio, incluindo *adaptadores* para os diferentes tipos de serviços. Alguns exemplos na tabela abaixo. @@ -71,6 +71,6 @@ Desenvolvedores as vezes vem uma grande vantagem em usar um serviço de apoio le **O desenvolvedor doze-fatores resiste a tentação de usar diferentes serviços de apoio entre desenvolvimento e produção**, mesmo quando adaptadores teoricamente abstraem as diferenças dos serviços de apoio. Diferenças entre serviços de apoio significam que pequenas incompatibilidades aparecerão, fazendo com que código que funcionava e passava em desenvolvimento ou homologação, falhe em produção. Tais tipos de erros criam fricção que desincentivam deploy contínuo. O custo dessa fricção e do subsequente decaimento de deploy contínuo é extremamente alto quando considerado que vai acumular no tempo de vida da aplicação. -Serviços locais leves são menos tentadores que já foram um dia. Serviços de apoio modernos tais como Memcached, PostgreSQL, e RabbitMQ não são difíceis de instalar e rodam graças a sistemas modernos de empacotamento tais como [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternativamente, ferramentas de provisionamento declarativo tais como [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/) combinado com ambientes virtuais leves como [Vagrant](http://vagrantup.com/) permitem desenvolvedores rodar ambientes locais que são bem próximos dos ambientes de produção. O custo de instalar e usar esses sistemas é baixo comparado ao benefício de ter a paridade entre desenv/produção e deploy contínuo. +Serviços locais leves são menos tentadores que já foram um dia. Serviços de apoio modernos tais como Memcached, PostgreSQL, e RabbitMQ não são difíceis de instalar e rodam graças a sistemas modernos de empacotamento tais como [Homebrew](http://mxcl.github.com/homebrew/) e [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternativamente, ferramentas de provisionamento declarativo tais como [Chef](http://www.opscode.com/chef/) e [Puppet](http://docs.puppetlabs.com/) combinado com ambientes virtuais leves como [Vagrant](http://vagrantup.com/) permitem desenvolvedores rodar ambientes locais que são bem próximos dos ambientes de produção. O custo de instalar e usar esses sistemas é baixo comparado ao benefício de ter a paridade entre desenvolvimento, produção e deploy contínuo. Adaptadores para diferentes serviços de apoio ainda são úteis, pois eles fazem a portabilidade para novos serviços de apoio relativamente tranquilas. Mas todos os deploys do app (ambientes de desenvolvimento, homologação, produção) devem usar o mesmo tipo e versão de cada serviço de apoio. From c784e386fa3ec4796141bb5dd928b363a51f1e00 Mon Sep 17 00:00:00 2001 From: Webysther Nunes Date: Thu, 21 Sep 2017 17:28:51 -0300 Subject: [PATCH 369/472] Typo in portuguese --- content/pt_br/admin-processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/admin-processes.md b/content/pt_br/admin-processes.md index 738ac5153..06e3b829b 100644 --- a/content/pt_br/admin-processes.md +++ b/content/pt_br/admin-processes.md @@ -9,6 +9,6 @@ A [formação de processos](./concurrency) é o conjunto de processos que são u Processos administrativos pontuais devem ser executados em um ambiente idêntico, como os [processos regulares de longa execução](./processes) da app. Eles rodam uma [versão](./build-release-run), usando a mesma [base de código](./codebase) e [configuração](./config) como qualquer processo executado com essa versão. Códigos de administração devem ser fornecidos com o código da aplicação para evitar problemas de sincronização. -A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` vendorizado para executar tanto o servidor web Tornado e qualquer processo de administração `manage.py`. +A mesma técnica de [isolamento de dependência](./dependencies) deve ser usada em todos tipos de processos. Por exemplo, se o processo web Ruby usa o comando `bundle exec thin start`, então uma migração de base de dados deve usar `bundle exec rake db:migrate`. Da mesma forma, um programa Python usando Virtualenv deve usar `bin/python` fornecido para executar tanto o servidor web Tornado e qualquer processo `manage.py` de administração. Doze-fatores favorecem fortemente linguagens que fornecem um shell REPL embutido, e que tornam mais fácil executar scripts pontuais. Em um deploy local, desenvolvedores invocam processos administrativos pontuais por um comando shell direto no diretório de checkout da app. Em um deploy de produção, desenvolvedores podem usar ssh ou outro mecanismo de execução de comandos remoto fornecido por aquele ambiente de execução do deploy para executar tal processo. From 017c7372d69149de84c48a04104d22e1cbbbe9a7 Mon Sep 17 00:00:00 2001 From: Luke Kim Date: Wed, 4 Oct 2017 11:56:35 +0900 Subject: [PATCH 370/472] Fix typo error and improve Korean translation. --- content/ko/admin-processes.md | 2 +- content/ko/build-release-run.md | 4 ++-- content/ko/codebase.md | 14 +++++++------- content/ko/concurrency.md | 2 +- content/ko/config.md | 2 +- content/ko/dependencies.md | 2 +- content/ko/disposability.md | 6 +++--- content/ko/toc.md | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/content/ko/admin-processes.md b/content/ko/admin-processes.md index 5648e8cdd..1a237e9cb 100644 --- a/content/ko/admin-processes.md +++ b/content/ko/admin-processes.md @@ -4,7 +4,7 @@ [프로세스 포메이션](./concurrency)은 애플리케이션의 일반적인 기능들(예: Web request의 처리)을 처리하기 위한 프로세스들의 집합 입니다. 이와는 별도로, 개발자들은 종종 일회성 관리나 유지 보수 작업이 필요합니다. 그 예는 아래와 같습니다. * 데이터베이스 마이그레이션을 실행합니다. (예: Django에서 `manage.py migrate`, Rail에서 `rake db:migrate`) -* 임의의 코드를 실행하거나 라이브 데이터베이스에서 앱의 모델을 조사하기 위해 콘솔([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) Shell로도 알려져 있는)을 실행한다. 대부분의 언어에서는 인터프리터를 아무런 인자 없이 실행하거나(예: python, perl) 별도의 명령어로 실행(예: ruby의 irb, rails의 rails console)할 수 있는 REPL를 제공합니다. +* 임의의 코드를 실행하거나 라이브 데이터베이스에서 앱의 모델을 조사하기 위해 콘솔([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) Shell로도 알려져 있는)을 실행합니다. 대부분의 언어에서는 인터프리터를 아무런 인자 없이 실행하거나(예: python, perl) 별도의 명령어로 실행(예: ruby의 irb, rails의 rails console)할 수 있는 REPL를 제공합니다. * 애플리케이션 저장소에 커밋된 일회성 스크립트의 실행 (예: php scripts/fix_bad_records.php) 일회성 admin 프로세스는 애플리케이션의 일반적인 [오래 실행되는 프로세스](./processes)들과 동일한 환경에서 실행되어야 합니다. 일회성 admin 프로세스들은 릴리즈를 기반으로 실행되며, 해당 릴리즈를 기반으로 돌아가는 모든 프로세스처럼 같은 [코드베이스](./codebase)와 [설정](./config)를 사용해야 합니다. admin 코드는 동기화 문제를 피하기 위해 애플리케이션 코드와 함께 배포되어야 합니다. diff --git a/content/ko/build-release-run.md b/content/ko/build-release-run.md index 60347e180..5002edd67 100644 --- a/content/ko/build-release-run.md +++ b/content/ko/build-release-run.md @@ -3,8 +3,8 @@ [코드베이스](./codebase)는 3 단계를 거쳐 (개발용이 아닌) 배포로 변환됩니다. -* *빌드 단계*는 코드 저장소를 코드 저장소를 *빌드*라는 실행 가능한 번들로 변환시키는 단계입니다. 빌드 단계에서는 커밋된 코드 중 배포 프로세스에서 지정된 버전을 사용하며, [종속성](./dependencies)를 가져와 바이너리와 에셋들을 컴파일합니다. -* *릴리즈 단계*에서는 빌드 단계에서 만들어진 빌드와 배포의 현재 [설정](./config)을 결합 합니다. 완성된 *릴리즈*는 빌드와 설정을 모두 포함하며 실행 환경에서 바로 실행될 수 있다도록 준비됩니다. +* *빌드 단계*는 코드 저장소를 코드 저장소를 *빌드*라는 실행 가능한 번들로 변환시키는 단계입니다. 빌드 단계에서는 커밋된 코드 중 배포 프로세스에서 지정된 버전을 사용하며, [종속성](./dependencies)을 가져와 바이너리와 에셋들을 컴파일합니다. +* *릴리즈 단계*에서는 빌드 단계에서 만들어진 빌드와 배포의 현재 [설정](./config)을 결합 합니다. 완성된 *릴리즈*는 빌드와 설정을 모두 포함하며 실행 환경에서 바로 실행될 수 있도록 준비됩니다. * *실행 단계*(런타임이라고도 하는)에서는 선택된 릴리즈에 대한 애플리케이션 [프로세스](./processes)의 집합을 시작하여, 애플리케이션을 실행 환경에서 돌아가도록 합니다. diff --git a/content/ko/codebase.md b/content/ko/codebase.md index 86461b7f9..28d54f827 100644 --- a/content/ko/codebase.md +++ b/content/ko/codebase.md @@ -1,17 +1,17 @@ ## I. 코드베이스 ### 버전 관리되는 하나의 코드베이스와 다양한 배포 -Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), [Subversion](http://subversion.apache.org/) 같은 버전 컨트롤 시스템을 사용하여 변화를 추적하며, 버전 추적 데이터베이스의 사본을 *코드 저장소*, 줄여서 *저장소*라고 부른다. +Twelve-Factor 앱은 항상 [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), [Subversion](http://subversion.apache.org/) 같은 버전 컨트롤 시스템을 사용하여 변화를 추적하며, 버전 추적 데이터베이스의 사본을 *코드 저장소*, 줄여서 *저장소*라고 부릅니다. -*코드베이스*는 단일 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우) 일수도 있고, 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)일수도 있다. +*코드베이스*는 단일 저장소(Subversion 같은 중앙 집중식 버전 관리 시스템의 경우) 일수도 있고, 루트 커밋을 공유하는 여러 저장소(Git 같은 분산 버전 관리 시스템)일수도 있습니다. ![하나의 코드베스는 여러 배포로 매핑됩니다.](/images/codebase-deploys.png) -코드베이스와 앱 사이에는 항상 1대1 관계가 성립된다. +코드베이스와 앱 사이에는 항상 1대1 관계가 성립됩니다. -* 코드베이스가 여러개 있는 경우, 앱이 아니라 분산 시스템으로 봐야한다. 분산 시스템의 개별 구성요소가 앱이 되며, 개별 앱이 Twelve-Factor를 따른다. -* 여러개 앱이 동일한 코드를 공유한다면 Twelve-Factor를 위반하는것이다. 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](./dependencies)로 관리한다. +* 코드베이스가 여러개 있는 경우, 앱이 아니라 분산 시스템으로 봐야합니다. 분산 시스템의 개별 구성요소가 앱이 되며, 개별 앱이 Twelve-Factor를 따릅니다. +* 여러개 앱이 동일한 코드를 공유한다면 Twelve-Factor를 위반하는것입니다. 이를 해결하려면 공유하는 코드를 라이브러리화 시키고, 해당 라이브러리를 [종속성 매니저](./dependencies)로 관리해야합니다. -앱의 코드베이스는 한개여야 하지만, 앱 배포는 여러개가 될수 있다. *배포*는 앱의 실행중인 인스턴스를 가리킨다. 보통 운영 사이트와 여러 스테이징 사이트가 여기에 해당한다. 모든 개발자는 자신의 로컬 개발 환경에 실행되는 앱을 가지고 있는데, 이것 역시 하나의 배포로 볼 수 있다. +앱의 코드베이스는 한개여야 하지만, 앱 배포는 여러개가 될수 있습니다. *배포*는 실행중인 앱의 인스턴스를 가리킵니다. 보통 운영 사이트와 여러 스테이징 사이트가 여기에 해당합니다. 모든 개발자는 자신의 로컬 개발 환경에 실행되는 앱을 가지고 있는데, 이것 역시 하나의 배포로 볼 수 있습니다. -배포마다 다른 버전이 활성화 될수 있지만, 코드베이스 자체는 모든 배포에 대해 동일하다. 예를 들어, 개발자는 아직 스테이징 환경에 배포하지 않은 커밋이 있을 수 있으며, 스테이징 환경에는 아직 운영 환경에 배포되지 않은 커밋이 있을 수 있다. 하지만 이 모든 것들이 같은 코드베이스를 공유하고, 같은 앱의 다른 배포라고 할 수 있다. \ No newline at end of file +배포마다 다른 버전이 활성화 될수 있지만, 코드베이스 자체는 모든 배포에 대해 동일합니다. 예를 들어, 개발자는 아직 스테이징 환경에 배포하지 않은 커밋이 있을 수 있으며, 스테이징 환경에는 아직 운영 환경에 배포되지 않은 커밋이 있을 수 있습니다. 하지만 이 모든 것들이 같은 코드베이스를 공유하고, 같은 앱의 다른 배포라고 할 수 있습니다. \ No newline at end of file diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md index d16e24179..8a0cddd38 100644 --- a/content/ko/concurrency.md +++ b/content/ko/concurrency.md @@ -5,7 +5,7 @@ ![Scale는 실행되는 프로세스의 갯수로 표현되고, Workload Diversity는 프로세스의 타입으로 표현됩니다. ](/images/process-types.png) -**Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션이 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. +**Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션의 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 시간이 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. 이는 런타임 VM 내부의 쓰레드나 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. diff --git a/content/ko/config.md b/content/ko/config.md index 3bedff6d3..c1f033277 100644 --- a/content/ko/config.md +++ b/content/ko/config.md @@ -1,7 +1,7 @@ ## III. 설정 ### 환경(environment)에 저장된 설정 -애플리케이션의 *설정*은 [배포](./codebase) (staging, production, 개발 환경 등) 마다 달라질 수 있는 모든 것들입니다. 설정에는 다음이 포함됩니다. +애플리케이션의 *설정*은 [배포](./codebase) (스테이징, 프로덕션, 개발 환경 등) 마다 달라질 수 있는 모든 것들입니다. 설정에는 다음이 포함됩니다. * 데이터베이스, memcached 등 [백엔드 서비스](./backing-services)들의 리소스 핸들 * Amazon S3 이나 트위터 등의 외부 서비스 인증 정보 diff --git a/content/ko/dependencies.md b/content/ko/dependencies.md index 943c0731f..99a2e7f74 100644 --- a/content/ko/dependencies.md +++ b/content/ko/dependencies.md @@ -5,7 +5,7 @@ **Twelve-Factor App은 전체 시스템에 특정 패키지가 암묵적으로 존재하는 것에 절대 의존하지 않습니다.** *종속선 선언* mainifest를 이용하여 모든 종속성을 완전하고 엄격하게 선언합니다. 더나아가, *종속성 분리* 툴을 사용하여 실행되는 동안 둘러싼 시스템으로 암묵적인 종속성 "유출"이 발생하지 않는 것을 보장합니다. 이런 완전하고 명시적인 종속성의 명시는 개발과 서비스 모두에게 동일하게 적용됩니다. -예를 들어, 루비에서 사용되는 [Bundler](https://bundler.io/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속선 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속석 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. +예를 들어, 루비에서 사용되는 [Bundler](https://bundler.io/)는 종속성 선언을 위해 `Gemfile` manifest 포맷을 지원하며, 종속성 분리를 위해 `bundle exec`를 지원합니다. 파이썬에는 이를 지원하기 위한 2가지 도구가 있습니다. [Pip](http://www.pip-installer.org/en/latest/)은 종속성 선언을 위해 사용되며, [Virtualenv](http://www.virtualenv.org/en/latest/)는 종속성 분리를 위해 사용됩니다. 심지어 C언어에도 종속성 분리를 위해 [Autoconf](http://www.gnu.org/s/autoconf/)가 있으며, static link를 활용해 종속성 분리도 가능합니다. 어떤 툴체인을 사용하든, 종속성 선언과 분리는 항상 같이 사용되어야 합니다. 하나만 사용하는 것은 Twelve-Factor에 만족하는 데 불충분합니다. 명시적인 종속성 선언의 장점 중 하나는 애플리케이션 개발에 새로 참가하게 된 개발자가 설치를 간단하게 할 수 있다는 점입니다. 새로 참가한 개발자는 애플리케이션의 코드베이스를 개발 머신에 체크아웃 하고, 언어의 런타임과 종속성 매니저만 미리 설치하면 됩니다. 개발자는 정해져있는 *빌드 명령어*만 입력하면 응용 프로그램의 코드를 실행하는 데 필요한 모든 것을 설치할 수 있습니다. 예를 들어, Ruby의 빌드 명령어는 `bundle install`이며, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme)에서는 `lein deps`입니다. diff --git a/content/ko/disposability.md b/content/ko/disposability.md index fc50abf84..077ff0edc 100644 --- a/content/ko/disposability.md +++ b/content/ko/disposability.md @@ -1,12 +1,12 @@ ## IX. 폐기 가능(Disposability) ### 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화 -**Twelve-Factor App의 [프로세스](./processes)는 *간단하게 폐기 가능*합니다. 즉, 프로세스는 바로 시작하거나 종료될 수 있습니다. 이러한 속성은 신축성 있는 확장과 [코드](./codebase)나 [설정](./config)의 변화를 빠르게 배포하는 것을 쉽게 하며, production 배포를 안정성 있게 해줍니다. +**Twelve-Factor App의 [프로세스](./processes)는 *간단하게 폐기 가능*합니다. 즉, 프로세스는 바로 시작하거나 종료될 수 있습니다.** 이러한 속성은 신축성 있는 확장과 [코드](./codebase)나 [설정](./config)의 변화를 빠르게 배포하는 것을 쉽게 하며, production 배포를 안정성 있게 해줍니다. 프로세스는 **시작 시간을 최소화**하도록 노력해야합니다. 이상적으로, 프로세스는 실행 커맨드가 실행된 뒤 몇 초만에 요청이나 작업을 받을 수 있도록 준비 됩니다. 짧은 실행 시간은 [릴리즈](./build-release-run) 작업과 확장(scale up)이 더 민첩하게 이루어질 수 있게 합니다. 또한 프로세스 매니저가 필요에 따라 쉽게 프로세스를 새로운 머신으로 프로세스를 옮길 수 있기 때문에 안정성도 높아집니다. -프로세스는 프로세스 매니저로부터 **[SIGTERM]((http://en.wikipedia.org/wiki/SIGTERM) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다. ** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. +프로세스는 프로세스 매니저로부터 **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다.** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. -worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](http://kr.github.com/beanstalkd/)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [idempotent](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. +worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](http://kr.github.com/beanstalkd/)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [멱등(idempotent)](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. 프로세스는 하드웨어 에러에 의한 **갑작스러운 죽음에도 견고해야합니다.** 이러한 사태는 `SIGTERM`에 의한 그레이스풀 셧다운에 비하면 드문 일이지만, 그럼에도 발생할 수 있습니다. 이런 일에 대한 대책으로 Beanstalkd와 같은 견고한 큐잉 백엔드를 사용하는 것을 권장합니다. 이러한 백엔드는 클라이언트가 접속이 끊기거나, 타임 아웃이 발생했을 때, 작업을 큐로 되돌립니다. Twelve-Factor App은 예기치 못한, 우아하지 않은 종료도 처리할 수 있도록 설계됩니다. [Crash-only design](http://lwn.net/Articles/191059/)에서는 [논리적인 결론](http://docs.couchdb.org/en/latest/intro/overview.html)으로 이러한 컨셉을 가져왔습니다. \ No newline at end of file diff --git a/content/ko/toc.md b/content/ko/toc.md index 4d9d92862..bac6c0e15 100644 --- a/content/ko/toc.md +++ b/content/ko/toc.md @@ -28,8 +28,8 @@ The Twelve Factors ## [IX. 폐기 가능(Disposability)](./disposability) ### 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화 -## [X. dev/prod 일치](./dev-prod-parity) -### development, staging, production 환경을 최대한 비슷하게 유지 +## [X. 개발/프로덕션환경 일치](./dev-prod-parity) +### 개발, 스테이징, 프로덕션 환경을 최대한 비슷하게 유지 ## [XI. 로그](./logs) ### 로그를 이벤트 스트림으로 취급 From eb30f0b1aef2beb123dab8d280eb7672aa4b7324 Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Wed, 18 Oct 2017 15:14:44 +0100 Subject: [PATCH 371/472] Improved grammar on the Backing Services page. --- content/en/backing-services.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/backing-services.md b/content/en/backing-services.md index dff7c7dcb..732a69b90 100644 --- a/content/en/backing-services.md +++ b/content/en/backing-services.md @@ -11,5 +11,4 @@ Each distinct backing service is a *resource*. For example, a MySQL database is A production deploy attached to four backing services. -Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. - +Resources can be attached to and detached from deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. From 22ecd4f5b4b5ea0be655f85dbccff3bd93daeea8 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Tue, 24 Oct 2017 00:23:05 +0900 Subject: [PATCH 372/472] Replace 'Fluent' with 'Fluentd' in logs.md --- content/de/logs.md | 2 +- content/en/logs.md | 2 +- content/es/logs.md | 2 +- content/fr/logs.md | 2 +- content/it/logs.md | 2 +- content/ja/logs.md | 2 +- content/ko/logs.md | 2 +- content/pl/logs.md | 2 +- content/pt_br/logs.md | 2 +- content/ru/logs.md | 2 +- content/tr/logs.md | 2 +- content/uk/logs.md | 4 ++-- content/zh_cn/logs.md | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/content/de/logs.md b/content/de/logs.md index 68af07286..940bdff5c 100644 --- a/content/de/logs.md +++ b/content/de/logs.md @@ -7,7 +7,7 @@ Logs sind der [Stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams **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. +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 [Fluentd](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 diesem System kann das Verhalten einer App leistungsfähig und flexibel beobachtet werden. Dies schließt ein: diff --git a/content/en/logs.md b/content/en/logs.md index a893811a9..22e3404e7 100644 --- a/content/en/logs.md +++ b/content/en/logs.md @@ -7,7 +7,7 @@ Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_ **A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluentd](https://github.com/fluent/fluentd)) are available for this purpose. The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: diff --git a/content/es/logs.md b/content/es/logs.md index 3ae035370..e5e9f451f 100644 --- a/content/es/logs.md +++ b/content/es/logs.md @@ -7,7 +7,7 @@ Los historiales son la [transmisión](https://adam.herokuapp.com/past/2011/4/1/l **Una aplicación "twelve-factor" nunca se preocupa del direccionamiento o el almacenamiento de sus transmisiones de salida.** No debería intentar escribir o gestionar ficheros de historial. En su lugar, cada proceso en ejecución escribe sus eventos a la `salida estándar` (o `stdout`). Durante el desarrollo, los desarrolladores verán el flujo en su terminal para observar el comportamiento de la aplicación. -En despliegues de preproducción y producción, cada transmisión del proceso será capturada por el entorno de ejecución, siendo capturadas junto con todos los otros flujos de la aplicación, y redirigidas a uno o más destinos finales para ser revisadas y archivadas. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales (como [Logplex](https://github.com/heroku/logplex) y [Fluent](https://github.com/fluent/fluentd)) se usan con este objetivo. +En despliegues de preproducción y producción, cada transmisión del proceso será capturada por el entorno de ejecución, siendo capturadas junto con todos los otros flujos de la aplicación, y redirigidas a uno o más destinos finales para ser revisadas y archivadas. Estos destinos donde se archivan no son visibles o configurables por la aplicación, se gestionan totalmente por el entorno de ejecución. Las herramientas de código abierto que capturan y almacenan los historiales (como [Logplex](https://github.com/heroku/logplex) y [Fluentd](https://github.com/fluent/fluentd)) se usan con este objetivo. Las transmisiones de eventos para una aplicación pueden ser redirigidas a un fichero u observadas en tiempo real mediante un "tail" en un terminal. Cabe destacar que la transmisión se puede enviar a un sistema de análisis e indexado como [Splunk](http://www.splunk.com/), o a un sistema de almacenamiendo de datos de propósito general como [Hadoop/Hive](http://hive.apache.org/). Estos sistemas se tienen en cuenta por el gran poder y la flexibilidad para inspeccionar el comportamiento de la aplicación a lo largo del tiempo, incluyendo: diff --git a/content/fr/logs.md b/content/fr/logs.md index 895873032..c05a70b17 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -7,7 +7,7 @@ Les logs sont des [flux (en)](https://adam.herokuapp.com/past/2011/4/1/logs_are_ **Une application 12 facteurs ne s'inquiète jamais du routage ou du stockage de ses flux de sortie.** Elle ne devrait pas tenter d'écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d'événements, sans tampon, vers `stdout`, la sortie standard ; en phase de développement local, les développeurs pourront voir ce flux dans leur terminal et observer le comportement de l'application. -Dans les déploiements de validation ou de production, les flux de chaque processus seront capturés par leur environnement d'exécution, assemblés avec les autres flux de l'application, et routés vers une ou plusieurs destinations pour un visionnage et un archivage de longue durée. Le lieu d'archivage n'est pas visible et ne peut être configuré par l'application : ils sont complètements gérés par l'environnement d'exécution. Des routeurs opensource de logs, (tel que [Logplex](https://github.com/heroku/logplex) et [Fluent](https://github.com/fluent/fluentd)) existent pour cela. +Dans les déploiements de validation ou de production, les flux de chaque processus seront capturés par leur environnement d'exécution, assemblés avec les autres flux de l'application, et routés vers une ou plusieurs destinations pour un visionnage et un archivage de longue durée. Le lieu d'archivage n'est pas visible et ne peut être configuré par l'application : ils sont complètements gérés par l'environnement d'exécution. Des routeurs opensource de logs, (tel que [Logplex](https://github.com/heroku/logplex) et [Fluentd](https://github.com/fluent/fluentd)) existent pour cela. Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepot de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : diff --git a/content/it/logs.md b/content/it/logs.md index d818d6177..a879e75e6 100644 --- a/content/it/logs.md +++ b/content/it/logs.md @@ -7,7 +7,7 @@ Un log può essere definito infatti come uno [stream](https://adam.herokuapp.com **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 ed 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 [Fluent](https://github.com/fluent/fluentd)). +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 ed 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 ad un sistema di analisi ed indicizzazione di log, come [Splunk](http://www.splunk.com/), oppure ad 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 ad esempio: diff --git a/content/ja/logs.md b/content/ja/logs.md index 0f02c7f47..b8aa706ea 100644 --- a/content/ja/logs.md +++ b/content/ja/logs.md @@ -7,7 +7,7 @@ **Twelve-Factor Appはアプリケーションの出力ストリームの送り先やストレージについて一切関知しない。** アプリケーションはログファイルに書き込んだり管理しようとするべきではない。代わりに、それぞれの実行中のプロセスはイベントストリームを`stdout`(標準出力)にバッファリングせずに書きだす。ローカルでの開発中、開発者はこのストリームをターミナルのフォアグラウンドで見ることで、アプリケーションの挙動を観察する。 -ステージングや本番のデプロイでは、それぞれのプロセスのストリームは実行環境に捕らえられ、アプリケーションからの他のすべてのストリームと一緒に並べられ、表示や長期アーカイブのために1つもしくは複数の最終目的地に送られる。これらの保存のための目的地は、アプリケーションからは見ることも設定することもできず、代わりに実行環境によって完全に管理される。[Logplex](https://github.com/heroku/logplex) や [Fluent](https://github.com/fluent/fluentd) などのオープンソースのログルーターがこの目的に利用できる。 +ステージングや本番のデプロイでは、それぞれのプロセスのストリームは実行環境に捕らえられ、アプリケーションからの他のすべてのストリームと一緒に並べられ、表示や長期アーカイブのために1つもしくは複数の最終目的地に送られる。これらの保存のための目的地は、アプリケーションからは見ることも設定することもできず、代わりに実行環境によって完全に管理される。[Logplex](https://github.com/heroku/logplex) や [Fluentd](https://github.com/fluent/fluentd) などのオープンソースのログルーターがこの目的に利用できる。 アプリケーションのイベントストリームは、ファイルに送られたり、ターミナルでtailを使ってリアルタイムに見られたりする。最も重要な用途として、ストリームは、[Splunk](http://www.splunk.com/)などのログインデックス・解析システムや、[Hadoop/Hive](http://hive.apache.org/)などの汎用データウェアハウスシステムに送られることもある。これらのシステムは、長期に渡ってアプリケーションの挙動を確認するための大きな力と柔軟性をもたらし、次のようなことができるようになる。 diff --git a/content/ko/logs.md b/content/ko/logs.md index d3fe4e766..1886334fa 100644 --- a/content/ko/logs.md +++ b/content/ko/logs.md @@ -7,7 +7,7 @@ **Twelve-Factor App은 아웃풋 스트림의 전달이나 저장에 절대 관여하지 않습니다.** app은 로그 파일을 작성하거나, 관리하려고 해서는 안됩니다. 대신, 각 프로세스는 이벤트 스트림을 버퍼링 없이 `stdout`에 출력합니다. 로컬 개발환경에서 작업 중인 개발자는 app의 동작을 관찰하기 원하면 각자의 터미널에 출력되는 이 스트림을 볼 수 있습니다. -스테이징이나 production 배포에서는 각 프로세스의 스트림은 실행 환경에 의해서 수집된 후, 앱의 다른 모든 스트림과 병합되어 열람하거나 보관하기 위한 하나 이상의 최종 목적지로 전달됩니다. 이러한 목적지들은 앱이 열람하거나 설정할 수 없지만, 대신 실행 환경에 의해서 완벽하게 관리됩니다. 이를 위해 오픈 소스 로그 라우터를 사용할 수 있습니다.(예: ([Logplex](https://github.com/heroku/logplex), [Fluent](https://github.com/fluent/fluentd))) +스테이징이나 production 배포에서는 각 프로세스의 스트림은 실행 환경에 의해서 수집된 후, 앱의 다른 모든 스트림과 병합되어 열람하거나 보관하기 위한 하나 이상의 최종 목적지로 전달됩니다. 이러한 목적지들은 앱이 열람하거나 설정할 수 없지만, 대신 실행 환경에 의해서 완벽하게 관리됩니다. 이를 위해 오픈 소스 로그 라우터를 사용할 수 있습니다.(예: ([Logplex](https://github.com/heroku/logplex), [Fluentd](https://github.com/fluent/fluentd))) 앱의 이벤트 스트림은 파일로 보내지거나 터미널에서 실시간으로 보여질 수 있습니다. 가장 중요한 점은 스트림은 [Splunk](http://www.splunk.com/)같은 로그 분석 시스템과 [Hadoop/Hive](http://hive.apache.org/)같은 범용 데이터 보관소에 보내질 수 있다는 점입니다. 이러한 시스템은 장기간에 걸쳐 앱의 동작을 조사할 수 있는 강력함과 유연성을 가지게 됩니다. diff --git a/content/pl/logs.md b/content/pl/logs.md index 339ae69ba..1a7d29cfc 100644 --- a/content/pl/logs.md +++ b/content/pl/logs.md @@ -7,7 +7,7 @@ **Aplikacja 12factor nie odpowiada za przekierowywanie i zapis swojego strumienia wyjściowego.** Nie powinna też zapisywać czy zarządzać plikami logów. Zamiast tego, każdy działający proces zapisuje swój niebuforowany strumień zdarzeń do `stdout`. Podczas pracy w lokalnym środowisku developer może obserwować zachowanie aplikacji przeglądając strumień w oknie terminala -We wdrożeniu stagingowym czy produkcyjnym, każdy strumień procesów zostanie przechwycony przez środowisko wykonawcze, dołączony do pozostałych i skierowany do jednego lub wielu miejsc w celu przeglądania i długoterminowego zapisu. Miejsca zapisu nie są widoczne ani konfigurowane przez aplikację - w całości zarządza nimi środowisko wykonawcze. W tym celu można skorzystać z narzędzi do obsługi logów (takich jak [Logplex](https://github.com/heroku/logplex) lub [Fluent](https://github.com/fluent/fluentd)) dostępnych na licencji open-source. +We wdrożeniu stagingowym czy produkcyjnym, każdy strumień procesów zostanie przechwycony przez środowisko wykonawcze, dołączony do pozostałych i skierowany do jednego lub wielu miejsc w celu przeglądania i długoterminowego zapisu. Miejsca zapisu nie są widoczne ani konfigurowane przez aplikację - w całości zarządza nimi środowisko wykonawcze. W tym celu można skorzystać z narzędzi do obsługi logów (takich jak [Logplex](https://github.com/heroku/logplex) lub [Fluentd](https://github.com/fluent/fluentd)) dostępnych na licencji open-source. Strumień zdarzeń aplikacji może być skierowany do pliku lub obserwowany w czasie rzeczywistym przy pomocy komendy `tail` w terminalu. Przeważnie strumień jest wysyłany do systemu indeksowania i analizowania jak np. [Splunk](http://www.splunk.com/), albo do systemu magazynowania danych jak [Hadoop/Hive](http://hive.apache.org/). Wymienione systemy oferują duże możliwości i elastyczność obserwacji i badania zachowań aplikacji w czasie, w tym: diff --git a/content/pt_br/logs.md b/content/pt_br/logs.md index 4f4b57794..ec4467c4e 100644 --- a/content/pt_br/logs.md +++ b/content/pt_br/logs.md @@ -7,7 +7,7 @@ Logs são o [fluxo](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_no **Um app doze-fatores nunca se preocupa com o roteamento ou armazenagem do seu fluxo de saída.** Ele não deve tentar escrever ou gerir arquivos de logs. No lugar, cada processo em execução escreve seu próprio fluxo de evento, sem buffer, para o `stdout`. Durante o desenvolvimento local, o desenvolvedor verá este fluxo no plano de frente do seu terminal para observar o comportamento do app. -Em deploys de homologação ou produção, cada fluxo dos processos serão capturados pelo ambiente de execução, colados com todos os demais fluxos do app, e direcionados para um ou mais destinos finais para visualização e arquivamento de longo prazo. Estes destinos de arquivamento não são visíveis ou configuráveis pelo app, e ao invés disso, são completamente geridos pelo ambiente de execução. Roteadores de log open source (tais como [Logplex](https://github.com/heroku/logplex) e [Fluent](https://github.com/fluent/fluentd)) estão disponíveis para este propósito. +Em deploys de homologação ou produção, cada fluxo dos processos serão capturados pelo ambiente de execução, colados com todos os demais fluxos do app, e direcionados para um ou mais destinos finais para visualização e arquivamento de longo prazo. Estes destinos de arquivamento não são visíveis ou configuráveis pelo app, e ao invés disso, são completamente geridos pelo ambiente de execução. Roteadores de log open source (tais como [Logplex](https://github.com/heroku/logplex) e [Fluentd](https://github.com/fluent/fluentd)) estão disponíveis para este propósito. O fluxo de evento para um app pode ser direcionado para um arquivo, ou visto em tempo real via `tail` num terminal. Mais significativamente, o fluxo pode ser enviado para um sistema indexador e analisador tal como [Splunk](http://www.splunk.com/), ou um sistema mais genérico de _data warehousing_ como o [Hadoop/Hive](http://hive.apache.org/). Estes sistemas permitem grande poder e flexibilidade para observar o comportamento de um app durante o tempo, incluindo: diff --git a/content/ru/logs.md b/content/ru/logs.md index 273ed4320..bbccbf64f 100644 --- a/content/ru/logs.md +++ b/content/ru/logs.md @@ -7,7 +7,7 @@ **Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода.** Приложение не должно записывать журнал в файл и управлять файлами журналов. Вместо этого каждый выполняющийся процесс записывает свой поток событий без буферизации в стандартный вывод `stdout`. Во время локальной разработки разработчик имеет возможность просматривать этот поток в терминале, чтобы наблюдать за поведением приложения. -При промежуточном и рабочем развёртывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluent](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. +При промежуточном и рабочем развёртывании поток вывода каждого процесса будет захвачен средой выполнения, собран вместе со всеми другими потоками вывода приложения и перенаправлен к одному или нескольким конечным пунктам назначения для просмотра и долгосрочной архивации. Эти конечные пункты архивации не являются видимыми для приложения и настраиваемыми приложением, вместо этого они полностью управляются средой выполнения. Маршрутизаторы журналов с открытым исходным кодом (например, [Logplex](https://github.com/heroku/logplex) и [Fluentd](https://github.com/fluent/fluentd)) могут быть использованы для этой цели. Поток событий приложения может быть перенаправлен в файл или просматриваться в терминале в режиме реального времени. Наиболее значимым является то, что поток событий может быть направлен в систему индексирования и анализа журналов, такую как [Splunk](http://www.splunk.com/), или систему хранения данных общего назначения, такую как [Hadoop/Hive](http://hive.apache.org/). Эти системы обладают большими возможностями и гибкостью для досконального анализа поведения приложение в течении времени, что включает в себя: diff --git a/content/tr/logs.md b/content/tr/logs.md index fe7011016..e8d61b386 100644 --- a/content/tr/logs.md +++ b/content/tr/logs.md @@ -7,7 +7,7 @@ Günlükler, bütün çalışan süreçler ve destek servislerinin çıktı akı **On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Günlük dosyalarını yazma ve yönetme yapmamalıdır. Bunun yerine, her çalışan süreç kendi olay akışını tamponlamadan `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinin önplanında bu akışı inceleyecekler. -Evreleme ve ürün dağıtımlarında herbir sürecin akışı çalışma ortamı tarafından yakalanmış diğer uygulamadaki, diğer bütün akışlarla birlikte sıralanmış, görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilmiş olacaklar. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, bunun yerine tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak günlük yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluent](https://github.com/fluent/fluentd) gibi) bu amaç için erişilebilirdir. +Evreleme ve ürün dağıtımlarında herbir sürecin akışı çalışma ortamı tarafından yakalanmış diğer uygulamadaki, diğer bütün akışlarla birlikte sıralanmış, görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilmiş olacaklar. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, bunun yerine tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak günlük yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluentd](https://github.com/fluent/fluentd) gibi) bu amaç için erişilebilirdir. Bir uygulama için olay akışı dosyaya yönlendirilebilir veya terminalden gerçek zamanlı kuyruklama aracılığla izlenebilir. En önemlisi, akış [Splunk](http://www.splunk.com/) gibi günlük numaralandırma ve analiz sistemine veya [Hadoop/Hive](http://hive.apache.org/) gibi genel amaçlı veri depolama sistemine gönderilebilir. Bu sistemler uygulamanın zamanla olan davranışlarında iç gözlem yapmak için büyük güç ve esnekliğe izin verir. Bunları içerir: diff --git a/content/uk/logs.md b/content/uk/logs.md index 3ce24c6f2..324dc0b39 100644 --- a/content/uk/logs.md +++ b/content/uk/logs.md @@ -7,10 +7,10 @@ **Застосунок дванадцяти факторів ніколи не займається маршрутизацію і зберіганням свого потоку виведення.** Застосунок не повинен записувати журнал у файл або керувати файлами журналів. Замість цього кожен запущений процес записує свій потік подій без буферизації в стандартне виведення `stdout`. В development середовищі розробник має можливість переглядати цей потік в терміналі, щоб спостерігати за поведінкою застосунку. -В staging та production розгортаннях потік виведення кожного процесу перехоплюється середовищем виконання, збирається разом з усіма іншими потоками виведення застосунку і спрямовується до одного або кількох кінцевих пунктів призначення для перегляду і довгострокового архівування. Ці кінцеві пункти призначення не видимі для застосунку і не налаштовуються ним, вони керуються середовищем виконання. Для цього можуть бути використані маршрутизатори журналів з відкритим вихідним кодом (наприклад, [Logplex](https://github.com/heroku/logplex) та [Fluent](https://github.com/fluent/fluentd)). +В staging та production розгортаннях потік виведення кожного процесу перехоплюється середовищем виконання, збирається разом з усіма іншими потоками виведення застосунку і спрямовується до одного або кількох кінцевих пунктів призначення для перегляду і довгострокового архівування. Ці кінцеві пункти призначення не видимі для застосунку і не налаштовуються ним, вони керуються середовищем виконання. Для цього можуть бути використані маршрутизатори журналів з відкритим вихідним кодом (наприклад, [Logplex](https://github.com/heroku/logplex) та [Fluentd](https://github.com/fluent/fluentd)). Потік подій застосунку може бути направлений у файл або переглянутий у терміналі в режимі реального часу. Найважливішим є те, що потік може бути направлений у систему індексування і аналізу журналів, таку як [Splunk](http://www.splunk.com/), або систему зберігання даних загального призначення, таку як [Hadoop/Hive](http://hive.apache.org/). Ці системи мають широкі можливості і гнучкість для детального аналізу поведінки застосунку протягом тривалого часу, в тому числі: * Виявлення конкретних подій у минулому; * Побудова графіків трендів (наприклад, кількість запитів за хвилину); -* Активне оповіщення відповідно до визначених користувачем евристичних правил (наприклад, попередження, коли кількість помилок за хвилину перевищує певний поріг). \ No newline at end of file +* Активне оповіщення відповідно до визначених користувачем евристичних правил (наприклад, попередження, коли кількість помилок за хвилину перевищує певний поріг). diff --git a/content/zh_cn/logs.md b/content/zh_cn/logs.md index 7873a7804..4204a7794 100644 --- a/content/zh_cn/logs.md +++ b/content/zh_cn/logs.md @@ -7,7 +7,7 @@ **12-factor应用本身从不考虑存储自己的输出流。** 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(`stdout`)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。 -在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 [Logplex](https://github.com/heroku/logplex) 和 [Fluent](https://github.com/fluent/fluentd) 的开源工具可以达到这个目的。 +在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 [Logplex](https://github.com/heroku/logplex) 和 [Fluentd](https://github.com/fluent/fluentd) 的开源工具可以达到这个目的。 这些事件流可以输出至文件,或者在终端实时观察。最重要的,输出流可以发送到 [Splunk](http://www.splunk.com/) 这样的日志索引及分析系统,或 [Hadoop/Hive](http://hive.apache.org/) 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括: From 7a37bc4daec8c9cc598340b5023acaf433a43941 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 18:49:03 +0100 Subject: [PATCH 373/472] Fix typos in dependencies.md --- content/fr/dependencies.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/fr/dependencies.md b/content/fr/dependencies.md index b4e6f285f..146c066d1 100644 --- a/content/fr/dependencies.md +++ b/content/fr/dependencies.md @@ -3,10 +3,10 @@ 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épendances 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. +**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 chaine 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. +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 oeil à 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`. +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, comme par exemple ImageMagick ou `curl`. Bien que ces outils puissent exister sur beaucoup voire la plupart des systèmes d'exploitations, 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. +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. From 5a35a92968d20c96aa49047442545eeb7d1b23d4 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:02:20 +0100 Subject: [PATCH 374/472] FIx typos in config.md --- content/fr/config.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/fr/config.md b/content/fr/config.md index 94fe08163..396519b4c 100644 --- a/content/fr/config.md +++ b/content/fr/config.md @@ -1,7 +1,7 @@ ## III. Configuration ### Stockez la configuration dans l'environnement -La *configuration* d'une application est tout ce qui est susceptible de varier entre des [déploiements](./codebase) (validation, production, environnement de développement, etc). Cela inclut : +La *configuration* d'une application est tout ce qui est susceptible de varier entre des [déploiements](./codebase) (validation, production, environnement de développement, etc.). Cela inclut : * Les ressources gérées par la base de données, Memcached, ou tout autre [service de stockage](./backing-services) * Les identifiants pour des services externes, tel qu'Amazon S3 ou Twitter @@ -9,14 +9,14 @@ La *configuration* d'une application est tout ce qui est susceptible de varier e Les applications stockent parfois la configuration avec des constantes dans le code. C'est une violation des 12 facteurs, qui requiert une **stricte séparation de la configuration et du code**. La configuration peut varier substantiellement à travers les déploiements, alors que ce n'est pas le cas du code. -Un bon moyen de tester si une application a correctement séparé son code, c'est de se demander si l'application pourrait être rendu open-source à tout instant, sans compromettre d'identifiants. +Un bon moyen de tester si une application a correctement séparé son code, c'est de se demander si l'application pourrait être rendue open-source à tout instant, sans compromettre d'identifiants. Notez que cette définition de "configuration" n'inclut **pas** la configuration interne de l'application, tel que `config/routes.rb` avec Rails, ou comment [les modules du noyau sont connectés (en)](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) dans [Spring](http://spring.io/). Ce type de configuration ne varie pas à travers les déploiements, et est ainsi mieux réalisé dans le code. -Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, comme par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendances à être spécifiques à un langage ou un framework. +Une autre approche de la configuration, c'est d'utiliser des fichiers de configuration qui ne sont pas inclus dans le système de contrôle de version, par exemple `config/database.yml` de Rails. C'est une amélioration considérable par rapport à l'utilisation de constantes qui sont versionnées dans le dépôt de code, mais a toujours des faiblesses : il est facile d'ajouter par inadvertance un fichier de configuration dans le dépôt. Il y a une tendance à ce que les fichiers de configuration soient dispersés à différents endroits et dans différents formats, rendant ainsi difficile de voir et gérer la configuration à un unique endroit. De plus, ces formats ont tendance à être spécifiques à un langage ou un framework. **Les applications 12 facteurs stockent la configuration dans des *variables d'environnement*** (souvent raccourcies en *variables d'env*, ou *env*). Les variables d'environnement sont faciles à changer entre des déploiements sans changer le moindre code ; contrairement aux fichiers de configuration, il y a peu de chance pour qu'elles soient ajoutées au dépôt de code accidentellement ; et contrairement aux fichiers de configuration personnalisés, ou tout autre mécanisme de configuration comme les propriétés système Java, ce sont des standards agnostiques du langage ou du système d'exploitation. -Un autre aspect de la gestion de configuration est le groupage. Parfois les applications regroupent la configuration dans des groupes nommés (souvent appelés les "environnements"), nommés ainsi d'après des déploiements spécifiques, comme les environnements `development`, `test`, et `production` de Rails. Cette méthode ne permet pas de grossir proprement : lorsque l'on ajoute de nouveaux déploiement à l'application, de nouveaux noms d'environnement sont nécessaires, comme `validation` ou `qa`. Quand le projet grossit encore plus, les développeurs vont avoir tendance à ajouter leur propres environnement particuliers, comme `joes-validation`, ce qui entraine une explosion combinatoire de la configuration qui rend la gestion des déploiement de l'application très fragile. +Un autre aspect de la gestion de configuration est le groupage. Parfois, les applications regroupent la configuration dans des groupes nommés (souvent appelés les "environnements"), nommés ainsi d'après des déploiements spécifiques, comme les environnements `development`, `test`, et `production` de Rails. Cette méthode ne permet pas de grossir proprement : lorsque l'on ajoute de nouveaux déploiement à l'application, de nouveaux noms d'environnement sont nécessaires, comme `validation` ou `qa`. Quand le projet grossit encore plus, les développeurs vont avoir tendance à ajouter leurs propres environnements particuliers, comme `joes-validation`, ce qui entraîne une explosion combinatoire de la configuration qui rend la gestion des déploiements de l'application très fragile. Dans une application 12 facteurs, les variables d'environnement permettent un contrôle granulaire, chacune complètement orthogonale aux autres variables d'environnement. Elles ne sont jamais groupées ensemble en "environnements", mais sont plutôt gérées indépendamment pour chaque déploiement. C'est un modèle qui permet de grossir verticalement en souplesse, lorsque l'application grossit naturellement en un plus grand nombre de déploiements au cours de sa vie. From f588745d9e806de53e62f33dc30010348c6f2d3f Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:07:12 +0100 Subject: [PATCH 375/472] fix typos in backing-services.md --- content/fr/backing-services.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md index 36b824cf9..c8551bd02 100644 --- a/content/fr/backing-services.md +++ b/content/fr/backing-services.md @@ -7,8 +7,8 @@ Les *services externes* comme la base de données sont le plus souvent gérés p **Le code d'une application 12 facteurs ne fait pas de distinction entre les services locaux et les services tiers**. Pour l'application, ce sont tous les deux des ressources attachées, accessibles via une URL ou un autre système de localisation et d'authentification stockée dans la [configuration](./config). Un [déploiement](./codebase) d'une application 12 facteurs doit pouvoir remplacer une base de données MySQL locale par une autre gérée par des tiers ([Amazon RDS](http://aws.amazon.com/rds/), par exemple) sans le moindre changement dans le code de l'application. De la même manière, un serveur SMTP local doit pouvoir être remplacé par un service tiers (Postmark, par exemple) sans changements dans le code. Dans les deux cas, seules les informations de configurations doivent changer. -Chaque service externe est une *ressource*. Par exemple, une base de données MySQL est une ressource. Deux bases de données MySQL (utilisées pour faire du sharding dans la couche applicative) correspondent à deux ressources distinctes. L'application 12 facteurs traite ces base de données comme des ressources attachées, ce qui indique leur couplage faible au déploiement auquel elles sont rattachées. +Chaque service externe est une *ressource*. Par exemple, une base de données MySQL est une ressource. Deux bases de données MySQL (utilisées pour faire du sharding dans la couche applicative) correspondent à deux ressources distinctes. L'application 12 facteurs traite ces bases de données comme des ressources attachées, ce qui indique leur couplage faible au déploiement auquel elles sont rattachées. Un déploiement de production lié à quatre services externes. -Les resources peuvent être attachées et détachées à volonté à des déploiements. Par exemple, si la base de données de l'application pose problème pour des raisons matérielles, l'administrateur de l'application peut vouloir lancer un nouveau serveur de base de données restauré à partir d'une sauvegarde récente. L'application courante pourrait être détachée de l'ancienne, puis rattachée à la nouvelle — le tout sans changement dans le code. +Les ressources peuvent être attachées et détachées à volonté à des déploiements. Par exemple, si la base de données de l'application pose problème pour des raisons matérielles, l'administrateur de l'application peut vouloir lancer un nouveau serveur de base de données restauré à partir d'une sauvegarde récente. L'application courante pourrait être détachée de l'ancienne, puis rattachée à la nouvelle — le tout sans changement dans le code. From d8498e0e3038a38dce4ebdc86116d33ddbb59253 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:28:55 +0100 Subject: [PATCH 376/472] fix typos in build-release-run.md --- content/fr/build-release-run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index 0dc1f5376..99c5da0b5 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -13,7 +13,7 @@ Une [base de code](./codebase) est transformée en un déploiement (non-dévelop Les outils de déploiement offrent généralement des outils de gestion de release, permettant notamment de revenir à une release antérieure. Par exemple, l'outil de déploiement [Capistrano](https://github.com/capistrano/capistrano/wiki) stocke les releases dans un sous-répertoire appelé `releases`, où la release courante est un lien symbolique vers le répertoire de release courante. Sa commande `rollback` permet de facilement revenir à une release précédente. -Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). Les liste des releases est accessible en écriture incrémentale uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. +Chaque release devrait toujours avoir un identifiant unique, comme un horodatage (timestamp) de la release (tel que `2011-04-06-20:32:17`) ou un nombre incrémental (tel que `v100`). La liste des releases est accessible en écriture incrémentale uniquement, et il n'est pas possible de modifier une release une fois qu'elle a été réalisée. Tout changement doit créer une nouvelle release. -Les assemblages sont initiées par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entrainer des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolues par le développeur qui réalise le déploiement. +Les assemblages sont initiés par le développeur de l'application dès que du nouveau code est déployé. Son exécution, au contraire, peut avoir lieu automatiquement en cas d'un reboot du serveur, ou du crash d'un processus qui est relancé par le gestionnaire de processus. De ce fait, l'étape d'exécution doit se limiter à un nombre minimal de parties mobiles, car les problèmes qui empêchent une application de fonctionner peuvent entraîner des dysfonctionnements au milieu de la nuit alors qu'aucun développeur ne sera là pour les corriger. L'étape d'assemblage peut être plus complexe, car les erreurs pourront toujours être résolues par le développeur qui réalise le déploiement. From fb09b59ab5467b9da76c6579618a16bd05daca36 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:36:37 +0100 Subject: [PATCH 377/472] fix typos in processes.md --- content/fr/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/processes.md b/content/fr/processes.md index cc79b9e2b..68ae62cb4 100644 --- a/content/fr/processes.md +++ b/content/fr/processes.md @@ -7,7 +7,7 @@ Dans la situation la plus simple, le code est un script indépendant, l'environn **Les processus 12 facteurs sont sans état et ne partagent [rien (en)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. -L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de données. Les applications 12 facteurs ne supposent jamais que quoi que ce soit qui ait été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est-à-dire en mémoire et sur le disque). +L'espace mémoire ou le système de fichier du processus peut être utilisé comme cache momentané pour des transactions uniques. Par exemple, télécharger un gros fichier, effectuer une opération dessus, puis stocker le résultat de l'opération dans la base de données. Les applications 12 facteurs ne supposent jamais que quelque chose ayant été mis en cache en mémoire ou sur le disque sera disponible dans une future requête ou job — avec plusieurs processus de chaque type qui s'exécutent, il y a de grandes chances qu'une future requête soit effectuée par un processus différent. Même lorsque l'on fait tourner seulement un processus, un redémarrage (déclenché par le déploiement du code, un changement de configuration, ou l'environnement d'exécution qui déplace le processus vers un lieu physique différent) va généralement balayer toutes les modifications locales (c'est-à-dire en mémoire et sur le disque). Des outils de création de paquets de ressources (ou "asset packagers") (tel que [Jammit](http://documentcloud.github.com/jammit/) ou [django-compressor](http://django-compressor.readthedocs.org/)) utilisent le système de fichier comme cache pour les ressources compilées. Une application 12 facteurs préfère faire cette compilation durant l'[étape d'assemblage](./build-release-run), comme avec le [pipeline des ressources de Rails](http://guides.rubyonrails.org/asset_pipeline.html), plutôt que durant l'exécution. From 3bce9d04811810f767e96dc6ddb71f614499443c Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:40:02 +0100 Subject: [PATCH 378/472] fix typos in port-binding.md --- content/fr/port-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/port-binding.md b/content/fr/port-binding.md index d480d5542..09036e959 100644 --- a/content/fr/port-binding.md +++ b/content/fr/port-binding.md @@ -7,7 +7,7 @@ Les applications web sont parfois exécutées à l'intérieur d'un container de 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. +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)). From e54fe991b9adba051244cd6b198fcf9cf1ea01ec Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:45:26 +0100 Subject: [PATCH 379/472] fix typos in concurrency.md --- content/fr/concurrency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index 0b9123d8d..fdc6cade2 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -5,10 +5,10 @@ Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou pl ![La scalabilité est exprimée par des processus qui s'exécutent, la diversité de la charge de travail est exprimée par les types de processus](/images/process-types.png) -**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière plan ayant une longue durée d'exécution peuvent être des processus dits "worker". +**Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière-plan ayant une longue durée d'exécution peuvent être des processus dits "worker". Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrone que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. -Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et le nombre de processus de chaque type est appelée *formation de processus*. +Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et du nombre de processus de chaque type est appelée *formation de processus*. Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. From ca3961a5cec96ef45dc85839d62cc4048f6762fe Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:49:29 +0100 Subject: [PATCH 380/472] Fix typos in concurrency.md again --- content/fr/concurrency.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index fdc6cade2..021404b2d 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -7,8 +7,8 @@ Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou pl **Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière-plan ayant une longue durée d'exécution peuvent être des processus dits "worker". -Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrone que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. +Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrones que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et du nombre de processus de chaque type est appelée *formation de processus*. -Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. A la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. +Les processus des applications 12 facteurs ne devraient [jamais être des daemons (en)](http://dustin.github.com/2010/02/28/running-processes.html) ou écrire des fichiers PID. À la place, utilisez le gestionnaire de processus du système d'exploitation (tel qu'[Upstart](http://upstart.ubuntu.com/), un gestionnaire de processus distribué sur une plateforme cloud, ou un outil comme [Foreman (en)](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durant le développement) pour gérer les [flux de sortie](./logs), répondre à un processus qui plante, et gérer les redémarrages et les arrêts initiés par les utilisateurs. From ab59711a102f2a3a6dee5ee2f6cdc5b68966e9cb Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 19:53:54 +0100 Subject: [PATCH 381/472] fix typos in disposability.md --- content/fr/disposability.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/fr/disposability.md b/content/fr/disposability.md index aac4fe309..9a3620512 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -1,14 +1,14 @@ ## IX. Jetable ### Maximisez la robustesse avec des démarrages rapides et des arrêts gracieux -**Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est à dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustesse des déploiements de production. +**Les [processus](./processes) des applications 12 facteurs sont *jetables*, c'est-à-dire qu'ils peuvent être démarrés ou stoppés en un instant.** Cela simplifie un rapide grossissement vertical, le déploiement rapide du [code](./codebase) ou de changements dans la [configuration](./config), ainsi que la robustesse des déploiements de production. -Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend plus agile les processus de [release](./build-release-run) et de scalabilité verticale; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. +Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement, un processus prend quelques secondes entre le moment où une commande le lance et celui où il est en marche et prêt à recevoir des requêtes ou du travail. Un court temps de démarrage rend les processus de [release](./build-release-run) et de scalabilité verticale plus agiles; il aide également à la robustesse, car les gestionnaires de processus peuvent plus facilement déplacer des processus vers de nouvelles machines physiques lorsque c'est nécessaire. Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problème lorsque la connection est perdue. Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le worker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). -Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non gracieuses. Le [design crash-only (en)](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique (en)](http://docs.couchdb.org/en/latest/intro/overview.html). +Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non-gracieuses. Le [design crash-only (en)](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique (en)](http://docs.couchdb.org/en/latest/intro/overview.html). From 97c3e261ac7e64e538403926049edf3162f6dd99 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 20:18:17 +0100 Subject: [PATCH 382/472] fix typos in dev-prod-parity.md --- content/fr/dev-prod-parity.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index 46db34050..d0a58cdc2 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -38,7 +38,7 @@ Si l'on résume cela en un tableau :
-[Les services externes](./backing-services), tel que la base de données, la file de messages, ou le cache sont des éléments importants de la parité développement/production. La plupart des langages fournissent des bibliothèques qui simplifient l'accès à ces services externes, en fournissant des adaptateurs pour différents types de services. Voici quelques exemples dans le tableau ci dessous. +[Les services externes](./backing-services), tels que la base de données, la file de messages, ou le cache sont des éléments importants de la parité développement/production. La plupart des langages fournissent des bibliothèques qui simplifient l'accès à ces services externes, en fournissant des adaptateurs pour différents types de services. Voici quelques exemples dans le tableau ci-dessous. @@ -69,8 +69,8 @@ Si l'on résume cela en un tableau : Les développeurs trouvent parfois agréable d'utiliser des services externes légers dans leur environnement local, alors qu'un service externe plus sérieux et robuste est utilisé en production. Par exemple, utiliser SQLite en local, et PostgreSQL en production; ou bien, durant le développement, mettre les données en cache dans la mémoire des processus locaux, et utiliser Memcached en production. -**Les développeurs des applications 12 facteurs résistent au besoin d'utiliser des services externes différents entre le développement local et la production**, même lorsque les adaptateurs permettent d'abstraire en théorie beaucoup de différences entre les services externes. Les différences entre les services externes signifient que de petites incompatibilités surviennent, ce qui va faire que du code qui fonctionnait et qui passait les tests durant le développement ou la validation ne fonctionnera pas en production. Ce type d'erreurs crée de la friction en défaveur du déploiement continu. Le coût de cette friction et son impact négatif sur le déploiement continu est extrèmement élevé lorsqu'il est cumulé sur toute la vie de l'application. +**Les développeurs des applications 12 facteurs résistent au besoin d'utiliser des services externes différents entre le développement local et la production**, même lorsque les adaptateurs permettent d'abstraire en théorie beaucoup de différences entre les services externes. Les différences entre les services externes signifient que de petites incompatibilités surviennent, ce qui va faire que du code qui fonctionnait et qui passait les tests durant le développement ou la validation ne fonctionnera pas en production. Ce type d'erreurs crée de la friction en défaveur du déploiement continu. Le coût de cette friction et son impact négatif sur le déploiement continu est extrêmement élevé lorsqu'il est cumulé sur toute la vie de l'application. -Les services locaux légers sont moins attirants aujourd'hui qu'ils ne l'étaient autrefois. Les services externes modernes tel que Memcached, PostgreSQL, et RabbitMQ ne sont pas difficiles à installer et à faire fonctionner grâce aux systèmes de paquets modernes comme [Homebrew](http://mxcl.github.com/homebrew/) et [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Autre possibilité, des outils de provisionnement comme [Chef](http://www.opscode.com/chef/) et [Puppet](http://docs.puppetlabs.com/), combinés à des environnements virtuels légers comme [Vagrant](http://vagrantup.com/) permettent aux développeurs de faire fonctionner des environnements locaux qui reproduisent de très près les environnements de production. Le coût d'installation et d'utilisation de ces systèmes est faible comparé aux bénéfices d'une bonne parité développement/production et du déploiement continu. +Les services locaux légers sont moins attirants aujourd'hui qu'ils ne l'étaient autrefois. Les services externes modernes tels que Memcached, PostgreSQL, et RabbitMQ ne sont pas difficiles à installer et à faire fonctionner grâce aux systèmes de paquets modernes comme [Homebrew](http://mxcl.github.com/homebrew/) et [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Autre possibilité, des outils de provisionnement comme [Chef](http://www.opscode.com/chef/) et [Puppet](http://docs.puppetlabs.com/), combinés à des environnements virtuels légers comme [Vagrant](http://vagrantup.com/) permettent aux développeurs de faire fonctionner des environnements locaux qui reproduisent de très près les environnements de production. Le coût d'installation et d'utilisation de ces systèmes est faible comparé aux bénéfices d'une bonne parité développement/production et du déploiement continu. Les adaptateurs à ces différents systèmes externes sont malgré tout utiles, car ils rendent le portage vers de nouveaux services externes relativement indolores. Mais tous les déploiements de l'application (environnement de développement, validation, production) devraient utiliser le même type et la même version de chacun de ces services externes. From ab0dd32909ffbb53c2a2027d98c21e14f5ae2696 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 20:20:06 +0100 Subject: [PATCH 383/472] fix typos in logs.md --- content/fr/logs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/logs.md b/content/fr/logs.md index 895873032..42191e331 100644 --- a/content/fr/logs.md +++ b/content/fr/logs.md @@ -3,13 +3,13 @@ Les *logs* fournissent de la visibilité au comportement de l'application qui s'exécute. Dans des environnements de type serveur, ils sont généralement écrits dans un fichier, sur le disque (dans un fichier de log). Mais c'est simplement un format de sortie. -Les logs sont des [flux (en)](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) d'aggrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. +Les logs sont des [flux (en)](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) d'agrégats d'évènements, ordonnés dans le temps, collectés à travers les flux de sortie de tous les processus et services externes qui tournent. Les logs, dans leur forme brute, sont au format texte avec un événement par ligne (bien que les traces d'exécutions puissent s'étaler sur plusieurs lignes). Les logs n'ont pas de début ou de fin fixe, mais se remplissent en continu tant que l'application est en marche. **Une application 12 facteurs ne s'inquiète jamais du routage ou du stockage de ses flux de sortie.** Elle ne devrait pas tenter d'écrire ou de gérer les fichiers de logs. À la place, chaque processus qui tourne écrit ses flux d'événements, sans tampon, vers `stdout`, la sortie standard ; en phase de développement local, les développeurs pourront voir ce flux dans leur terminal et observer le comportement de l'application. Dans les déploiements de validation ou de production, les flux de chaque processus seront capturés par leur environnement d'exécution, assemblés avec les autres flux de l'application, et routés vers une ou plusieurs destinations pour un visionnage et un archivage de longue durée. Le lieu d'archivage n'est pas visible et ne peut être configuré par l'application : ils sont complètements gérés par l'environnement d'exécution. Des routeurs opensource de logs, (tel que [Logplex](https://github.com/heroku/logplex) et [Fluent](https://github.com/fluent/fluentd)) existent pour cela. -Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepot de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : +Le flux d'événements d'une application peut être routé dans un fichier, ou surveillé en temps réel (avec tail) dans un terminal. Plus pertinent, les flux peuvent être envoyés vers un outil d'indexation et d'archivage des logs tel que [Splunk](http://www.splunk.com/), ou bien dans un entrepôt de données générique comme [Hadoop/Hive](http://hive.apache.org/). Ces systèmes sont très puissants et flexibles pour inspecter le comportement de l'application au cours du temps, ce qui inclut : * Trouver un événement spécifique dans le passé * Faire des graphiques à grande échelle des tendances (comme le nombre de requêtes par minutes) From 960f0c7d6445bcaa468c7ed0ee020908b5ab8bc8 Mon Sep 17 00:00:00 2001 From: Simon Malesys Date: Wed, 1 Nov 2017 20:26:37 +0100 Subject: [PATCH 384/472] fix typos in admin-processes.md --- content/fr/admin-processes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/admin-processes.md b/content/fr/admin-processes.md index 5e51ba20a..dd57d955a 100644 --- a/content/fr/admin-processes.md +++ b/content/fr/admin-processes.md @@ -4,8 +4,8 @@ La [formation de processus](./concurrency) est la liste des processus qui sont utilisés pour le fonctionnement normal de l'application (comme gérer les requêtes web) lorsqu'elle tourne. Les développeurs vont souvent vouloir effectuer des tâches occasionnelles d'administration ou de maintenance, comme : * Lancer les migrations de base de données (par ex. `manage.py migrate` avec Django, `rake db:migrate` avec Rails). -* Lancer une console (également appelée terminal [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) pour exécuter du code arbitraire ou inspecter les modèles de l'application dans la base de donnée. La plupart des langages fournissent un terminal REPL en lançant l'interpréteur sans arguments (par exemple `python` ou `perl`), ou dans certains cas à l'aide d'une commande dédiée (par ex. `irb` pour Ruby, `rails console` pour Rails). -* Exécuter des scripts ponctuels inclus dans le dépot de code (par ex. `php scripts/fix_bad_records.php`). +* Lancer une console (également appelée terminal [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) pour exécuter du code arbitraire ou inspecter les modèles de l'application dans la base de données. La plupart des langages fournissent un terminal REPL en lançant l'interpréteur sans arguments (par exemple `python` ou `perl`), ou dans certains cas à l'aide d'une commande dédiée (par ex. `irb` pour Ruby, `rails console` pour Rails). +* Exécuter des scripts ponctuels inclus dans le dépôt de code (par ex. `php scripts/fix_bad_records.php`). Les processus ponctuels d'administration devraient être lancés dans un environnement identique à ceux des [processus standards](./processes) de l'application. Ils s'exécutent sur une [release](./build-release-run), en utilisant la même [base de code](./codebase) et [configuration](./config) que tout processus qui tourne pour cette release. Le code d'administration doit être livré avec le code de l'application afin d'éviter les problèmes de synchronisation. From eff1e9c434143de2a5adbc9cc95f3295dc67218d Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Fri, 10 Nov 2017 12:32:32 +0100 Subject: [PATCH 385/472] Correct claims about how Jammit works Props to @stevecrozz: https://github.com/heroku/12factor/pull/9 --- content/en/processes.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/processes.md b/content/en/processes.md index dbd86a7c8..622998403 100644 --- a/content/en/processes.md +++ b/content/en/processes.md @@ -9,7 +9,6 @@ In the simplest case, the code is a stand-alone script, the execution environmen The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. +Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). - From d909fa5813fab834f583017e009070d74d06ca69 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Fri, 10 Nov 2017 12:43:34 +0100 Subject: [PATCH 386/472] Update ru/background.md Props to @greenplace: https://github.com/heroku/12factor/pull/39 --- content/ru/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/background.md b/content/ru/background.md index 5902fa949..b6b41cb66 100644 --- a/content/ru/background.md +++ b/content/ru/background.md @@ -3,6 +3,6 @@ Участники, внёсшие вклад в этот документ, были непосредственно вовлечены в разработку и развёртывание сотен приложений и косвенно были свидетелями разработки, выполнения и масштабирования сотен тысяч приложений во время нашей работы над платформой [Heroku](http://www.heroku.com/). -В этом документе обобщается весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделения особого внимания динамике органического роста приложения с течением времени, динамики сотрудничества разработчиков, работающих над кодовой базой приложения и [устранения последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +В этом документе обобщается весь наш опыт использования и наблюдения за самыми разнообразными SaaS-приложениями в дикой природе. Документ является объединением трёх идеальных подходов к разработке приложений: уделение особого внимания динамике органического роста приложения с течением времени, динамике сотрудничества разработчиков, работающих над кодовой базой приложения, и [устранение последствий эрозии программного обеспечения](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). Наша мотивация заключается в повышении осведомлённости о некоторых системных проблемах, которые мы встретили в практике разработки современных приложений, а также для того, чтобы предоставить общие основные понятия для обсуждения этих проблем и предложить набор общих концептуальных решений этих проблем с сопутствующей терминологией. Формат навеян книгами Мартина Фаулера (Martin Fowler) *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* и *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. From 8b609d79d1b981b781ed26a54d88943b5e41f912 Mon Sep 17 00:00:00 2001 From: Charlie Gleason Date: Fri, 10 Nov 2017 12:01:42 +0000 Subject: [PATCH 387/472] Update processes.md --- content/en/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/processes.md b/content/en/processes.md index 622998403..f63957def 100644 --- a/content/en/processes.md +++ b/content/en/processes.md @@ -9,6 +9,6 @@ In the simplest case, the code is a stand-alone script, the execution environmen The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. -Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. +Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). From 42146f05b0470b4b2004a2b28994266e228b7e20 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Fri, 10 Nov 2017 13:23:23 +0100 Subject: [PATCH 388/472] Fix typo in zh_cn/build-release-run.md Props to @sakeven: https://github.com/heroku/12factor/pull/149 --- content/zh_cn/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/build-release-run.md b/content/zh_cn/build-release-run.md index 838e0418c..09e0f443b 100644 --- a/content/zh_cn/build-release-run.md +++ b/content/zh_cn/build-release-run.md @@ -9,7 +9,7 @@ ![代码被构建,然后和配置结合成为发布版本](/images/release.png) -**12-facfor 应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 +**12-factor 应用严格区分构建,发布,运行这三个步骤。** 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。 部署工具通常都提供了发布管理工具,最引人注目的功能是退回至较旧的发布版本。比如, [Capistrano](https://github.com/capistrano/capistrano/wiki) 将所有发布版本都存储在一个叫 `releases` 的子目录中,当前的在线版本只需映射至对应的目录即可。该工具的 `rollback` 命令可以很容易地实现回退版本的功能。 From 90bd9360576112b46445ad4a6f316e41f0e686cc Mon Sep 17 00:00:00 2001 From: Santiago Blanco Date: Sat, 25 Nov 2017 21:44:46 +0100 Subject: [PATCH 389/472] Update dev-pro-parity with docker Update related to pull request 118: https://github.com/heroku/12factor/pull/118 --- content/es/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/es/dev-prod-parity.md b/content/es/dev-prod-parity.md index abedbc197..8ac2f2c99 100644 --- a/content/es/dev-prod-parity.md +++ b/content/es/dev-prod-parity.md @@ -71,6 +71,6 @@ Los desarrolladores, a veces, caen en la tentación de usar "backing services" l **Un desarrollador "twelve-factor" no cae en la tentación de usar diferentes "backing services" en desarrollo y producción**, incluso cuando los adaptadores teóricamente abstractos están lejos de cualquier diferencia en "backing services". Las diferencias entre los servicios de respaldo tienen que ver con las pequeñas incompatibilidades que surgen de la nada, causando que el código que funciona y pasa los tests en desarrollo o en preproducción, falle en producción. Este tipo de errores provocan conflictos que desincentivan la filosofía del despliegue continuo. El coste de estos conflictos y el enfriamiento subsiguiente del despliegue continuo es extremadamente alto cuando se hace balance del total de tiempo de vida de una aplicación. -Los servicios ligeros locales son menos atractivos que antes. Los "backing services" modernos como Memcached, PostgreSQL, y RabbitMQ no son difíciles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinadas con entornos virtuales ligeros como [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas es bajo comparado con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. +Los servicios ligeros locales son menos atractivos que antes. Los "backing services" modernos como Memcached, PostgreSQL, y RabbitMQ no son difíciles de instalar y ejecutar gracias a los sistemas de gestión de paquetes modernos, como [Homebrew](http://mxcl.github.com/homebrew/) y [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Al mismo tiempo, las herramientas de gestión de la configuración como [Chef](http://www.opscode.com/chef/) y [Puppet](http://docs.puppetlabs.com/) combinadas con entornos virtuales ligeros como [Docker](https://www.docker.com/) o [Vagrant](http://vagrantup.com/) permiten a los desarrolladores ejecutar entornos locales que son muy parecidos a los entornos de producción. El coste de instalar y usar estos sistemas es bajo comparado con el beneficio que se puede obtener de la paridad entre desarrollo y producción y del despliegue continuo. Los adaptadores de los "backing services" todavía son de gran utilidad, porque hacen que cambiar de unos a otros sea un trámite relativamente poco doloroso. No obstante, todos los despliegues de una aplicación (en entornos de desarrollo, preproducción y producción) deberían usar el mismo tipo y versión de cada uno de los "backing services". From fe1bd8d6975d71135b06b939d6519c3895a98946 Mon Sep 17 00:00:00 2001 From: Riccardo Cirimelli Date: Wed, 10 Jan 2018 15:40:48 +0100 Subject: [PATCH 390/472] Fix typo in table --- content/it/dev-prod-parity.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md index a6fbd8b84..37fc2be19 100644 --- a/content/it/dev-prod-parity.md +++ b/content/it/dev-prod-parity.md @@ -29,7 +29,7 @@ Riassumendo tutto in una tabella: - @@ -73,4 +73,4 @@ Gli sviluppatori, inoltre, trovano utile usare dei servizi "leggeri" in fase di 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 ed usare senza difficoltà tramite alcuni sistemi di packaging come [Homebrew](http://mxcl.github.com/homebrew/) ed [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 deploy. -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 deploy di un'applicazione. \ No newline at end of file +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 deploy di un'applicazione. From 14f336c32cdb8fd8de5f974d75f2e864c926f3bd Mon Sep 17 00:00:00 2001 From: max beizer Date: Tue, 16 Jan 2018 16:59:56 -0600 Subject: [PATCH 391/472] Upgrade to ruby 2.4.3 --- .gitignore | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index fa2d9f1f8..365e22148 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .rvmrc .bundle +.tool-versions diff --git a/Gemfile b/Gemfile index 67620ca50..10311cb91 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.3.1' +ruby '2.4.3' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index 9c24f402f..e58ed5cc0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.3.1p112 + ruby 2.4.3p205 BUNDLED WITH - 1.12.5 + 1.16.1 From 6bdece06984f071bb9280bba430387480d6e8096 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 17 Jan 2018 14:39:22 +0100 Subject: [PATCH 392/472] Use Ruby 2.4.3 in Travis too --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 546e58466..e87e82408 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.3.1 + - 2.4.3 script: exit 0 sudo: false From d19fb208dab10990bcb38e03317032f1be0e8295 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Thu, 25 Jan 2018 12:19:50 +0100 Subject: [PATCH 393/472] Update link to MIT license in README --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 804b36250..7ad77407e 100644 --- a/Readme.md +++ b/Readme.md @@ -29,5 +29,5 @@ Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson Translations and edits by: [@sigerello](https://github.com/sigerello), [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott), [@melikeyurtoglu](https://github.com/melikeyurtoglu) and [more](https://github.com/heroku/12factor/graphs/contributors). -Released under the MIT License: http://www.opensource.org/licenses/mit-license.php - +Released under the MIT License: +https://opensource.org/licenses/MIT From fd73a17d1589f19490025e033eec0ea0667e052d Mon Sep 17 00:00:00 2001 From: Arialdo Martini Date: Sun, 14 Jan 2018 11:47:33 +0100 Subject: [PATCH 394/472] As an adjective, "inglese" shouldn't be capitalised --- locales/it.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/it.yml b/locales/it.yml index a2ce7cff0..98c4ada16 100644 --- a/locales/it.yml +++ b/locales/it.yml @@ -4,4 +4,4 @@ it: # A text to make known that the article is a translation not an original. # Empty for English, original. - translation: (Questo testo è una traduzione della versione originale in Inglese.) + translation: (Questo testo è una traduzione della versione originale in inglese.) From 8c52c931f747cc2ec9c38d5d7e41465a0771ce81 Mon Sep 17 00:00:00 2001 From: Arialdo Martini Date: Sun, 14 Jan 2018 11:57:07 +0100 Subject: [PATCH 395/472] Removed all the wrong "d eufoniche" In Italian, the "d eufonica" is a "d" added to the conjunction "e" or to "a" when tehy appear right before words beginning with the same vowel. For example, rather than the wrong: professori e esperti provare a anticipare one should write: professori ed esperti provare ad anticipare The "d eufonica" cannot be put prior words beginning with different vowels. For example: ed inoltre is wrong, and should be written, instead: e inoltre This commit fixes all the wrong "d eufoniche", removing them when they are not justified. It also replaces "ad esempio" with "per esempio", for the same reason. --- content/it/admin-processes.md | 10 +++++----- content/it/background.md | 4 ++-- content/it/backing-services.md | 6 +++--- content/it/build-release-run.md | 10 +++++----- content/it/codebase.md | 6 +++--- content/it/concurrency.md | 8 ++++---- content/it/config.md | 6 +++--- content/it/dependencies.md | 4 ++-- content/it/dev-prod-parity.md | 8 ++++---- content/it/disposability.md | 6 +++--- content/it/intro.md | 4 ++-- content/it/logs.md | 8 ++++---- content/it/port-binding.md | 8 ++++---- content/it/processes.md | 8 ++++---- content/it/toc.md | 4 ++-- content/it/who.md | 2 +- 16 files changed, 51 insertions(+), 51 deletions(-) diff --git a/content/it/admin-processes.md b/content/it/admin-processes.md index 74f7e5ba4..168563c8b 100644 --- a/content/it/admin-processes.md +++ b/content/it/admin-processes.md @@ -1,14 +1,14 @@ ## XII. Processi di Amministrazione ### Esegui i task di amministrazione come processi una tantum -La "[process formation](./concurrency)" è l'array dei processi che vengono usati durante le normali operazioni dell'applicazione (ad esempio, la gestione delle richieste web). Non è tutto, però: ci sono dei task che lo sviluppatore può voler eseguire, una volta ogni tanto. Ad esempio: +La "[process formation](./concurrency)" è l'array dei processi che vengono usati durante le normali operazioni dell'applicazione (per esempio, la gestione delle richieste web). Non è tutto, però: ci sono dei task che lo sviluppatore può voler eseguire, una volta ogni tanto. Per esempio: * Esecuzione delle migration del database (esempi: `manage.py migrate` in Django, `rake db:migrate` in Rails). -* Esecuzione di una console (una [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) in modo tale da avviare del codice arbitrariamente o analizzare alcuni aspetti dell'applicazione specifici. Molti linguaggi prevedono una REPL, in genere avviando l'interprete senza opzioni ed argomenti aggiuntivi (esempi: `python` o `perl`) o in alcuni casi eseguibile con un comando separato (esempi: `irb` per Ruby, `rails console` per Rails). +* Esecuzione di una console (una [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) in modo tale da avviare del codice arbitrariamente o analizzare alcuni aspetti dell'applicazione specifici. Molti linguaggi prevedono una REPL, in genere avviando l'interprete senza opzioni e argomenti aggiuntivi (esempi: `python` o `perl`) o in alcuni casi eseguibile con un comando separato (esempi: `irb` per Ruby, `rails console` per Rails). * Esecuzione one-time di alcuni script specifici (esempio: `php scripts/fix_bad_records.php`). -Tali processi dovrebbero essere avviati in un ambiente identico a quello in cui [lavorano gli altri](./processes) nel contesto dell'applicazione. Dovrebbero essere eseguiti quindi su una specifica [release](./build-release-run), partendo dalla stessa [codebase](./codebase) ed impostazioni di [configurazione](./config). Il codice per l'amministrazione dovrebbe inoltre essere incluso nel codice dell'applicazione, in modo tale da evitare qualsiasi problema di sincronizzazione. +Tali processi dovrebbero essere avviati in un ambiente identico a quello in cui [lavorano gli altri](./processes) nel contesto dell'applicazione. Dovrebbero essere eseguiti quindi su una specifica [release](./build-release-run), partendo dalla stessa [codebase](./codebase) e impostazioni di [configurazione](./config). Il codice per l'amministrazione dovrebbe inoltre essere incluso nel codice dell'applicazione, in modo tale da evitare qualsiasi problema di sincronizzazione. -La stessa tecnica di [isolamento delle dipendenze](./dependencies) dovrebbe poter essere usata allo stesso modo su tutti i processi. Ad esempio, se il processo web di Ruby può usare il comando `bundle exec thin start`, una migration del database dovrebbe poter usare `bundle exec rake db:migrate` senza problemi. Allo stesso modo, un programma Python che usa Virtualenv dovrebbe usare il `bin/python` per eseguire sia i server Tornado che processi di amministrazione. +La stessa tecnica di [isolamento delle dipendenze](./dependencies) dovrebbe poter essere usata allo stesso modo su tutti i processi. Per esempio, se il processo web di Ruby può usare il comando `bundle exec thin start`, una migration del database dovrebbe poter usare `bundle exec rake db:migrate` senza problemi. Allo stesso modo, un programma Python che usa Virtualenv dovrebbe usare il `bin/python` per eseguire sia i server Tornado che processi di amministrazione. -La metodologia twelve-factor favorisce molto tutti quei linguaggi che offrono una shell REPL out of the box, rendendo quindi semplice l'esecuzione di script una tantum. In un deploy locale, gli sviluppatori possono invocare questi processi speciali tramite un semplice comando diretto. In un ambiente di produzione, invece, gli sviluppatori possono raggiungere lo stesso obiettivo tramite SSH o un qualsiasi altro sistema di esecuzione di comandi remoto. \ No newline at end of file +La metodologia twelve-factor favorisce molto tutti quei linguaggi che offrono una shell REPL out of the box, rendendo quindi semplice l'esecuzione di script una tantum. In un deploy locale, gli sviluppatori possono invocare questi processi speciali tramite un semplice comando diretto. In un ambiente di produzione, invece, gli sviluppatori possono raggiungere lo stesso obiettivo tramite SSH o un qualsiasi altro sistema di esecuzione di comandi remoto. diff --git a/content/it/background.md b/content/it/background.md index 19e5f254d..45e1a6d79 100644 --- a/content/it/background.md +++ b/content/it/background.md @@ -1,8 +1,8 @@ Background ========== -Chi ha scritto questo documento è stato coinvolto direttamente nella realizzazione e deploy di centinaia di applicazioni, ed indirettamente assistito allo sviluppo, operazioni e scaling di centinaia (o migliaia) di app tramite il proprio lavoro sulla piattaforma [Heroku](http://www.heroku.com/). +Chi ha scritto questo documento è stato coinvolto direttamente nella realizzazione e deploy di centinaia di applicazioni, e indirettamente assistito allo sviluppo, operazioni e scaling di centinaia (o migliaia) di app tramite il proprio lavoro sulla piattaforma [Heroku](http://www.heroku.com/). Questo documento riassume tutta quella che è stata la nostra esperienza, basata sull'osservazione di un grande numero di applicazioni SaaS. Si tratta di una "triangolazione" di pratiche di sviluppo ideali (con una particolare attenzione alla crescita organica dell'app nel tempo), la collaborazione dinamica nel corso del tempo tra gli sviluppatori sulla codebase e la necessità di evitare i costi di [software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). -La nostra motivazione è di far crescere la consapevolezza intorno ad alcuni problemi sistemici che abbiamo scoperto nello sviluppo di applicazioni moderne, cercando di fornire un vocabolario condiviso per la discussione di tali problemi. Oltre, ovviamente, ad offrire delle soluzioni concettuali a queste situazioni (senza però tralasciare il fattore tecnologia). Questo format si rifà ai libri di Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. \ No newline at end of file +La nostra motivazione è di far crescere la consapevolezza intorno ad alcuni problemi sistemici che abbiamo scoperto nello sviluppo di applicazioni moderne, cercando di fornire un vocabolario condiviso per la discussione di tali problemi. Oltre, ovviamente, a offrire delle soluzioni concettuali a queste situazioni (senza però tralasciare il fattore tecnologia). Questo format si rifà ai libri di Martin Fowler *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* e *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. diff --git a/content/it/backing-services.md b/content/it/backing-services.md index fbde27ef9..666ad0bbe 100644 --- a/content/it/backing-services.md +++ b/content/it/backing-services.md @@ -3,12 +3,12 @@ Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](http://kr.github.com/beanstalkd/)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). -Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), ed anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). +Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), e anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). -**Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). Ad un qualsiasi [deploy](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale ad uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. +**Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). A un qualsiasi [deploy](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale a uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. Ogni backing service è quindi definibile come una "risorsa connessa". Un Database MySQL è una risorsa. Due database MySQL (utilizzati per lo sharding a livello di applicazione) saranno visti come due distinte risorse. Un'app twelve-factor vede questi database come *risorse* anche per sottolineare la separazione dal deploy a cui fanno riferimento. Un deploy di produzione collegato a quattro backing service. -Le risorse possono essere collegate e scollegate da un deploy a piacimento. Ad esempio, supponiamo che il database dell'applicazione si comporti in modo anomalo per problemi hardware. L'amministratore potrebbe decidere di voler configurare un altro server di database ripreso da un recente backup. Il vecchio database verrebbe scollegato, quello nuovo connesso -- senza modifiche al codice. \ No newline at end of file +Le risorse possono essere collegate e scollegate da un deploy a piacimento. Per esempio, supponiamo che il database dell'applicazione si comporti in modo anomalo per problemi hardware. L'amministratore potrebbe decidere di voler configurare un altro server di database ripreso da un recente backup. Il vecchio database verrebbe scollegato, quello nuovo connesso -- senza modifiche al codice. diff --git a/content/it/build-release-run.md b/content/it/build-release-run.md index abe85269d..ce4f73791 100644 --- a/content/it/build-release-run.md +++ b/content/it/build-release-run.md @@ -3,16 +3,16 @@ Una [codebase](./codebase) viene "trasformata" in deploy attraverso tre fasi: -* la fase di *build*, che converte il codice del repo in una build "eseguibile". Usando una certa versione del codice, ad una specifica commit, nella fase di build vengono compilati i binari con gli asset appropriati includendo anche le eventuali dipendenze; +* la fase di *build*, che converte il codice del repo in una build "eseguibile". Usando una certa versione del codice, a una specifica commit, nella fase di build vengono compilati i binari con gli asset appropriati includendo anche le eventuali dipendenze; * la fase di *release* prende la build prodotta nella fase precedente e la combina con l'attuale insieme di impostazioni di configurazione del deploy specifico. La *release* risultante contiene sia la build che le impostazioni; * la fase di *esecuzione* (conosciuta anche come "runtime") vede l'applicazione in esecuzione nell'ambiente di destinazione, attraverso l'avvio di processi della release scelta; ![Il codice diventa build, che combinata con le impostazioni diventa release.](/images/release.png) -**Un'app twelve-factor definisce una separazione netta tra build, release ed esecuzione.** Ad esempio, è impossibile effettuare dei cambiamenti del codice a runtime, dato che non c'è modo di propagare queste modifiche all'"indietro", verso la fase di build. +**Un'app twelve-factor definisce una separazione netta tra build, release ed esecuzione.** Per esempio, è impossibile effettuare dei cambiamenti del codice a runtime, dato che non c'è modo di propagare queste modifiche all'"indietro", verso la fase di build. -I tool di deploy offrono tipicamente dei tool di gestione delle release, in particolare alcuni dedicati ad un rollback verso una release precedente. Ad esempio, [Capistrano](https://github.com/capistrano/capistrano/wiki) memorizza le varie release in una sotto-directory chiamata `releases`, in cui la release attuale non è che un symlink verso la directory della release attuale. Il comando di rollback permette di tornare indietro ad una certa release velocemente. +I tool di deploy offrono tipicamente dei tool di gestione delle release, in particolare alcuni dedicati a un rollback verso una release precedente. Per esempio, [Capistrano](https://github.com/capistrano/capistrano/wiki) memorizza le varie release in una sotto-directory chiamata `releases`, in cui la release attuale non è che un symlink verso la directory della release attuale. Il comando di rollback permette di tornare indietro a una certa release velocemente. -Ogni release dovrebbe inoltre possedere un ID univoco di rilascio, come ad esempio un timestamp (es. `2011-04-06-20:32:17`) o un numero incrementale (es. `v100`). In un certo senso, la creazione di una release è una procedura "a senso unico" e una certa release non può essere modificata dopo la sua creazione. Qualsiasi cambiamento deve quindi prevedere una nuova release. +Ogni release dovrebbe inoltre possedere un ID univoco di rilascio, come per esempio un timestamp (es. `2011-04-06-20:32:17`) o un numero incrementale (es. `v100`). In un certo senso, la creazione di una release è una procedura "a senso unico" e una certa release non può essere modificata dopo la sua creazione. Qualsiasi cambiamento deve quindi prevedere una nuova release. -Una fase di build è sempre avviata da uno sviluppatore, non appena il codice viene modificato. Al contrario, l'esecuzione può essere anche gestita in modo automatico (si pensi al riavvio del server oppure ad un crash con successivo riavvio del processo). Ad ogni modo, una volta in esecuzione, la regola aurea è di evitare il più possibile (se non del tutto) modifiche che potrebbero rompere qualche equilibrio. Magari nel bel mezzo della notte, quando non c'è nessuno disponibile. La fase di build può essere sicuramente più "faticosa", comunque, visto che possono verificarsi degli errori da risolvere prima di proseguire. \ No newline at end of file +Una fase di build è sempre avviata da uno sviluppatore, non appena il codice viene modificato. Al contrario, l'esecuzione può essere anche gestita in modo automatico (si pensi al riavvio del server oppure a un crash con successivo riavvio del processo). A ogni modo, una volta in esecuzione, la regola aurea è di evitare il più possibile (se non del tutto) modifiche che potrebbero rompere qualche equilibrio. Magari nel bel mezzo della notte, quando non c'è nessuno disponibile. La fase di build può essere sicuramente più "faticosa", comunque, visto che possono verificarsi degli errori da risolvere prima di proseguire. diff --git a/content/it/codebase.md b/content/it/codebase.md index 61b63e66b..0771fd938 100644 --- a/content/it/codebase.md +++ b/content/it/codebase.md @@ -7,11 +7,11 @@ Una *codebase* è quindi un singolo repository (in un sistema centralizzato come ![Una codebase, N deploy](/images/codebase-deploys.png) -C'è sempre una relazione uno-ad-uno tra codebase ed applicazione: +C'è sempre una relazione uno-ad-uno tra codebase e applicazione: -* Se ci sono più codebase, non si parla più di applicazione ma di sistema distribuito. Ogni componente in un sistema distribuito è un'applicazione, ed ognuna di queste applicazioni può individualmente aderire alla metodologia twelve-factor. +* Se ci sono più codebase, non si parla più di applicazione ma di sistema distribuito. Ogni componente in un sistema distribuito è un'applicazione, e ognuna di queste applicazioni può individualmente aderire alla metodologia twelve-factor. * Se più applicazioni condividono lo stesso codice si ha una violazione del twelve-factor. La soluzione è, ovviamente, quella di sistemare il codice in modo adeguato, in modo tale da essere incluso eventualmente dove necessario tramite un [dependency manager](./dependencies). Quindi: una sola codebase per applicazione, ma ci saranno comunque tanti deploy della stessa app. Per *deploy* si intende un'istanza dell'applicazione. Può essere il software in produzione, oppure una delle varie istanze in staging. Ancora, un deploy può essere la copia posseduta dal singolo sviluppatore nel suo ambiente locale. -La codebase rimane comunque sempre la stessa su tutti i deploy, anche se potrebbero essere attive diverse versioni nello stesso istante. Si pensi ad esempio ad uno sviluppatore che possiede dei commit in più che non ha ancora mandato in staging. Nonostante questo, comunque, rimane la condivisione della stessa codebase, nonostante la possibilità di avere più deploy della stessa app. \ No newline at end of file +La codebase rimane comunque sempre la stessa su tutti i deploy, anche se potrebbero essere attive diverse versioni nello stesso istante. Si pensi per esempio a uno sviluppatore che possiede dei commit in più che non ha ancora mandato in staging. Nonostante questo, comunque, rimane la condivisione della stessa codebase, nonostante la possibilità di avere più deploy della stessa app. diff --git a/content/it/concurrency.md b/content/it/concurrency.md index 727d83a8c..c0c851a91 100644 --- a/content/it/concurrency.md +++ b/content/it/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Concorrenza ### Scalare attraverso il process model -Ogni software, una volta avviato, è rappresentato da uno o più processi. Le web application in particolare hanno assunto nel tempo una gran varietà di forme e di tipologie di esecuzione, in tal senso. Ad esempio, i processi PHP vengono eseguiti come sotto-processi figli di Apache, avviati su richiesta quando necessari in base al volume di richieste. Java invece gestisce le cose nella maniera opposta, tramite un superprocesso unico che usa una grande quantità di risorse sul server (CPU e memoria) dall'avvio, con una concorrenza gestita "internamente" tramite i threads. In entrambi i casi, comunque, i processi non sono esplicitamente visibili allo sviluppatore. +Ogni software, una volta avviato, è rappresentato da uno o più processi. Le web application in particolare hanno assunto nel tempo una gran varietà di forme e di tipologie di esecuzione, in tal senso. Per esempio, i processi PHP vengono eseguiti come sotto-processi figli di Apache, avviati su richiesta quando necessari in base al volume di richieste. Java invece gestisce le cose nella maniera opposta, tramite un superprocesso unico che usa una grande quantità di risorse sul server (CPU e memoria) dall'avvio, con una concorrenza gestita "internamente" tramite i threads. In entrambi i casi, comunque, i processi non sono esplicitamente visibili allo sviluppatore. ![Il fattore di scale è espresso con un numero di processi dello stesso tipo avviati, la diversità del carico di lavoro, invece, come le varie tipologie di processo.](/images/process-types.png) -**In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro ad un tipo di processo ben definito. Ad esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. +**In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro a un tipo di processo ben definito. Per esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. -Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo ed interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. +Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo e interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. -Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice ed affidabile. L'array dei tipi di processo ed il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). +Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice e affidabile. L'array dei tipi di processo e il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). I processi di un'app twelve-factor non dovrebbero [essere soggetti a daemonizing](http://dustin.github.com/2010/02/28/running-processes.html), o scrivere file PID. Al contrario, facendo affidamento sul process manager del sistema operativo (come [systemd](https://www.freedesktop.org/wiki/Software/systemd/), un process manager distribuito su piattaforma cloud, o tool come [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) durante lo sviluppo) per gestire [gli stream in output](./logs), rispondere adeguatamente a crash di processi e gestire riavvii e shutdown. diff --git a/content/it/config.md b/content/it/config.md index 2ef8dc89e..c9ead28ea 100644 --- a/content/it/config.md +++ b/content/it/config.md @@ -3,7 +3,7 @@ La "configurazione" di un'applicazione è tutto quello che può variare da un [deploy](./codebase) all'altro (staging, production, ambienti di sviluppo). Ad esempio: -* Valori da usare per connettersi ad un database, Memcached, oppure altri [backing service](./backing-services); +* Valori da usare per connettersi a un database, Memcached, oppure altri [backing service](./backing-services); * Credenziali per servizi esterni, come Amazon S3 o Twitter; * Valori eventualmente definiti per i singoli deploy, come l'hostname; @@ -13,10 +13,10 @@ Il codice dell'applicazione, infatti, potrebbe essere reso open-source in ogni m Nota che comunque la definizione di "configurazione" **non** include eventuali configurazione interne dell'applicazione, come `config/routes.rb` in Rails, o come [i moduli di codice sono connessi](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). Questo tipo di configurazione non varia da deploy a deploy: come giusto che sia, quindi, rimane nel codice. -Un ottimo approccio al "rispetto" di questo principio consiste nell'usare dei file di configurazione non coinvolti dal version control, come ad esempio `config/database.yml` in Rails. Stiamo parlando di un miglioramento enorme rispetto all'uso di costanti nel codice, ma c'è da dire la cosa ha il suo lato negativo: basta poco per sbagliarsi ed includere nel repo il file di configurazione che, invece, non dovrebbe essere lì. C'è una certa tendenza, infatti, a non avere tutti i file di configurazione necessari nello stesso posto. Inoltre, i vari formati tendono ad essere collegati ad un certo linguaggio/framework. +Un ottimo approccio al "rispetto" di questo principio consiste nell'usare dei file di configurazione non coinvolti dal version control, come per esempio `config/database.yml` in Rails. Stiamo parlando di un miglioramento enorme rispetto all'uso di costanti nel codice, ma c'è da dire la cosa ha il suo lato negativo: basta poco per sbagliarsi e includere nel repo il file di configurazione che, invece, non dovrebbe essere lì. C'è una certa tendenza, infatti, a non avere tutti i file di configurazione necessari nello stesso posto. Inoltre, i vari formati tendono a essere collegati a un certo linguaggio/framework. **L'applicazione che rispetta la metodologia twelve-factor memorizza tutte le impostazioni in *variabili d'ambiente*** (spesso dette *env vars* o *env*). Le variabili d'ambiente sono molto semplici da cambiare di deploy in deploy senza dover toccare il codice direttamente. Inoltre, a differenza dei file di configurazione classici, c'è una probabilità molto bassa di venire inclusi nel repo. Infine, questi file sono indipendenti sia dal linguaggio che dal sistema operativo utilizzato. -Un altro aspetto del config management è il raggruppamento. A volte, infatti, alcune applicazioni prevedono la memorizzazione delle impostazioni in gruppi (chiamati spesso "ambienti") dal nome ben preciso: "development", "test" e "production", ad esempio. Questo metodo non scala correttamente, se ci pensi: potrebbero essere necessari nuovi ambienti, come "staging" e "qa". Oppure, i vari sviluppatori potrebbero aver bisogno di creare i propri ambienti "speciali", come "joes-staging" e così via. Il risultato? Una quantità di combinazioni ingestibile e disordinata. +Un altro aspetto del config management è il raggruppamento. A volte, infatti, alcune applicazioni prevedono la memorizzazione delle impostazioni in gruppi (chiamati spesso "ambienti") dal nome ben preciso: "development", "test" e "production", per esempio. Questo metodo non scala correttamente, se ci pensi: potrebbero essere necessari nuovi ambienti, come "staging" e "qa". Oppure, i vari sviluppatori potrebbero aver bisogno di creare i propri ambienti "speciali", come "joes-staging" e così via. Il risultato? Una quantità di combinazioni ingestibile e disordinata. In una buona twelve-factor app, le variabili di ambiente sono controllate in modo più "granulare", in modo totalmente ortogonale alle altre. Non sono mai raggruppate e classificate sotto "ambienti" specifici, ma vengono gestite in modo totalmente indipendente per ogni deploy. Il prodotto finale ne risente positivamente in termini di scalabilità. \ No newline at end of file diff --git a/content/it/dependencies.md b/content/it/dependencies.md index 8a002c163..cfc7408ee 100644 --- a/content/it/dependencies.md +++ b/content/it/dependencies.md @@ -1,11 +1,11 @@ ## II. Dipendenze -### Dipendenze dichiarate ed isolate +### Dipendenze dichiarate e isolate Molti linguaggi di programmazione offrono dei sistemi di packaging per la distribuzione delle proprie librerie, come [CPAN](http://www.cpan.org/) per Perl o [Rubygems](http://rubygems.org/) per Ruby. Le librerie installate attraverso questi sistemi, inoltre, possono essere identificate come "system-wide" (attive a livello di sistema), oppure posizionate nella directory della singola applicazione (in questo caso si parla di "vendoring" o "bundling"). **Un'applicazione che aderisce alla twelve-factor non si basa mai sull'esistenza implicita di librerie system-wide**. Le dipendenze vengono tutte dichiarate, tramite un manifest dedicato. Inoltre, viene contemplato anche l'uso di un tool di *isolamento delle dipendenze* durante l'esecuzione, in modo tale da assicurarsi che non ci siano delle "dipendenze implicite" che creino interferenze nel sistema in cui ci si trova. La specifica completa ed esplicita delle dipendenze si applica in modo uniforme: sia in production che in sviluppo. -Ad esempio, [Bundler](https://bundler.io/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione ed isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. +Per esempio, [Bundler](https://bundler.io/) per Ruby offre il supporto di un file-manifesto `Gemfile` da usare per la dichiarazione delle dipendenze e `bundle exec` per il loro isolamento. In Python invece troviamo altri due tool per questi scopi -- [Pip](http://www.pip-installer.org/en/latest/) viene usato per la dichiarazione e [Virtualenv](http://www.virtualenv.org/en/latest/) per l'isolamento. Anche C ha [Autoconf](http://www.gnu.org/s/autoconf/) per la dichiarazione di dipendenze, mentre lo static linking si occupa dell'isolamento. Non importa quale sia il toolchain usato, le operazioni di dichiarazione e isolamento vanno sempre effettuate. In caso contrario, l'applicazione non aderisce più alla metodologia. Un altro importante beneficio di una dichiarazione esplicita delle dipendenze sta nel fatto che semplifica di molto la configurazione iniziale per gli sviluppatori appena entrati a lavorare al progetto. Il nuovo arrivato non dovrà fare altro che effettuare un check out della codebase nella propria macchina di sviluppo, occupandosi di dover installare solo ed esclusivamente le dipendenze, appunto, dichiarate. Molto spesso è inoltre presente un *build command* che permette di automatizzare il processo. Per Ruby/Bundler si usa `bundle install`, mentre per Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) c'è `lein deps`. diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md index 37fc2be19..33232f904 100644 --- a/content/it/dev-prod-parity.md +++ b/content/it/dev-prod-parity.md @@ -1,11 +1,11 @@ ## 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 ad un [deploy](./codebase) in locale) e quello di produzione (un deploy in esecuzione raggiungibile dagli utenti finali). Differenze (o gap) che si possono raggruppare in tre categorie: +Storicamente, ci sono sempre state differenze sostanziali tra gli ambienti di sviluppo (lo sviluppatore che effettua delle modifiche live a un [deploy](./codebase) in locale) e quello di produzione (un deploy 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 deploy; -* **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite ed OS X, mentre in produzione per il deploy verrebbero installati Apache, MySQL e Linux. +* **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite e OS X, mentre in produzione per il deploy 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: @@ -67,10 +67,10 @@ I [backing service](./backing-services), come il database dell'applicazione o la
Sviluppatori e Ops Sono diversiSono gli stessi/td> + Sono gli stessi
Sviluppo e Produzione
-Gli sviluppatori, inoltre, trovano utile usare dei servizi "leggeri" in fase di sviluppo, passando quindi a qualcosa di più serio e robusto in produzione. Ad esempio, usando SQLite localmente e PostgreSQL in produzone. Ancora, un sistema di cache in locale in fase di sviluppo e Memcached in produzione. +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 produzone. 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 ed usare senza difficoltà tramite alcuni sistemi di packaging come [Homebrew](http://mxcl.github.com/homebrew/) ed [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 deploy. +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 deploy. 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 deploy di un'applicazione. diff --git a/content/it/disposability.md b/content/it/disposability.md index 876d59cd3..dcc61af49 100644 --- a/content/it/disposability.md +++ b/content/it/disposability.md @@ -5,8 +5,8 @@ I processi dovrebbero inoltre ambire a **minimizzare i tempi di avvio**. Idealmente, un processo impiega pochi secondi dal tempo di lancio al momento in cui tutto è pronto per ricevere nuove richieste. Dei tempi brevi di avvio inoltre forniscono una maggiore agilità in fase di [release](./build-release-run); il tutto a vantaggio della robustezza dell'applicazione, dato che il process manager può così muoversi agevolmente verso un'altra macchina fisica, se necessario. -I processi dovrebbero inoltre **terminare in modo tutt'altro che brusco, quindi graduale, in caso di ricezione di un segnale [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** dal process manager. Per un'applicazione web, la giusta terminazione di un processo viene ottenuta quando si cessa innanzitutto di ascoltare sulla porta dedicata del servizio (evitando quindi di ricevere altre richieste), permettendo poi di terminare le richieste esistenti ed infine di concludere la fase di terminazione in modo definitivo. +I processi dovrebbero inoltre **terminare in modo tutt'altro che brusco, quindi graduale, in caso di ricezione di un segnale [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** dal process manager. Per un'applicazione web, la giusta terminazione di un processo viene ottenuta quando si cessa innanzitutto di ascoltare sulla porta dedicata del servizio (evitando quindi di ricevere altre richieste), permettendo poi di terminare le richieste esistenti e infine di concludere la fase di terminazione in modo definitivo. -Per un processo worker, invece, la fase di terminazione più adatta vede il ritorno del job corrente alla coda. Ad esempio, su [RabbitMQ](http://www.rabbitmq.com/) il worker può inviare un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); su [Beanstalkd](http://kr.github.com/beanstalkd/), il job viene automaticamente rimandato in coda nel caso in cui il worker si disconnette. I sistemi basati su lock come [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) prevedono una "messa in sicurezza" prima di rilasciare il loro lock sul record del job attuale. Basandosi su questo modello risulta implicito che tutti i vari job sono di tipo [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), obiettivo raggiungibile wrappando il risultato in una transazione o rendendo l'operazione [idempotente](http://en.wikipedia.org/wiki/Idempotence). +Per un processo worker, invece, la fase di terminazione più adatta vede il ritorno del job corrente alla coda. Per esempio, su [RabbitMQ](http://www.rabbitmq.com/) il worker può inviare un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); su [Beanstalkd](http://kr.github.com/beanstalkd/), il job viene automaticamente rimandato in coda nel caso in cui il worker si disconnette. I sistemi basati su lock come [Delayed Date: Mon, 15 Jan 2018 18:59:01 +0100 Subject: [PATCH 396/472] who.md has a correct use of the subjunctive tense --- content/it/who.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/who.md b/content/it/who.md index 767c55298..03d7cd8c0 100644 --- a/content/it/who.md +++ b/content/it/who.md @@ -1,4 +1,4 @@ A chi è destinato questo documento? ============================== -A ogni sviluppatore che costruisce applicazioni SaaS (Software As a Service), e a ogni ops che effettua il deploy e gestisce queste applicazioni. +A ogni sviluppatore che costruisa applicazioni SaaS (Software As a Service), e a ogni ops che effettui il deploy e gestisci queste applicazioni. From 6c13c52590508def421998146ce500cbacbe17b1 Mon Sep 17 00:00:00 2001 From: Arialdo Martini Date: Mon, 15 Jan 2018 19:05:44 +0100 Subject: [PATCH 397/472] Typo: i log i presentano => i log si presentano --- content/it/logs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/logs.md b/content/it/logs.md index 2d7c78e40..58f93f405 100644 --- a/content/it/logs.md +++ b/content/it/logs.md @@ -3,7 +3,7 @@ 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 i 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 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. From 32402ec0560ecf6c81e3f861b89b3c7f7fa2b7e9 Mon Sep 17 00:00:00 2001 From: Arialdo Martini Date: Sat, 17 Feb 2018 11:09:45 +0100 Subject: [PATCH 398/472] deploy -> deployment when used as a noun --- content/it/admin-processes.md | 2 +- content/it/background.md | 2 +- content/it/backing-services.md | 10 +++++----- content/it/build-release-run.md | 6 +++--- content/it/codebase.md | 6 +++--- content/it/config.md | 12 ++++++------ content/it/dev-prod-parity.md | 12 ++++++------ content/it/port-binding.md | 2 +- content/it/processes.md | 4 ++-- content/it/toc.md | 2 +- 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/content/it/admin-processes.md b/content/it/admin-processes.md index 168563c8b..327282d0a 100644 --- a/content/it/admin-processes.md +++ b/content/it/admin-processes.md @@ -11,4 +11,4 @@ Tali processi dovrebbero essere avviati in un ambiente identico a quello in cui La stessa tecnica di [isolamento delle dipendenze](./dependencies) dovrebbe poter essere usata allo stesso modo su tutti i processi. Per esempio, se il processo web di Ruby può usare il comando `bundle exec thin start`, una migration del database dovrebbe poter usare `bundle exec rake db:migrate` senza problemi. Allo stesso modo, un programma Python che usa Virtualenv dovrebbe usare il `bin/python` per eseguire sia i server Tornado che processi di amministrazione. -La metodologia twelve-factor favorisce molto tutti quei linguaggi che offrono una shell REPL out of the box, rendendo quindi semplice l'esecuzione di script una tantum. In un deploy locale, gli sviluppatori possono invocare questi processi speciali tramite un semplice comando diretto. In un ambiente di produzione, invece, gli sviluppatori possono raggiungere lo stesso obiettivo tramite SSH o un qualsiasi altro sistema di esecuzione di comandi remoto. +La metodologia twelve-factor favorisce molto tutti quei linguaggi che offrono una shell REPL out of the box, rendendo quindi semplice l'esecuzione di script una tantum. In un deployment locale, gli sviluppatori possono invocare questi processi speciali tramite un semplice comando diretto. In un ambiente di produzione, invece, gli sviluppatori possono raggiungere lo stesso obiettivo tramite SSH o un qualsiasi altro sistema di esecuzione di comandi remoto. diff --git a/content/it/background.md b/content/it/background.md index 45e1a6d79..7552707aa 100644 --- a/content/it/background.md +++ b/content/it/background.md @@ -1,7 +1,7 @@ Background ========== -Chi ha scritto questo documento è stato coinvolto direttamente nella realizzazione e deploy di centinaia di applicazioni, e indirettamente assistito allo sviluppo, operazioni e scaling di centinaia (o migliaia) di app tramite il proprio lavoro sulla piattaforma [Heroku](http://www.heroku.com/). +Chi ha scritto questo documento è stato coinvolto direttamente nella realizzazione e nel deployment di centinaia di applicazioni, e ha indirettamente assistito allo sviluppo, le operazioni e lo scaling di centinaia (o migliaia) di app tramite il proprio lavoro sulla piattaforma [Heroku](http://www.heroku.com/). Questo documento riassume tutta quella che è stata la nostra esperienza, basata sull'osservazione di un grande numero di applicazioni SaaS. Si tratta di una "triangolazione" di pratiche di sviluppo ideali (con una particolare attenzione alla crescita organica dell'app nel tempo), la collaborazione dinamica nel corso del tempo tra gli sviluppatori sulla codebase e la necessità di evitare i costi di [software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). diff --git a/content/it/backing-services.md b/content/it/backing-services.md index 666ad0bbe..43fb210f4 100644 --- a/content/it/backing-services.md +++ b/content/it/backing-services.md @@ -3,12 +3,12 @@ Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](http://kr.github.com/beanstalkd/)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). -Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deploy dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), e anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). +Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deployment dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), e anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). -**Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). A un qualsiasi [deploy](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale a uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. +**Il codice di un'app twelve-factor non fa distinzioni tra servizi in locale o third party**. Per l'applicazione, entrambi sono risorse connesse, accessibili via URL (o tramite un altro locator) e credenziali memorizzate nell'opportuno file di [configurazione](./config). A un qualsiasi [deployment](./codebase) di un'applicazione twelve-factor si deve poter permettere di passare velocemente da un database MySQL locale a uno third party (come [Amazon RDS](http://aws.amazon.com/rds/)) senza alcuna modifica al codice. Allo stesso modo, un server SMTP locale dovrebbe poter essere cambiato con uno third party (come Postmark). In entrambi i casi, a cambiare dovrebbero essere **solo** i file di configurazione necessari. -Ogni backing service è quindi definibile come una "risorsa connessa". Un Database MySQL è una risorsa. Due database MySQL (utilizzati per lo sharding a livello di applicazione) saranno visti come due distinte risorse. Un'app twelve-factor vede questi database come *risorse* anche per sottolineare la separazione dal deploy a cui fanno riferimento. +Ogni backing service è quindi definibile come una "risorsa connessa". Un Database MySQL è una risorsa. Due database MySQL (utilizzati per lo sharding a livello di applicazione) saranno visti come due distinte risorse. Un'app twelve-factor vede questi database come *risorse* anche per sottolineare la separazione dal deployment a cui fanno riferimento. -Un deploy di produzione collegato a quattro backing service. +Un deployment di produzione collegato a quattro backing service. -Le risorse possono essere collegate e scollegate da un deploy a piacimento. Per esempio, supponiamo che il database dell'applicazione si comporti in modo anomalo per problemi hardware. L'amministratore potrebbe decidere di voler configurare un altro server di database ripreso da un recente backup. Il vecchio database verrebbe scollegato, quello nuovo connesso -- senza modifiche al codice. +Le risorse possono essere collegate e scollegate da un deployment a piacimento. Per esempio, supponiamo che il database dell'applicazione si comporti in modo anomalo per problemi hardware. L'amministratore potrebbe decidere di voler configurare un altro server di database ripreso da un recente backup. Il vecchio database verrebbe scollegato, quello nuovo connesso -- senza modifiche al codice. diff --git a/content/it/build-release-run.md b/content/it/build-release-run.md index ce4f73791..96927e3b1 100644 --- a/content/it/build-release-run.md +++ b/content/it/build-release-run.md @@ -1,17 +1,17 @@ ## V. Build, release, esecuzione ### Separare in modo netto lo stadio di build dall'esecuzione -Una [codebase](./codebase) viene "trasformata" in deploy attraverso tre fasi: +Una [codebase](./codebase) viene "trasformata" in deployment attraverso tre fasi: * la fase di *build*, che converte il codice del repo in una build "eseguibile". Usando una certa versione del codice, a una specifica commit, nella fase di build vengono compilati i binari con gli asset appropriati includendo anche le eventuali dipendenze; -* la fase di *release* prende la build prodotta nella fase precedente e la combina con l'attuale insieme di impostazioni di configurazione del deploy specifico. La *release* risultante contiene sia la build che le impostazioni; +* la fase di *release* prende la build prodotta nella fase precedente e la combina con l'attuale insieme di impostazioni di configurazione del deployment specifico. La *release* risultante contiene sia la build che le impostazioni; * la fase di *esecuzione* (conosciuta anche come "runtime") vede l'applicazione in esecuzione nell'ambiente di destinazione, attraverso l'avvio di processi della release scelta; ![Il codice diventa build, che combinata con le impostazioni diventa release.](/images/release.png) **Un'app twelve-factor definisce una separazione netta tra build, release ed esecuzione.** Per esempio, è impossibile effettuare dei cambiamenti del codice a runtime, dato che non c'è modo di propagare queste modifiche all'"indietro", verso la fase di build. -I tool di deploy offrono tipicamente dei tool di gestione delle release, in particolare alcuni dedicati a un rollback verso una release precedente. Per esempio, [Capistrano](https://github.com/capistrano/capistrano/wiki) memorizza le varie release in una sotto-directory chiamata `releases`, in cui la release attuale non è che un symlink verso la directory della release attuale. Il comando di rollback permette di tornare indietro a una certa release velocemente. +I tool di deployment offrono tipicamente dei tool di gestione delle release, in particolare alcuni dedicati a un rollback verso una release precedente. Per esempio, [Capistrano](https://github.com/capistrano/capistrano/wiki) memorizza le varie release in una sotto-directory chiamata `releases`, in cui la release attuale non è che un symlink verso la directory della release attuale. Il comando di rollback permette di tornare indietro a una certa release velocemente. Ogni release dovrebbe inoltre possedere un ID univoco di rilascio, come per esempio un timestamp (es. `2011-04-06-20:32:17`) o un numero incrementale (es. `v100`). In un certo senso, la creazione di una release è una procedura "a senso unico" e una certa release non può essere modificata dopo la sua creazione. Qualsiasi cambiamento deve quindi prevedere una nuova release. diff --git a/content/it/codebase.md b/content/it/codebase.md index 0771fd938..e7669a05c 100644 --- a/content/it/codebase.md +++ b/content/it/codebase.md @@ -5,13 +5,13 @@ Un'app conforme alla metodologia twelve-factor è sempre sotto un sistema di con Una *codebase* è quindi un singolo repository (in un sistema centralizzato come Subversion), oppure un set di repo che condividono una root commit (in un sistema di controllo decentralizzato come Git). -![Una codebase, N deploy](/images/codebase-deploys.png) +![Una codebase, N deployment](/images/codebase-deploys.png) C'è sempre una relazione uno-ad-uno tra codebase e applicazione: * Se ci sono più codebase, non si parla più di applicazione ma di sistema distribuito. Ogni componente in un sistema distribuito è un'applicazione, e ognuna di queste applicazioni può individualmente aderire alla metodologia twelve-factor. * Se più applicazioni condividono lo stesso codice si ha una violazione del twelve-factor. La soluzione è, ovviamente, quella di sistemare il codice in modo adeguato, in modo tale da essere incluso eventualmente dove necessario tramite un [dependency manager](./dependencies). -Quindi: una sola codebase per applicazione, ma ci saranno comunque tanti deploy della stessa app. Per *deploy* si intende un'istanza dell'applicazione. Può essere il software in produzione, oppure una delle varie istanze in staging. Ancora, un deploy può essere la copia posseduta dal singolo sviluppatore nel suo ambiente locale. +Quindi: una sola codebase per applicazione, ma ci saranno comunque tanti deployment della stessa app. Per *deploy* si intende un'istanza dell'applicazione. Può essere il software in produzione, oppure una delle varie istanze in staging. Ancora, un deploy può essere la copia posseduta dal singolo sviluppatore nel suo ambiente locale. -La codebase rimane comunque sempre la stessa su tutti i deploy, anche se potrebbero essere attive diverse versioni nello stesso istante. Si pensi per esempio a uno sviluppatore che possiede dei commit in più che non ha ancora mandato in staging. Nonostante questo, comunque, rimane la condivisione della stessa codebase, nonostante la possibilità di avere più deploy della stessa app. +La codebase rimane comunque sempre la stessa su tutti i deployment, anche se potrebbero essere attive diverse versioni nello stesso istante. Si pensi per esempio a uno sviluppatore che possiede dei commit in più che non ha ancora mandato in staging. Nonostante questo, comunque, rimane la condivisione della stessa codebase, nonostante la possibilità di avere più deploy della stessa app. diff --git a/content/it/config.md b/content/it/config.md index c9ead28ea..656dca8e2 100644 --- a/content/it/config.md +++ b/content/it/config.md @@ -1,22 +1,22 @@ ## III. Configurazione ### Memorizza le informazioni di configurazione nell'ambiente -La "configurazione" di un'applicazione è tutto quello che può variare da un [deploy](./codebase) all'altro (staging, production, ambienti di sviluppo). Ad esempio: +La "configurazione" di un'applicazione è tutto quello che può variare da un [deployment](./codebase) all'altro (staging, production, ambienti di sviluppo). Ad esempio: * Valori da usare per connettersi a un database, Memcached, oppure altri [backing service](./backing-services); * Credenziali per servizi esterni, come Amazon S3 o Twitter; -* Valori eventualmente definiti per i singoli deploy, come l'hostname; +* Valori eventualmente definiti per i singoli deployment, come l'hostname; -Molto spesso, queste informazioni vengono memorizzate come costanti nel codice: la cosa viola la metodologia twelve-factor, che richiede una **separazione ben definita delle impostazioni di configurazione dal codice**. Le impostazioni possono infatti variare da un deploy all'altro: il codice, invece, no. +Molto spesso, queste informazioni vengono memorizzate come costanti nel codice: la cosa viola la metodologia twelve-factor, che richiede una **separazione ben definita delle impostazioni di configurazione dal codice**. Le impostazioni possono infatti variare da un deployment all'altro: il codice, invece, no. Il codice dell'applicazione, infatti, potrebbe essere reso open-source in ogni momento: un buon motivo per separare le due cose. -Nota che comunque la definizione di "configurazione" **non** include eventuali configurazione interne dell'applicazione, come `config/routes.rb` in Rails, o come [i moduli di codice sono connessi](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). Questo tipo di configurazione non varia da deploy a deploy: come giusto che sia, quindi, rimane nel codice. +Nota che comunque la definizione di "configurazione" **non** include eventuali configurazione interne dell'applicazione, come `config/routes.rb` in Rails, o come [i moduli di codice sono connessi](http://static.springsource.org/spring/docs/2.5.x/reference/beans.html) in [Spring](http://www.springsource.org/). Questo tipo di configurazione non varia da deployment a deployment: come giusto che sia, quindi, rimane nel codice. Un ottimo approccio al "rispetto" di questo principio consiste nell'usare dei file di configurazione non coinvolti dal version control, come per esempio `config/database.yml` in Rails. Stiamo parlando di un miglioramento enorme rispetto all'uso di costanti nel codice, ma c'è da dire la cosa ha il suo lato negativo: basta poco per sbagliarsi e includere nel repo il file di configurazione che, invece, non dovrebbe essere lì. C'è una certa tendenza, infatti, a non avere tutti i file di configurazione necessari nello stesso posto. Inoltre, i vari formati tendono a essere collegati a un certo linguaggio/framework. -**L'applicazione che rispetta la metodologia twelve-factor memorizza tutte le impostazioni in *variabili d'ambiente*** (spesso dette *env vars* o *env*). Le variabili d'ambiente sono molto semplici da cambiare di deploy in deploy senza dover toccare il codice direttamente. Inoltre, a differenza dei file di configurazione classici, c'è una probabilità molto bassa di venire inclusi nel repo. Infine, questi file sono indipendenti sia dal linguaggio che dal sistema operativo utilizzato. +**L'applicazione che rispetta la metodologia twelve-factor memorizza tutte le impostazioni in *variabili d'ambiente*** (spesso dette *env vars* o *env*). Le variabili d'ambiente sono molto semplici da cambiare di deployment in deployment senza dover toccare il codice direttamente. Inoltre, a differenza dei file di configurazione classici, c'è una probabilità molto bassa di venire inclusi nel repo. Infine, questi file sono indipendenti sia dal linguaggio che dal sistema operativo utilizzato. Un altro aspetto del config management è il raggruppamento. A volte, infatti, alcune applicazioni prevedono la memorizzazione delle impostazioni in gruppi (chiamati spesso "ambienti") dal nome ben preciso: "development", "test" e "production", per esempio. Questo metodo non scala correttamente, se ci pensi: potrebbero essere necessari nuovi ambienti, come "staging" e "qa". Oppure, i vari sviluppatori potrebbero aver bisogno di creare i propri ambienti "speciali", come "joes-staging" e così via. Il risultato? Una quantità di combinazioni ingestibile e disordinata. -In una buona twelve-factor app, le variabili di ambiente sono controllate in modo più "granulare", in modo totalmente ortogonale alle altre. Non sono mai raggruppate e classificate sotto "ambienti" specifici, ma vengono gestite in modo totalmente indipendente per ogni deploy. Il prodotto finale ne risente positivamente in termini di scalabilità. \ No newline at end of file +In una buona twelve-factor app, le variabili di ambiente sono controllate in modo più "granulare", in modo totalmente ortogonale alle altre. Non sono mai raggruppate e classificate sotto "ambienti" specifici, ma vengono gestite in modo totalmente indipendente per ogni deployment. Il prodotto finale ne risente positivamente in termini di scalabilità. \ No newline at end of file diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md index 33232f904..7e1218f30 100644 --- a/content/it/dev-prod-parity.md +++ b/content/it/dev-prod-parity.md @@ -1,11 +1,11 @@ ## 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 [deploy](./codebase) in locale) e quello di produzione (un deploy in esecuzione raggiungibile dagli utenti finali). Differenze (o gap) che si possono raggruppare in tre categorie: +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 deploy; -* **Strumenti**: gli sviluppatori potrebbero usare uno stack quale Nginx, SQLite e OS X, mentre in produzione per il deploy verrebbero installati Apache, MySQL e Linux. +* **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: @@ -22,7 +22,7 @@ Riassumendo tutto in una tabella: App Twelve-factor - Tempo tra i Deploy + Tempo tra i Deployment Settimane Ore @@ -71,6 +71,6 @@ Gli sviluppatori, inoltre, trovano utile usare dei servizi "leggeri" in fase di **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 deploy. +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 deploy di un'applicazione. +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. diff --git a/content/it/port-binding.md b/content/it/port-binding.md index 1378b0e4b..e6cc9c1a0 100644 --- a/content/it/port-binding.md +++ b/content/it/port-binding.md @@ -5,7 +5,7 @@ Normalmente, le applicazioni web sono qualcosa di eseguito all'interno di un ser **L'applicazione twelve-factor** è completamente self-contained (contenuta in se stessa) e non si affida a un altro servizio (come appunto un webserver) nell'ambiente di esecuzione. La web app **esporta HTTP come un servizio effettuando un binding specifico a una porta**, rimanendo in ascolto su tale porta per le richieste in entrata. -In un ambiente di sviluppo locale, lo sviluppatore accede al servizio tramite un URL come `http://localhost:5000/`. In fase di deploy, invece, un layer di routing gestisce le richieste da un hostname pubblico alla specifica porta desiderata. +In un ambiente di sviluppo locale, lo sviluppatore accede al servizio tramite un URL come `http://localhost:5000/`. In fase di deployment, invece, un layer di routing gestisce le richieste da un hostname pubblico alla specifica porta desiderata. Tale funzionalità viene, frequentemente, implementata tramite [dichiarazione delle opportune dipendenze](./dependencies), aggiungendo una libreria webserver all'applicazionecome [Tornado](http://www.tornadoweb.org/) per Python, [Thin](http://code.macournoyer.com/thin/) per Ruby, o [Jetty](http://www.eclipse.org/jetty/) per Java e altri linguaggi basati su JVM. L'evento, nella sua interezza, "ha luogo" nello spazio dell'utente, nel codice dell'applicazione. diff --git a/content/it/processes.md b/content/it/processes.md index 88a7ad54e..97407cc80 100644 --- a/content/it/processes.md +++ b/content/it/processes.md @@ -3,11 +3,11 @@ L'app viene eseguita nell'ambiente di esecuzione come uno o più *processi*. -Nel caso più semplice, il codice non è che uno script stand-alone, l'ambiente di esecuzione è il laptop dello sviluppatore e il processo viene lanciato tramite linea di comando (per esempio, `python my_script.py`). Tuttavia, il deploy in produzione di un'app sofisticata potrebbe usare più [tipologie di processo, istanziate in zero o più processi](./concurrency). +Nel caso più semplice, il codice non è che uno script stand-alone, l'ambiente di esecuzione è il laptop dello sviluppatore e il processo viene lanciato tramite linea di comando (per esempio, `python my_script.py`). Tuttavia, il deployment in produzione di un'app sofisticata potrebbe usare più [tipologie di processo, istanziate in zero o più processi](./concurrency). ***I processi twelve-factor sono stateless (senza stato) e [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Tutti i dati che devono persistere devono essere memorizzati in un [backing service](./backing-services), come per esempio un database. -Lo spazio di memoria o il filesystem di un processo possono essere visti come una "singola transazione" breve. Come il download di un file, le successive operazioni su di esso e infine la memorizzazione del risultato sul database. Un'app twelve-factor non assume mai che qualsiasi cosa messa in cache sarà poi disponibile successivamente -- con tanti processi in esecuzione, le possibilità che una certa richiesta venga servita da un altro processo sono molto alte. Comunque, anche nel caso in cui si usi un singolo processo in esecuzione, un riavvio (dovuto a deploy di codice, cambio di file di configurazione e così via) resetterà lo stato in cui si trova il sistema. +Lo spazio di memoria o il filesystem di un processo possono essere visti come una "singola transazione" breve. Come il download di un file, le successive operazioni su di esso e infine la memorizzazione del risultato sul database. Un'app twelve-factor non assume mai che qualsiasi cosa messa in cache sarà poi disponibile successivamente -- con tanti processi in esecuzione, le possibilità che una certa richiesta venga servita da un altro processo sono molto alte. Comunque, anche nel caso in cui si usi un singolo processo in esecuzione, un riavvio (dovuto a deployment di codice, cambio di file di configurazione e così via) resetterà lo stato in cui si trova il sistema. I packager di asset (come [Jammit](http://documentcloud.github.com/jammit/) o [django-compressor](http://django-compressor.readthedocs.org/)) usano il filesystem come cache per gli asset compilati. Un'app twelve-factor vuole questa compilazione durante la [fase di build](./build-release-run), così come [l'asset pipeline di Rails](http://guides.rubyonrails.org/asset_pipeline.html), e non a runtime. diff --git a/content/it/toc.md b/content/it/toc.md index c225b63e1..074f8745c 100644 --- a/content/it/toc.md +++ b/content/it/toc.md @@ -2,7 +2,7 @@ I "Dodici Fattori" ================== ## [I. Codebase](./codebase) -### Una sola codebase sotto controllo di versione, tanti deploy +### Una sola codebase sotto controllo di versione, tanti deployment ## [II. Dipendenze](./dependencies) ### Dipendenze dichiarate e isolate From ac28bc852fc77bb0a957d0f0a8b76d35742af61c Mon Sep 17 00:00:00 2001 From: Arialdo Martini Date: Sat, 17 Feb 2018 11:15:30 +0100 Subject: [PATCH 399/472] typos in the verb tenses --- content/it/who.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/who.md b/content/it/who.md index 03d7cd8c0..a9ab92943 100644 --- a/content/it/who.md +++ b/content/it/who.md @@ -1,4 +1,4 @@ A chi è destinato questo documento? ============================== -A ogni sviluppatore che costruisa applicazioni SaaS (Software As a Service), e a ogni ops che effettui il deploy e gestisci queste applicazioni. +A ogni sviluppatore che costruisca applicazioni SaaS (Software As a Service), e a ogni ops che effettui il deploy e gestisca queste applicazioni. From 4e10c3dcf2579ef53994c2ae86a25440a03148f6 Mon Sep 17 00:00:00 2001 From: Fernando Nomellini Date: Thu, 15 Mar 2018 08:50:54 -0300 Subject: [PATCH 400/472] Typo in portuguese MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit correção da palavra "entretando". --- content/pt_br/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt_br/codebase.md b/content/pt_br/codebase.md index 26a6a75da..91d46fcb9 100644 --- a/content/pt_br/codebase.md +++ b/content/pt_br/codebase.md @@ -14,4 +14,4 @@ Existe sempre uma correlação um-para-um entre a base de código e a aplicaçã Existe apenas uma base de código por aplicação, mas existirão vários deploys da mesma. Um *deploy* (ou implantação) é uma instância executando a aplicação. Isto é tipicamente um local de produção, e um ou mais locais de testes. Adicionalmente, todo desenvolvedor tem uma cópia da aplicação rodando em seu ambiente local de desenvolvimento, cada um desses pode ser qualificado como um deploy. -A base de código é a mesma através de todos os deploys, entretando diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não implantados no ambiente de teste, o ambiente de teste ainda tem registros não implantados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. +A base de código é a mesma através de todos os deploys, entretanto diferentes versões podem estar ativas em cada deploy. Por exemplo, um desenvolvedor tem alguns registros ainda não implantados no ambiente de teste, o ambiente de teste ainda tem registros não implantados em produção. Mas todos esses ambientes compartilham a mesma base de código, tornando-os identificáveis ​​como diferentes deploys do mesmo app. From 48cf7000824d300431528780e01e1755b9091606 Mon Sep 17 00:00:00 2001 From: Hannes Fostie Date: Wed, 4 Apr 2018 13:51:10 +0200 Subject: [PATCH 401/472] bump ruby to 2.5.1 --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 10311cb91..3c0dd669f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.4.3' +ruby '2.5.1' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index e58ed5cc0..27bffd26c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.4.3p205 + ruby 2.5.1p57 BUNDLED WITH 1.16.1 From cb19dba660a6cfb658085f4b5640455b3ea91bce Mon Sep 17 00:00:00 2001 From: Hannes Fostie Date: Wed, 4 Apr 2018 14:13:04 +0200 Subject: [PATCH 402/472] change ruby on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e87e82408..9fff394d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.4.3 + - 2.5.1 script: exit 0 sudo: false From 5700113f4e633bbb7afbf7a5720389b0dbec4ef0 Mon Sep 17 00:00:00 2001 From: Hoai-Thu Vuong Date: Sat, 7 Jul 2018 20:27:52 +0700 Subject: [PATCH 403/472] move colon outside bold style to look like other lines --- content/en/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/dev-prod-parity.md b/content/en/dev-prod-parity.md index 0eef17945..e771d163c 100644 --- a/content/en/dev-prod-parity.md +++ b/content/en/dev-prod-parity.md @@ -3,7 +3,7 @@ Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The time gap**: A developer may work on code that takes days, weeks, or even months to go into production. * **The personnel gap**: Developers write code, ops engineers deploy it. * **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. From eb044a045a354468ff1a4763819b0cfd66d79a94 Mon Sep 17 00:00:00 2001 From: Thibault Ducret Date: Fri, 27 Jul 2018 10:01:32 +0200 Subject: [PATCH 404/472] =?UTF-8?q?'0'=20to=20'z=C3=A9ro'=20because=20'0'?= =?UTF-8?q?=20looks=20like=20'o',=20which=20is=20confusing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently, they already corrected it in the English version? --- content/fr/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/processes.md b/content/fr/processes.md index 68ae62cb4..7b0d56459 100644 --- a/content/fr/processes.md +++ b/content/fr/processes.md @@ -3,7 +3,7 @@ L'application est exécutée dans l'environnement d'exécution comme un ou plusieurs *processus*. -Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiquée peut utiliser plusieurs [types de processus, instanciés dans 0 ou plus processus en fonctionnement](./concurrency). +Dans la situation la plus simple, le code est un script indépendant, l'environnement d'exécution est l'ordinateur portable du développeur sur lequel est installé de quoi exécuter le langage, et le processus est lancé depuis la ligne de commande. (par exemple, `python mon_script.py`). De l'autre côté du spectre, un déploiement de production d'une application sophistiquée peut utiliser plusieurs [types de processus, instanciés dans zéro ou plus processus en fonctionnement](./concurrency). **Les processus 12 facteurs sont sans état et ne partagent [rien (en)](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Toute donnée qui doit être persistée doit être stockée dans un [service externe](./backing-services) stateful, typiquement une base de données. From 8185d60d5d7b8e8ea454bfe9ba72d48960a01dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Souza?= Date: Mon, 30 Jul 2018 14:00:29 -0300 Subject: [PATCH 405/472] =?UTF-8?q?Corrige=20gram=C3=A1tica=20e=20melhora?= =?UTF-8?q?=20tradu=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Justificativas sobre as alterações: 1. O termo "às vezes" leva crase no trecho modificado, como explicado em https://duvidas.dicio.com.br/as-vezes-ou-as-vezes/ 1. Doze-fatores é uma metodologia, portanto "a doze-fatores" é mais consistente com o resto do texto. Por exemplo, na introdução utiliza-se "a metodologia doze-fatores": https://github.com/heroku/12factor/blob/master/content/pt_br/intro.md 1. No texto original, lê-se: "This is a violation of twelve-factor, which requires strict separation [...]". Neste sentido, "which" refere-se a "twelve-factor" e não a "violation", portanto a tradução precisa é "a qual" (a metodologia doze-fatores). 1. No texto original, lê-se "strict separation of config from code". Neste sentido, "from" não indica origem ("a partir de"), e sim distância (conceitual) entre as duas coisas. Literalmente, poderíamos traduzir como "estrita separação da configuração do código", mas assim parece que a configuração pertence ao código. Mais claro é "estrita separação entre configuração e código". 1. No texto original, lê-se "named groups [...] named after specific deploys". Literalmente, a tradução seria "grupos nomeados [...] nomeados de acordo com deploys específicos", mas convenhamos que a leitura fica ruim. A alternativa "homenagear" tem esse tom inesperado de celebração. Mais neutro é "remeter". --- content/pt_br/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/config.md b/content/pt_br/config.md index a6abb1bce..e4c11387d 100644 --- a/content/pt_br/config.md +++ b/content/pt_br/config.md @@ -7,7 +7,7 @@ A *configuração* de uma aplicação é tudo o que é provável variar entre [d * Credenciais para serviços externos como Amazon S3 ou Twitter * Valores por deploy como o nome canônico do host para o deploy -Aplicações as vezes armazenam as configurações no código como constantes. Isto é uma violação do doze-fatores, o que exige uma **estrita separação da configuração a partir do código**. Configuração varia substancialmente entre deploys, código não. +Aplicações às vezes armazenam as configurações no código como constantes. Isto é uma violação da doze-fatores, a qual exige uma **estrita separação entre configuração e código**. Configuração varia substancialmente entre deploys, código não. A prova de fogo para saber se uma aplicação tem todas as configurações corretamente consignadas fora do código é saber se a base de código poderia ter seu código aberto ao público a qualquer momento, sem comprometer as credenciais. @@ -17,6 +17,6 @@ Outra abordagem para configuração é o uso de arquivos de configuração que n **A aplicação doze-fatores armazena configuração em *variáveis de ambiente*** (muitas vezes abreviadas para *env vars* ou *env*). Env vars são fáceis de mudar entre deploys sem alterar qualquer código; ao contrário de arquivos de configuração, há pouca chance de serem colocados acidentalmente no repositório do código; e ao contrário dos arquivos de configuração personalizados, ou outros mecanismos de configuração como Propriedades do Sistema Java, eles são por padrão agnósticos a linguagem e ao SO. -Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, as aplicações incluem a configuração em grupos nomeados (muitas vezes chamados de ambientes) em homenagem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. +Outro aspecto do gerenciamento de configuração é o agrupamento. Às vezes, as aplicações incluem a configuração em grupos nomeados (muitas vezes chamados de ambientes) que remetem a deploys específicos, tais como os ambientes `development`, `test`, e `production` em Rails. Este método não escala de forma limpa: quanto mais deploys da aplicação são criados, novos nomes de ambiente são necessários, tais como `staging` ou `qa`. A medida que o projeto cresce ainda mais, desenvolvedores podem adicionar seus próprios ambientes especiais como `joes-staging`, resultando em uma explosão combinatória de configurações que torna o gerenciamento de deploys da aplicação muito frágil. Em uma aplicação doze-fatores, env vars são controles granulares, cada um totalmente ortogonal às outras env vars. Elas nunca são agrupadas como "environments", mas em vez disso são gerenciadas independentemente para cada deploy. Este é um modelo que escala sem problemas à medida que o app naturalmente se expande em muitos deploys durante seu ciclo de vida. From 331f913065965061110bf7c5792e0122fda98f67 Mon Sep 17 00:00:00 2001 From: SilverFox Date: Wed, 1 Aug 2018 06:23:39 +0800 Subject: [PATCH 406/472] fix typo in Chinese translation --- content/zh_cn/background.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/background.md b/content/zh_cn/background.md index abcdedddb..32d89ff1c 100644 --- a/content/zh_cn/background.md +++ b/content/zh_cn/background.md @@ -1,7 +1,7 @@ 背景 ========== -本文的贡献者者参与过数以百计的应用程序的开发和部署,并通过 [Heroku](http://www.heroku.com/) 平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 +本文的贡献者参与过数以百计的应用程序的开发和部署,并通过 [Heroku](http://www.heroku.com/) 平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 本文综合了我们关于 SaaS 应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何 [避免软件污染](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/) 。 From c36ee52d2199770316f8cc6939a5c7ea28cd33a6 Mon Sep 17 00:00:00 2001 From: Guyllaume Doyer Date: Wed, 3 Oct 2018 10:47:44 +0200 Subject: [PATCH 407/472] Fixes typo in FR translation --- content/fr/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/build-release-run.md b/content/fr/build-release-run.md index 99c5da0b5..ae76a3b19 100644 --- a/content/fr/build-release-run.md +++ b/content/fr/build-release-run.md @@ -3,7 +3,7 @@ Une [base de code](./codebase) est transformée en un déploiement (non-développement) à travers les étapes suivantes : -* L'*étapes d'assemblage* (ou "build") est une transformation qui convertit un dépôt de code en un paquet autonome exécutable appelé l'assemblage (ou "build"). En utilisant une version du code référencée par un commit spécifié lors du processus de déploiement, l'étape d'assemblage va chercher toutes les [dépendances externes](./dependencies) et compile les fichiers binaires et les ressources. +* L'*étape d'assemblage* (ou "build") est une transformation qui convertit un dépôt de code en un paquet autonome exécutable appelé l'assemblage (ou "build"). En utilisant une version du code référencée par un commit spécifié lors du processus de déploiement, l'étape d'assemblage va chercher toutes les [dépendances externes](./dependencies) et compile les fichiers binaires et les ressources. * L'*étape de publication * (ou "release") prend l'assemblage produit à l'étape précédente et le combine avec la [configuration](./config) de déploiement courante. La release résultante contient à la fois l'assemblage et la configuration, et elle est prête pour une exécution immédiate dans l'environnement d'exécution. * L'*étape d'exécution* (ou "runtime") fait fonctionner l'application dans l'environnement d'exécution, en lançant un ensemble de [processus](./processes) de l'application associée à la release considérée. From 5618341154dbfd79712b9fe08cfdaf36c525f4d3 Mon Sep 17 00:00:00 2001 From: Hannes Fostie Date: Mon, 8 Oct 2018 15:40:58 +0200 Subject: [PATCH 408/472] upgrade stack to heroku-18 --- app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app.json b/app.json index 70e3f19a4..9e07c3198 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,6 @@ { "name": "12factor", + "stack": "heroku-18", "scripts": { }, "env": { From 740f177aac9d2820157761da50a2bb3bde5ec2e6 Mon Sep 17 00:00:00 2001 From: Artur Szott Date: Sat, 13 Oct 2018 14:22:44 +0200 Subject: [PATCH 409/472] Change text displayed on google search results for PL locale --- locales/pl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.yml b/locales/pl.yml index fb77304b9..2364030c8 100644 --- a/locales/pl.yml +++ b/locales/pl.yml @@ -4,4 +4,4 @@ pl: # A text to make known that the article is a translation not an original. # Empty for English, original. - translation: "To jest tłumaczenie." + translation: "- edycja polska" From 27df529c0d5c8e5e5b752372c33d4775c28e0497 Mon Sep 17 00:00:00 2001 From: David Routen Date: Tue, 23 Oct 2018 18:15:03 -0400 Subject: [PATCH 410/472] Upgrade to Ruby 2.5.3 due to prodsec issues: https://github.com/heroku/prodsec/issues/631 --- .ruby-version | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 000000000..aedc15bb0 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.5.3 diff --git a/Gemfile b/Gemfile index 3c0dd669f..74131e760 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.5.1' +ruby '2.5.3' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index 27bffd26c..4c6f38a0f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.5.1p57 + ruby 2.5.3p105 BUNDLED WITH - 1.16.1 + 1.16.6 From 3ec1a303411f1fbfde4eb19b4bfc2e10c438d510 Mon Sep 17 00:00:00 2001 From: David Routen Date: Tue, 23 Oct 2018 18:20:30 -0400 Subject: [PATCH 411/472] Travis.yml was still set to 2.5.1... --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9fff394d9..3f53bbd4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.5.1 + - 2.5.3 script: exit 0 sudo: false From d4ca0b69202c56ce6b9f8d76a5baf40a66aca703 Mon Sep 17 00:00:00 2001 From: David Routen Date: Tue, 6 Nov 2018 11:59:03 +0100 Subject: [PATCH 412/472] Upgraded Rack version for issue: https://github.com/heroku/prodsec/issues/655. --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4c6f38a0f..516f82ffa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,7 +5,7 @@ GEM eventmachine (1.2.0.1) i18n (0.7.0) maruku (0.7.2) - rack (1.6.4) + rack (1.6.11) rack-protection (1.5.3) rack rack-ssl-enforcer (0.2.9) From 590a3ce3b8e24cb17cf827a013e9682bf8eec4ee Mon Sep 17 00:00:00 2001 From: Hannes Fostie Date: Tue, 20 Nov 2018 13:47:08 +0100 Subject: [PATCH 413/472] replace beanstalkd website --- content/de/backing-services.md | 2 +- content/de/disposability.md | 2 +- content/en/backing-services.md | 2 +- content/en/disposability.md | 2 +- content/es/backing-services.md | 2 +- content/es/disposability.md | 2 +- content/fr/backing-services.md | 2 +- content/fr/disposability.md | 2 +- content/it/backing-services.md | 2 +- content/it/disposability.md | 2 +- content/ja/backing-services.md | 2 +- content/ja/disposability.md | 2 +- content/ko/backing-services.md | 4 ++-- content/ko/disposability.md | 8 ++++---- content/pl/backing-services.md | 2 +- content/pl/disposability.md | 2 +- content/pt_br/backing-services.md | 2 +- content/pt_br/disposability.md | 2 +- content/ru/backing-services.md | 2 +- content/ru/disposability.md | 2 +- content/tr/backing-services.md | 2 +- content/tr/disposability.md | 2 +- content/uk/backing-services.md | 4 ++-- content/uk/disposability.md | 4 ++-- content/zh_cn/backing-services.md | 2 +- content/zh_cn/disposability.md | 4 ++-- 26 files changed, 33 insertions(+), 33 deletions(-) diff --git a/content/de/backing-services.md b/content/de/backing-services.md index 7a4790207..283ed2d0d 100644 --- a/content/de/backing-services.md +++ b/content/de/backing-services.md @@ -1,7 +1,7 @@ ## IV. Unterstützende Dienste ### Unterstützende Dienste als angehängte Ressourcen behandeln -Ein *unterstützender Dienst* ist jeder Dienst, den die App über das Netzwerk im Rahmen ihrer normalen Arbeit konsumiert. Beispiele sind Datenspeicher (wie [MySQL](http://dev.mysql.com/) oder [CouchDB](http://couchdb.apache.org/)), Messaging/Queueing-Systeme (wie [RabbitMQ](http://www.rabbitmq.com/) oder [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP-Dienste für das Senden von Mail (wie [Postfix](http://www.postfix.org/)), und Cache-Systeme (wie [Memcached](http://memcached.org/)). +Ein *unterstützender Dienst* ist jeder Dienst, den die App über das Netzwerk im Rahmen ihrer normalen Arbeit konsumiert. Beispiele sind Datenspeicher (wie [MySQL](http://dev.mysql.com/) oder [CouchDB](http://couchdb.apache.org/)), Messaging/Queueing-Systeme (wie [RabbitMQ](http://www.rabbitmq.com/) oder [Beanstalkd](https://beanstalkd.github.io)), SMTP-Dienste für das Senden von Mail (wie [Postfix](http://www.postfix.org/)), und Cache-Systeme (wie [Memcached](http://memcached.org/)). 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](https://developers.google.com/maps/), oder [Last.fm](http://www.last.fm/api)). diff --git a/content/de/disposability.md b/content/de/disposability.md index 1237d199c..3d15f925e 100644 --- a/content/de/disposability.md +++ b/content/de/disposability.md @@ -7,6 +7,6 @@ Prozesse sollten **möglichst geringe Startup-Zeiten** haben. Idealerweise brauc 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](https://beanstalkd.github.io) 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/en/backing-services.md b/content/en/backing-services.md index 732a69b90..3474e1165 100644 --- a/content/en/backing-services.md +++ b/content/en/backing-services.md @@ -1,7 +1,7 @@ ## IV. Backing services ### Treat backing services as attached resources -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). +A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](https://beanstalkd.github.io)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). diff --git a/content/en/disposability.md b/content/en/disposability.md index 085f2d721..4725ef581 100644 --- a/content/en/disposability.md +++ b/content/en/disposability.md @@ -7,7 +7,7 @@ Processes should strive to **minimize startup time**. Ideally, a process takes 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](http://kr.github.com/beanstalkd/), 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). +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). diff --git a/content/es/backing-services.md b/content/es/backing-services.md index 7b14e5b27..ab5c94da0 100644 --- a/content/es/backing-services.md +++ b/content/es/backing-services.md @@ -1,7 +1,7 @@ ## IV. Backing services ### Tratar a los "backing services" como recursos conectables -Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](http://kr.github.com/beanstalkd/)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). +Un *backing service* es cualquier recurso que la aplicación puede consumir a través de la red como parte de su funcionamiento habitual. Entre otros ejemplos, podemos encontrar bases de datos (como [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), los sistemas de mensajería y de colas (como [RabbitMQ](http://www.rabbitmq.com/) o [Beanstalkd](https://beanstalkd.github.io)), los servicios SMTP de email (como [Postfix](http://www.postfix.org/)), y los sistemas de cache (como [Memcached](http://memcached.org/)). Tradicionalmente, los "backing services" (como las bases de datos) han sido gestionadas por los mismos administradores de sistemas que despliegan la aplicacion en producción. Además de esos servicios gestionados localmente, las aplicaciones también pueden usar servicios proporcionados y gestionados por terceros, como por ejemplo los servicios SMTP ([Postmark](http://postmarkapp.com/)), los servicios de recopilación de métricas (como [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), los servicios de activos binarios (como [Amazon S3](http://aws.amazon.com/s3/)), e incluso servicios que se consumen accediendo a ellos mediante un API (como [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). diff --git a/content/es/disposability.md b/content/es/disposability.md index 9900459f7..d010e39c4 100644 --- a/content/es/disposability.md +++ b/content/es/disposability.md @@ -7,6 +7,6 @@ Los procesos deberían intentar conseguir **minimizar el tiempo de arranque**. E Los procesos **se paran de manera segura cuando reciben una señal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** desde el gestor de procesos. Un proceso web para de manera segura cuando deja de escuchar el puerto asociado al servicio (así rechaza cualquier nueva petición), permitiendo que cualquier petición termine de procesarse y pueda finalizar sin problemas. Implícitamente, según este modelo, las peticiones HTTP son breves (no duran más de unos pocos segundos) y, en el caso de un sondeo largo, el cliente debería intentar reconectar una y otra vez cuando se pierda la conexión. -Para finalizar de manera segura, un trabajador (o "worker") debe devolver el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](http://kr.github.com/beanstalkd/), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implícitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). +Para finalizar de manera segura, un trabajador (o "worker") debe devolver el trabajo actual a una cola de trabajos. Por ejemplo, en [RabbitMQ](http://www.rabbitmq.com/) un trabajador puede mandar un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); en [Beanstalkd](https://beanstalkd.github.io), el trabajo se devuelve a una cola automáticamente en el momento en el que el trabajador finaliza. Los sistemas de exclusión mutua como [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) necesitan estar seguros para liberar su candado en el registro de trabajos. Implícitamente, según este modelo, todos los trabajos son [reentrantes](https://es.wikipedia.org/wiki/Reentrancia_%28inform%C3%A1tica%29), lo que se consigue normalmente generando los resultados de manera transaccional, o convirtiendo la operación en [idempotente](http://es.wikipedia.org/wiki/Idempotencia). Los procesos deberían estar **preparados contra finalizaciones inesperadas**, como en el caso de un fallo a nivel hardware. Aunque es un caso más raro que una finalización mediante la señal `SIGTERM`, se puede dar el caso. Lo recomendable es usar un sistema de colas robusto, como Beanstalkd, que devuelve los trabajos a su cola cuando los clientes se desconectan o expira su tiempo de espera ("timeout"). En cualquier caso, una aplicación "twelve-factor" es una arquitectura que trata finalizaciones inesperadas y peligrosas. El [diseño Crash-only](http://lwn.net/Articles/191059/) lleva este concepto a su [conclusión lógica](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/fr/backing-services.md b/content/fr/backing-services.md index c8551bd02..e5e67d897 100644 --- a/content/fr/backing-services.md +++ b/content/fr/backing-services.md @@ -1,7 +1,7 @@ ## IV. Services externes ### Traitez les services externes comme des ressources attachées -Un *service externe* (backing service) correspond à tout service que l'application utilise à travers le réseau pour son fonctionnement nominal. Cela concerne par exemple les bases de données (tel que [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), les systèmes de messages/files (tel que [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), les services SMTP pour l'envoi d'email (comme [Postfix](http://www.postfix.org/)), ainsi que les systèmes de cache (comme [Memcached](http://memcached.org/)). +Un *service externe* (backing service) correspond à tout service que l'application utilise à travers le réseau pour son fonctionnement nominal. Cela concerne par exemple les bases de données (tel que [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), les systèmes de messages/files (tel que [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](https://beanstalkd.github.io)), les services SMTP pour l'envoi d'email (comme [Postfix](http://www.postfix.org/)), ainsi que les systèmes de cache (comme [Memcached](http://memcached.org/)). Les *services externes* comme la base de données sont le plus souvent gérés par les mêmes administrateurs réseau que ceux qui gèrent l'application de production. En plus de ces services gérés localement, l'application peut également avoir besoin de services gérés par des tiers. Cela concerne par exemple les services SMTP (comme [Postmark](http://postmarkapp.com/)), les services de gestion de métriques (comme [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), les services de ressources binaires (comme [Amazon S3](http://aws.amazon.com/s3/)), et même les services que l'on peut consommer à travers une API (comme [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), ou [Last.fm](http://www.last.fm/api)). diff --git a/content/fr/disposability.md b/content/fr/disposability.md index 9a3620512..61afcdfdd 100644 --- a/content/fr/disposability.md +++ b/content/fr/disposability.md @@ -7,7 +7,7 @@ Les processus doivent viser à **minimiser le temps de démarrage**. Idéalement Les processus **s'éteignent gracieusement lorsqu'ils reçoivent un signal [SIGTERM (fr)](https://fr.wikipedia.org/wiki/SIGTERM)** du gestionnaire de processus. Pour un processus web, s'éteindre en douceur se fait en arrêtant d'écouter sur le port de service (refusant, par la même occasion, toute nouvelle requête), en permettant à la requête courante de se terminer, et en quittant ensuite. Ce qui est implicite dans ce modèle, c'est que les requêtes sont courtes (pas plus de quelques secondes), ou dans le cas de longues requêtes, les clients doivent pouvoir tenter de se reconnecter sans problème lorsque la connection est perdue. -Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le worker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](http://kr.github.com/beanstalkd/), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). +Pour un processus de worker, s'éteindre gracieusement est réalisé en renvoyant le travail en cours dans la file de travaux. Par exemple, avec [RabbitMQ](http://www.rabbitmq.com/) le worker peut envoyer un message [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); avec [Beanstalkd](https://beanstalkd.github.io), le travail est renvoyé dans la file automatiquement dès qu'un worker se déconnecte. Les systèmes basés sur des verrous, comme [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) doivent s'assurer de supprimer le verrou de leur travail en cours. Il est implicite dans ce modèle que toutes les tâches sont [réentrantes (fr)](http://fr.wikipedia.org/wiki/R%C3%A9entrance), ce qui est réalisé en englobant les résultats dans une transaction, ou en rendant l'opération [idempotente (fr)](http://fr.wikipedia.org/wiki/Idempotence). Les processus doivent également être **robustes face aux morts subites**, dans le cas d'une panne du hardware sous-jacent. Bien que ce soit bien moins courant qu'un arrêt gracieux avec `SIGTERM`, cela peut arriver malgré tout. L'approche recommandée est l'utilisation d'un backend robuste de files de messages, tel que Beanstalkd, capable de renvoyer les tâches dans la file lorsqu'un client se déconnecte ou ne répond plus. Dans les deux cas, une application 12 facteurs est structurée pour gérer des fins inattendues et non-gracieuses. Le [design crash-only (en)](http://lwn.net/Articles/191059/) amène ce concept à sa [conclusion logique (en)](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/it/backing-services.md b/content/it/backing-services.md index 43fb210f4..781901b9a 100644 --- a/content/it/backing-services.md +++ b/content/it/backing-services.md @@ -1,7 +1,7 @@ ## IV. Backing Service ### Tratta i backing service come "risorse" -Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](http://kr.github.com/beanstalkd/)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). +Un "backing service" è un qualsiasi servizio che l'applicazione consuma attraverso la rete durante la sua esecuzione. Alcuni esempi includono i database (come [MySQL](http://dev.mysql.com/) o [CouchDB](http://couchdb.apache.org/)), servizi di messaging/code (come [RabbitMQ](http://www.rabbitmq.com/) oppure [Beanstalkd](https://beanstalkd.github.io)), servizi SMTP per la posta (come [Postfix](http://www.postfix.org/)) e sistemi di cache (come [Memcached](http://memcached.org/)). Un backing service (prendiamo ad esempio un database) è tradizionalmente gestito dallo stesso amministratore di sistema, al deployment dell'applicazione. In aggiunta a questi servizi gestiti in locale potrebbero esserne presenti altri, forniti da terze parti. Parliamo di servizi SMTP (come [Postmark](http://postmarkapp.com/)), servizi di raccolta metriche (come [New Relic](http://newrelic.com/) o [Loggly](http://www.loggly.com/)), servizi per asset (come [Amazon S3](http://aws.amazon.com/s3/)), e anche servizi accessibili via API (come [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), o [Last.fm](http://www.last.fm/api)). diff --git a/content/it/disposability.md b/content/it/disposability.md index dcc61af49..355806714 100644 --- a/content/it/disposability.md +++ b/content/it/disposability.md @@ -7,6 +7,6 @@ I processi dovrebbero inoltre ambire a **minimizzare i tempi di avvio**. Idealme I processi dovrebbero inoltre **terminare in modo tutt'altro che brusco, quindi graduale, in caso di ricezione di un segnale [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** dal process manager. Per un'applicazione web, la giusta terminazione di un processo viene ottenuta quando si cessa innanzitutto di ascoltare sulla porta dedicata del servizio (evitando quindi di ricevere altre richieste), permettendo poi di terminare le richieste esistenti e infine di concludere la fase di terminazione in modo definitivo. -Per un processo worker, invece, la fase di terminazione più adatta vede il ritorno del job corrente alla coda. Per esempio, su [RabbitMQ](http://www.rabbitmq.com/) il worker può inviare un [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); su [Beanstalkd](http://kr.github.com/beanstalkd/), il job viene automaticamente rimandato in coda nel caso in cui il worker si disconnette. I sistemi basati su lock come [Delayed -리소스는 자유롭게 배포에 연결되거나 분리될 수 있습니다. 예를 들어, 애플리케이션의 데이터베이스가 하드웨어 이슈로 작용이 이상한 경우, 애플리케이션의 관리자는 최신 백업에서 새로운 데이터베이스 서버를 시작시킬 것입니다. 그리고 코드를 전혀 수정하지 않고 현재 운영에 사용하고 있는 데이터베이스를 분리하고 새로운 데이터베이스를 연결할 수 있습니다. \ No newline at end of file +리소스는 자유롭게 배포에 연결되거나 분리될 수 있습니다. 예를 들어, 애플리케이션의 데이터베이스가 하드웨어 이슈로 작용이 이상한 경우, 애플리케이션의 관리자는 최신 백업에서 새로운 데이터베이스 서버를 시작시킬 것입니다. 그리고 코드를 전혀 수정하지 않고 현재 운영에 사용하고 있는 데이터베이스를 분리하고 새로운 데이터베이스를 연결할 수 있습니다. diff --git a/content/ko/disposability.md b/content/ko/disposability.md index 077ff0edc..f9201b38e 100644 --- a/content/ko/disposability.md +++ b/content/ko/disposability.md @@ -3,10 +3,10 @@ **Twelve-Factor App의 [프로세스](./processes)는 *간단하게 폐기 가능*합니다. 즉, 프로세스는 바로 시작하거나 종료될 수 있습니다.** 이러한 속성은 신축성 있는 확장과 [코드](./codebase)나 [설정](./config)의 변화를 빠르게 배포하는 것을 쉽게 하며, production 배포를 안정성 있게 해줍니다. -프로세스는 **시작 시간을 최소화**하도록 노력해야합니다. 이상적으로, 프로세스는 실행 커맨드가 실행된 뒤 몇 초만에 요청이나 작업을 받을 수 있도록 준비 됩니다. 짧은 실행 시간은 [릴리즈](./build-release-run) 작업과 확장(scale up)이 더 민첩하게 이루어질 수 있게 합니다. 또한 프로세스 매니저가 필요에 따라 쉽게 프로세스를 새로운 머신으로 프로세스를 옮길 수 있기 때문에 안정성도 높아집니다. +프로세스는 **시작 시간을 최소화**하도록 노력해야합니다. 이상적으로, 프로세스는 실행 커맨드가 실행된 뒤 몇 초만에 요청이나 작업을 받을 수 있도록 준비 됩니다. 짧은 실행 시간은 [릴리즈](./build-release-run) 작업과 확장(scale up)이 더 민첩하게 이루어질 수 있게 합니다. 또한 프로세스 매니저가 필요에 따라 쉽게 프로세스를 새로운 머신으로 프로세스를 옮길 수 있기 때문에 안정성도 높아집니다. -프로세스는 프로세스 매니저로부터 **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다.** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. +프로세스는 프로세스 매니저로부터 **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) 신호를 받았을 때 그레이스풀 셧다운(graceful shutdown)을 합니다.** 웹프로세스의 그레이스풀 셧다운 과정에서는 서비스 포트의 수신을 중지하고(그럼으로써 새로운 요청을 거절함), 현재 처리 중인 요청이 끝나길 기다린 뒤에 프로세스가 종료 되게 됩니다. 이 모델은 암묵적으로 HTTP 요청이 짧다는 가정(기껏해야 몇 초)을 깔고 있습니다. long polling의 경우에는 클라이언트가 연결이 끊긴 시점에 바로 다시 연결을 시도해야 합니다. -worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](http://kr.github.com/beanstalkd/)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [멱등(idempotent)](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. +worker 프로세스의 경우, 그레이스풀 셧다운은 현재 처리중인 작업을 작업 큐로 되돌리는 방법으로 구현됩니다. 예를 들어, [RabbitMQ](http://www.rabbitmq.com/)에서는 worker는 [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)을 메시지큐로 보낼 수 있습니다. [Beanstalkd](https://beanstalkd.github.io)에서는 woker와의 연결이 끊기면 때 자동으로 작업을 큐로 되돌립니다. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme)와 같은 Lock-based 시스템들은 작업 레코드에 걸어놨던 lock을 확실하게 풀어놓을 필요가 있습니다. 이 모델은 암묵적으로 모든 작업은 [재입력 가능(reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)하다고 가정합니다. 이는 보통, 결과를 트랜잭션으로 감싸거나 요청을 [멱등(idempotent)](http://en.wikipedia.org/wiki/Idempotence)하게 함으로써 구현될 수 있습니다. -프로세스는 하드웨어 에러에 의한 **갑작스러운 죽음에도 견고해야합니다.** 이러한 사태는 `SIGTERM`에 의한 그레이스풀 셧다운에 비하면 드문 일이지만, 그럼에도 발생할 수 있습니다. 이런 일에 대한 대책으로 Beanstalkd와 같은 견고한 큐잉 백엔드를 사용하는 것을 권장합니다. 이러한 백엔드는 클라이언트가 접속이 끊기거나, 타임 아웃이 발생했을 때, 작업을 큐로 되돌립니다. Twelve-Factor App은 예기치 못한, 우아하지 않은 종료도 처리할 수 있도록 설계됩니다. [Crash-only design](http://lwn.net/Articles/191059/)에서는 [논리적인 결론](http://docs.couchdb.org/en/latest/intro/overview.html)으로 이러한 컨셉을 가져왔습니다. \ No newline at end of file +프로세스는 하드웨어 에러에 의한 **갑작스러운 죽음에도 견고해야합니다.** 이러한 사태는 `SIGTERM`에 의한 그레이스풀 셧다운에 비하면 드문 일이지만, 그럼에도 발생할 수 있습니다. 이런 일에 대한 대책으로 Beanstalkd와 같은 견고한 큐잉 백엔드를 사용하는 것을 권장합니다. 이러한 백엔드는 클라이언트가 접속이 끊기거나, 타임 아웃이 발생했을 때, 작업을 큐로 되돌립니다. Twelve-Factor App은 예기치 못한, 우아하지 않은 종료도 처리할 수 있도록 설계됩니다. [Crash-only design](http://lwn.net/Articles/191059/)에서는 [논리적인 결론](http://docs.couchdb.org/en/latest/intro/overview.html)으로 이러한 컨셉을 가져왔습니다. diff --git a/content/pl/backing-services.md b/content/pl/backing-services.md index 12a58637a..abab6962d 100644 --- a/content/pl/backing-services.md +++ b/content/pl/backing-services.md @@ -1,7 +1,7 @@ ## IV. Usługi wspierające ### Traktuj usługi wspierające jako przydzielone zasoby -Usługą wspierającą jest każda, z której aplikacja korzysta przez sieć jako część normalnego działania. Zaliczamy do nich np. magazyny danych (takie jak [MySQL](http://dev.mysql.com/) albo [CouchDB](http://couchdb.apache.org/)), systemy wysyłania/kolejkowania wiadomości (takie jak [RabbitMQ](http://www.rabbitmq.com/) czy [Beanstalkd](http://kr.github.com/beanstalkd/)), usługi SMTP do zewnętrznej wysyłki emaili (np. [Postfix](http://www.postfix.org/)) oraz systemy cachowania pamięci (np. [Memcached](http://memcached.org/)). +Usługą wspierającą jest każda, z której aplikacja korzysta przez sieć jako część normalnego działania. Zaliczamy do nich np. magazyny danych (takie jak [MySQL](http://dev.mysql.com/) albo [CouchDB](http://couchdb.apache.org/)), systemy wysyłania/kolejkowania wiadomości (takie jak [RabbitMQ](http://www.rabbitmq.com/) czy [Beanstalkd](https://beanstalkd.github.io)), usługi SMTP do zewnętrznej wysyłki emaili (np. [Postfix](http://www.postfix.org/)) oraz systemy cachowania pamięci (np. [Memcached](http://memcached.org/)). Usługa wspierająca taka jak baza danych jest zazwyczaj zarządzana przez tych samych programistów, którzy zajmują się wdrażaniem aplikacji. Dodatkowo aplikacja może również korzystać z usług oferowanych przez osoby trzecie. Do przykładów zaliczają się usługi SMTP ([Postmark](http://postmarkapp.com/)),usługi zbierające metryki ([New Relic](http://newrelic.com/) czy [Loggly](http://www.loggly.com/)), usługi przechowywania danych (takie jak [Amazon S3](http://aws.amazon.com/s3/)), czy również usługi dostępne przez publiczne API (jak np. [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), lub [Last.fm](http://www.last.fm/api)). diff --git a/content/pl/disposability.md b/content/pl/disposability.md index ac987739e..0ee598b8f 100644 --- a/content/pl/disposability.md +++ b/content/pl/disposability.md @@ -7,7 +7,7 @@ Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealn Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long pollingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie. -Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](http://kr.github.com/beanstalkd/), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [idempotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). +Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](http://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](https://beanstalkd.github.io), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](http://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [idempotentną](http://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87). Architektura aplikacji 12factor jest również zaprojektowana by działające procesy zostały poprawnie **zakończone w razie awarii** sprzętu. Podczas gdy taka sytuacja jest o wiele rzadsza niż otrzymanie sygnału `SIGTERM`, wciąż może mieć miejsce. Zalecanym podejściem w takich przypadkach jest stosowanie serwerowego systemu kolejkowania zadań, jak Beanstalkd, który zwróci zadanie do kolejki, gdy klient się rozłączy, bądź minie maksymalny czas obsługi pojedynczego zapytania. Architektura ["crash-only"](http://lwn.net/Articles/191059/) jest więc rozwinięciem takiego [konceptu](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/pt_br/backing-services.md b/content/pt_br/backing-services.md index 6937c2d22..64f45456d 100644 --- a/content/pt_br/backing-services.md +++ b/content/pt_br/backing-services.md @@ -1,7 +1,7 @@ ## IV. Serviços de Apoio ### Trate serviços de apoio como recursos anexados -Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados (como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](http://kr.github.com/beanstalkd/)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). +Um *serviço de apoio* é qualquer serviço que o app consuma via rede como parte de sua operação normal. Exemplos incluem armazenamentos de dados (como [MySQL](http://dev.mysql.com/) ou [CouchDB](http://couchdb.apache.org/)), sistemas de mensagens/filas (tais como [RabbitMQ](http://www.rabbitmq.com/) ou [Beanstalkd](https://beanstalkd.github.io)), serviços SMTP para emails externos (tais como [Postfix](http://www.postfix.org/)), e sistemas de cache (tais como [Memcached](http://memcached.org/)). Serviços de apoio como o banco de dados são tradicionalmente gerenciados pelos mesmos administradores de sistema do servidor de deploy de tempo de execução do app. Adicionalmente à esses serviços localmente gerenciados, o app pode ter serviços providos e gerenciados por terceiros. Exemplos incluem serviços SMTP (tais como [Postmark](http://postmarkapp.com/)), serviços de colheita de métricas (tais como [New Relic](http://newrelic.com/) ou [Loggly](http://www.loggly.com/)), serviços de ativos binários (tais como [Amazon S3](http://aws.amazon.com/s3/)), e até serviços de consumidores acessíveis via API (tais como [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), ou [Last.fm](http://www.last.fm/api)). diff --git a/content/pt_br/disposability.md b/content/pt_br/disposability.md index 66a401f18..999c5ebc0 100644 --- a/content/pt_br/disposability.md +++ b/content/pt_br/disposability.md @@ -7,6 +7,6 @@ Processos devem empenhar-se em **minimizar o tempo de inicialização**. Idealme Processos **desligam-se graciosamente quando recebem um sinal [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** do seu gestor de processos. Para um processo web, desligamento gracioso é alcançado quando cessa de escutar à porta de serviço (consequentemente recusando quaisquer requisições novas), permitindo qualquer requisição em andamento terminar, e então desligando. Implícito neste modelo é que as requisições HTTP são curtas (não mais que alguns poucos segundos), ou no caso de um longo _polling_, o cliente deve ser capaz de transparentemente tentar se reconectar quando a conexão for perdida. -Para um processo de trabalho (worker), desligamento gracioso é alcançado retornando a tarefa atual para fila de trabalho. Por exemplo, no [RabbitMQ](http://www.rabbitmq.com/) o trabalhador pode enviar um [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); no [Beanstalkd](http://kr.github.com/beanstalkd/), a tarefa é retornada para a fila automaticamente sempre que um trabalhador se desconecta. Sistemas baseados em trava como o [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) precisam se certificar de soltar a trava no registro da tarefa. Implícito neste modelo é que todas as tarefas são [reentrantes](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), o que tipicamente é atingindo envolvendo os resultados numa transação, ou tornando a operação [idempotente](http://en.wikipedia.org/wiki/Idempotence). +Para um processo de trabalho (worker), desligamento gracioso é alcançado retornando a tarefa atual para fila de trabalho. Por exemplo, no [RabbitMQ](http://www.rabbitmq.com/) o trabalhador pode enviar um [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); no [Beanstalkd](https://beanstalkd.github.io), a tarefa é retornada para a fila automaticamente sempre que um trabalhador se desconecta. Sistemas baseados em trava como o [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) precisam se certificar de soltar a trava no registro da tarefa. Implícito neste modelo é que todas as tarefas são [reentrantes](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), o que tipicamente é atingindo envolvendo os resultados numa transação, ou tornando a operação [idempotente](http://en.wikipedia.org/wiki/Idempotence). Processos também devem ser **robustos contra morte súbida**, no caso de uma falha de hardware. Ao passo que isso é muito menos comum que um desligamento via `SIGTERM`, isso ainda pode acontecer. Uma abordagem recomendada é usar um backend de filas robusto, como o Beanstalkd, que retorna tarefas à fila quando clientes desconectam ou esgotam o tempo de resposta. De qualquer forma, um app doze-fatores é arquitetado para lidar com terminações não esperadas e não graciosas. [Crash-only design](http://lwn.net/Articles/191059/) leva este conceito à sua [conclusão lógica](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/ru/backing-services.md b/content/ru/backing-services.md index 48295ceca..c6a44e011 100644 --- a/content/ru/backing-services.md +++ b/content/ru/backing-services.md @@ -1,7 +1,7 @@ ## IV. Сторонние службы (Backing Services) ### Считайте сторонние службы (backing services) подключаемыми ресурсами -*Сторонняя служба*-- это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Например, хранилища данных (например, [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например, [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](http://kr.github.com/beanstalkd/)), службы SMTP для исходящей электронной почты (например, [Postfix](http://www.postfix.org/)) и кэширующие системы (например, [Memcached](http://memcached.org/)). +*Сторонняя служба*-- это любая служба, которая доступна приложению по сети и необходима как часть его нормальной работы. Например, хранилища данных (например, [MySQL](http://dev.mysql.com/) и [CouchDB](http://couchdb.apache.org/)), системы очередей сообщений (например, [RabbitMQ](http://www.rabbitmq.com/) и [Beanstalkd](https://beanstalkd.github.io)), службы SMTP для исходящей электронной почты (например, [Postfix](http://www.postfix.org/)) и кэширующие системы (например, [Memcached](http://memcached.org/)). Традиционно, сторонние службы, такие как базы данных, поддерживаются тем же самым системным администратором, который разворачивает приложение. Помимо локальных сервисов приложение может использовать сервисы, предоставленные и управляемые третьей стороной. Примеры включают в себя SMTP сервисы (например [Postmark](http://postmarkapp.com/)), сервисы сбора метрик (такие как [New Relic](http://newrelic.com/) и [Loggly](http://www.loggly.com/)), хранилища бинарных данных (например, [Amazon S3](http://aws.amazon.com/s3/)), а также использование API различных сервисов (таких как [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) и [Last.fm](http://www.last.fm/api)). diff --git a/content/ru/disposability.md b/content/ru/disposability.md index 60aa9cb39..aa527b66d 100644 --- a/content/ru/disposability.md +++ b/content/ru/disposability.md @@ -7,6 +7,6 @@ Процессы должны **завершаться корректно, когда они получают [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал от диспетчера процессов. Для веб-процесса корректное завершение работы достигается путём прекращения прослушивания порта сервиса (таким образом, отказаться от каких-либо новых запросов), что позволяет завершить текущие запросы и затем завершиться. В этой модели подразумевается, что HTTP-запросы короткие (не более чем на несколько секунд), в случае длинных запросов клиент должен плавно попытаться восстановить подключение при потере соединения. -Для процесса, выполняющего фоновые задачи (worker), корректное завершение работы достигается путём возвращения текущей задачи назад в очередь задач. Например, в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках такие, как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путём оборачивания результатов работы в транзакции или путём использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. +Для процесса, выполняющего фоновые задачи (worker), корректное завершение работы достигается путём возвращения текущей задачи назад в очередь задач. Например, в [RabbitMQ](http://www.rabbitmq.com/) рабочий процесс может отправлять команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](https://beanstalkd.github.io) задача возвращается в очередь автоматически, когда рабочий процесс отключается. Системы, основанные на блокировках такие, как [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) должны быть уведомлены, чтобы освободить блокировку задачи. В этой модели подразумевается, что все задачи являются [повторно входимыми](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), что обычно достигается путём оборачивания результатов работы в транзакции или путём использования [идемпотентных](http://en.wikipedia.org/wiki/Idempotence) операций. Процессы также должны быть **устойчивыми к внезапной смерти** в случае отказа аппаратного обеспечения. Хотя это менее вероятное событие, чем корректное завершение работы сигналом `SIGTERM`, оно всё же может случиться. Рекомендуемым подходом является использование надёжных очередей задач, таких как Beanstalkd, которые возвращают задачу в очередь когда клиент отключается или превышает лимит времени. В любом случае приложение двенадцати факторов должно проектироваться так, чтобы обрабатывать неожиданные и неизящные выключения. [Архитектура только аварийного выключения (Crash-only design)](http://lwn.net/Articles/191059/) доводит эту концепцию до её [логического завершения](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/tr/backing-services.md b/content/tr/backing-services.md index d2dba0ae8..9c0008049 100644 --- a/content/tr/backing-services.md +++ b/content/tr/backing-services.md @@ -1,7 +1,7 @@ ## IV. Destek servisi ### Destek servislerine ekli kaynak olarak davranma -Bir *destek servisi* uygulamanın kendi normal işleminin bir parçası olarak ağ üzerinden tüketim yapan bir servistir. Örnekler veri deposu([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlama/kuyruklama sistemleri( [RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](http://kr.github.com/beanstalkd/)), giden email için SMTP servisi([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemleri([Memcached](http://memcached.org/) gibi) içerir. +Bir *destek servisi* uygulamanın kendi normal işleminin bir parçası olarak ağ üzerinden tüketim yapan bir servistir. Örnekler veri deposu([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlama/kuyruklama sistemleri( [RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](https://beanstalkd.github.io)), giden email için SMTP servisi([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemleri([Memcached](http://memcached.org/) gibi) içerir. Destek servisleri, veri tabanı gibi, uygulamaların çalışma zamanlı dağıtımlarında olduğu gibi benzer sistem yöneticileri tarafından geleneksel olarak yönetilirler. Bu yerel yönetilen servislere ilave olarak, uygulama üçüncü parti uygulamalar tarafından onaylanmış ve yönetilmiş servislere sahip olabilirler. Örnekler SMTP servisleri([Postmark](http://postmarkapp.com/) gibi), Metrik toplama servisleri( [New Relic](http://newrelic.com/) veya [Loggly](http://www.loggly.com/) gibi), binary servisler([Amazon S3](http://aws.amazon.com/s3/) gibi) ve API-erişilebilir tüketici servisleri bile [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ve [Last.fm](http://www.last.fm/api) gibi) içerir. diff --git a/content/tr/disposability.md b/content/tr/disposability.md index f90c73693..8618c1670 100644 --- a/content/tr/disposability.md +++ b/content/tr/disposability.md @@ -7,6 +7,6 @@ Süreçler **başlangıç zamanını küçültmeye* çabalamalıdır. İdeal ola Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, incelikli kapanır.** Web süreci için incelikli kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), herhangi bir o anki isteklerin bitmesine izin verilmesi ve daha sonra çıkılmasıyla sonuçlanır. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. -Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](http://kr.github.com/beanstalkd/)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. +Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. Süreçler esas donanımdaki hata durumlarında **ani kapanmaya karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile incelikli kapamadan daha az yaygın bir olay olduğu için hala olabilir. Önerilen yaklaşım sağlam arkaplan kuyruklama kullanımıdır, Beanstalkd gibi, istemciler oturumu kapattığı zaman veya süre dolduğu zaman işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması incelikli olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only dezaynı](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucunu](http://docs.couchdb.org/en/latest/intro/overview.html) alır. diff --git a/content/uk/backing-services.md b/content/uk/backing-services.md index a650fc84a..ee2457558 100644 --- a/content/uk/backing-services.md +++ b/content/uk/backing-services.md @@ -1,7 +1,7 @@ ## IV. Сторонні служби ### Вважайте сторонні служби (backing services) підключеними ресурсами -*Стороння служба* — це будь-яка служба, яка доступна застосунку по мережі і необхідна для його нормальної роботи: бази даних (наприклад, [MySQL](http://dev.mysql.com/) або [CouchDB](http://couchdb.apache.org/)), системи черг повідомлень (наприклад, [RabbitMQ](http://www.rabbitmq.com/) або [Beanstalkd](http://kr.github.com/beanstalkd/)), служби SMTP для вихідної пошти (наприклад, [Postfix](http://www.postfix.org/)), системи кешування (наприклад, [Memcached](http://memcached.org/)) тощо. +*Стороння служба* — це будь-яка служба, яка доступна застосунку по мережі і необхідна для його нормальної роботи: бази даних (наприклад, [MySQL](http://dev.mysql.com/) або [CouchDB](http://couchdb.apache.org/)), системи черг повідомлень (наприклад, [RabbitMQ](http://www.rabbitmq.com/) або [Beanstalkd](https://beanstalkd.github.io)), служби SMTP для вихідної пошти (наприклад, [Postfix](http://www.postfix.org/)), системи кешування (наприклад, [Memcached](http://memcached.org/)) тощо. Допоміжні служби, такі як бази даних, традиційно управляються тими ж системними адміністраторами, які розгортають застосунок. Окрім локальних служб, застосунок може також використовувати служби, що надаються і керуються третіми сторонами: SMTP-сервіси (наприклад, [Postmark](http://postmarkapp.com/)), сервіси збору метрик (наприклад, [New Relic](http://newrelic.com/) або [Loggly](http://www.loggly.com/)), сховища бінарних даних (наприклад, [Amazon S3](http://aws.amazon.com/s3/)), а також різні сервіси, що надають доступ через API (наприклад, [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), або [Last.fm](http://www.last.fm/api)). @@ -11,4 +11,4 @@ production-розгортання, в якому підключені чотири сторонні служби -Ресурси за необхідності можуть бути підключені та відключені до розгортання застосунку. Наприклад, якщо база даних застосунку функціонує некорекно у зв'язку з апаратними проблемами, адміністратор може запустити новий сервер бази даних, відновленої з останньої резервної копії. Поточна база даних може бути відключена, а нова база даних підключена — все це без будь-яких змін коду. \ No newline at end of file +Ресурси за необхідності можуть бути підключені та відключені до розгортання застосунку. Наприклад, якщо база даних застосунку функціонує некорекно у зв'язку з апаратними проблемами, адміністратор може запустити новий сервер бази даних, відновленої з останньої резервної копії. Поточна база даних може бути відключена, а нова база даних підключена — все це без будь-яких змін коду. diff --git a/content/uk/disposability.md b/content/uk/disposability.md index 8e6fc6d6d..1aa86f6dd 100644 --- a/content/uk/disposability.md +++ b/content/uk/disposability.md @@ -7,6 +7,6 @@ Процеси мають **коректно завершувати свою роботу, коли вони отримують [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** сигнал від диспетчеру процесів. Для веб-процесу коректне завершення роботи досягається завдяки припиненню прослуховування порту, до якого він прив'язаний (що означає відмову від отримання будь-яких нових запитів), завершенню обробки будь-яких поточних запитів та зупинці самого процесу. В цій моделі передбачається, що HTTP-запити короткі (не більше ніж кілька секунд), а у разі довгих запитів (long polling) клієнт має намагатися відновити з'єднання у разі його втрати. -Для процесу, що виконує фонові задачі (worker), коректне завершення роботи досягається за рахунок повернення поточного завдання назад у чергу задач. Наприклад, в [RabbitMQ](http://www.rabbitmq.com/) робочий процес може надіслати команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](http://kr.github.com/beanstalkd/) завдання повертається в чергу автоматично щоразу, коли процес втрачає з'єднання. Системи, що використовують блокування, такі як [Delayed Job](https://github.com/collectiveidea/delayed_job#readme), мають бути повідомлені, щоб звільнити блокування задачі. В цій моделі передбачається, що всі задачі є [повторно вхідними](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), що зазвичай досягається шляхом обертання результатів їхньої роботи в транзакції або шляхом використання [ідемпотентних](http://en.wikipedia.org/wiki/Idempotence) операцій. +Для процесу, що виконує фонові задачі (worker), коректне завершення роботи досягається за рахунок повернення поточного завдання назад у чергу задач. Наприклад, в [RabbitMQ](http://www.rabbitmq.com/) робочий процес може надіслати команду [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); в [Beanstalkd](https://beanstalkd.github.io) завдання повертається в чергу автоматично щоразу, коли процес втрачає з'єднання. Системи, що використовують блокування, такі як [Delayed Job](https://github.com/collectiveidea/delayed_job#readme), мають бути повідомлені, щоб звільнити блокування задачі. В цій моделі передбачається, що всі задачі є [повторно вхідними](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), що зазвичай досягається шляхом обертання результатів їхньої роботи в транзакції або шляхом використання [ідемпотентних](http://en.wikipedia.org/wiki/Idempotence) операцій. -Процеси також мають бути **стійкі до раптової зупинки** в разі відмови апаратних засобів, на яких вони запущені. Хоча це менш ймовірна подія, ніж коректне завершення роботи за допомогою сигналу `SIGTERM`, вона все ж таки може статися. Рекомендованим підходом є використання надійних черг завдань, таких як Beanstalkd, які повертають завдання в чергу задач, коли клієнти втрачають з'єднання або від'єднуються по тайм-ауту. У будь-якому випадку, застосунок дванадцяти факторів має проектуватися таким чином, щоб обробляти несподівані та некоректні вимкнення. Прикладом вдалої реалізації [архітектури "тільки аварійного вимкнення" (Crash-only design)](http://lwn.net/Articles/191059/) є [СouchDB](http://docs.couchdb.org/en/latest/intro/overview.html). \ No newline at end of file +Процеси також мають бути **стійкі до раптової зупинки** в разі відмови апаратних засобів, на яких вони запущені. Хоча це менш ймовірна подія, ніж коректне завершення роботи за допомогою сигналу `SIGTERM`, вона все ж таки може статися. Рекомендованим підходом є використання надійних черг завдань, таких як Beanstalkd, які повертають завдання в чергу задач, коли клієнти втрачають з'єднання або від'єднуються по тайм-ауту. У будь-якому випадку, застосунок дванадцяти факторів має проектуватися таким чином, щоб обробляти несподівані та некоректні вимкнення. Прикладом вдалої реалізації [архітектури "тільки аварійного вимкнення" (Crash-only design)](http://lwn.net/Articles/191059/) є [СouchDB](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/zh_cn/backing-services.md b/content/zh_cn/backing-services.md index 69051a2d3..6843f8945 100644 --- a/content/zh_cn/backing-services.md +++ b/content/zh_cn/backing-services.md @@ -1,7 +1,7 @@ ## IV. 后端服务 ### 把后端服务(*backing services*)当作附加资源 -*后端服务*是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](http://kr.github.com/beanstalkd/)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 +*后端服务*是指程序运行所需要的通过网络调用的各种服务,如数据库([MySQL](http://dev.mysql.com/),[CouchDB](http://couchdb.apache.org/)),消息/队列系统([RabbitMQ](http://www.rabbitmq.com/),[Beanstalkd](https://beanstalkd.github.io)),SMTP 邮件发送服务([ Postfix](http://www.postfix.org/)),以及缓存系统([Memcached](http://memcached.org/))。 类似数据库的后端服务,通常由部署应用程序的系统管理员一起管理。除了本地服务之外,应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP(例如 [Postmark](http://postmarkapp.com/)),数据收集服务(例如 [New Relic](http://newrelic.com/) 或 [Loggly](http://www.loggly.com/)),数据存储服务(如 [Amazon S3](http://http://aws.amazon.com/s3/)),以及使用 API 访问的服务(例如 [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), [Last.fm](http://www.last.fm/api))。 diff --git a/content/zh_cn/disposability.md b/content/zh_cn/disposability.md index dbb4444f7..121699b65 100644 --- a/content/zh_cn/disposability.md +++ b/content/zh_cn/disposability.md @@ -7,7 +7,7 @@ 进程 **一旦接收 [终止信号(`SIGTERM`)](http://en.wikipedia.org/wiki/SIGTERM) 就会优雅的终止** 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟),而在长时间轮询中,客户端在丢失连接后应该马上尝试重连。 -对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](http://kr.github.com/beanstalkd/) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [幂等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 +对于 worker 进程来说,优雅终止是指将当前任务退回队列。例如,[RabbitMQ](http://www.rabbitmq.com/) 中,worker 可以发送一个[`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack)信号。 [Beanstalkd](https://beanstalkd.github.io) 中,任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) 则需要确定释放了系统资源。此类型的进程所隐含的要求是,任务都应该 [可重复执行](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) , 这主要由将结果包装进事务或是使重复操作 [幂等](http://en.wikipedia.org/wiki/Idempotence) 来实现。 -进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](http://kr.github.com/beanstalkd/) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。[Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 +进程还应当**在面对突然死亡时保持健壮**,例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少,但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列,例如 [Beanstalkd](https://beanstalkd.github.io) ,它可以在客户端断开或超时后自动退回任务。无论如何,12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。[Crash-only design](http://lwn.net/Articles/191059/) 将这种概念转化为 [合乎逻辑的理论](http://couchdb.apache.org/docs/overview.html)。 From c3156725cb1a3c1ba2d0be8e2e5dfb2dc3612123 Mon Sep 17 00:00:00 2001 From: Hannes Fostie Date: Tue, 20 Nov 2018 13:48:40 +0100 Subject: [PATCH 414/472] replace eventmachine website --- content/de/concurrency.md | 2 +- content/en/concurrency.md | 2 +- content/es/concurrency.md | 2 +- content/fr/concurrency.md | 2 +- content/it/concurrency.md | 2 +- content/ja/concurrency.md | 2 +- content/ko/concurrency.md | 6 +++--- content/pl/concurrency.md | 2 +- content/pt_br/concurrency.md | 2 +- content/ru/concurrency.md | 2 +- content/tr/concurrency.md | 2 +- content/uk/concurrency.md | 4 ++-- content/zh_cn/concurrency.md | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/content/de/concurrency.md b/content/de/concurrency.md index c5a76cc72..e6166d174 100644 --- a/content/de/concurrency.md +++ b/content/de/concurrency.md @@ -7,7 +7,7 @@ Jedes Computerprogramm wird, wenn es läuft, repräsentiert durch einen oder meh **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 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](https://github.com/eventmachine/eventmachine), [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 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. diff --git a/content/en/concurrency.md b/content/en/concurrency.md index 32c8dab02..9e7426fcf 100644 --- a/content/en/concurrency.md +++ b/content/en/concurrency.md @@ -7,7 +7,7 @@ Any computer program, once run, is represented by one or more processes. Web ap **In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. diff --git a/content/es/concurrency.md b/content/es/concurrency.md index c1d0c7c96..f19ac8080 100644 --- a/content/es/concurrency.md +++ b/content/es/concurrency.md @@ -7,7 +7,7 @@ Todo programa de ordenador, al ejecutarse, se encuentra representado en memoria **En las aplicaciones "twelve-factor", los procesos son ciudadanos de primera clase.** Los procesos de las aplicaciones "twelve-factor" se inspiran en [el modelo de procesos de unix para ejecutar demonios](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Usando este modelo, el desarrollador puede distribuir la ejecución de su aplicación para gestionar diversas cargas de trabajo asignando cada tipo de trabajo a un *tipo de proceso*. Por ejemplo, las peticiones HTTP se pueden procesar con un proceso y las tareas con mucha carga de trabajo con hilos. -Esto no exime a los procesos de gestionar su propia división interna mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual aislada tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. +Esto no exime a los procesos de gestionar su propia división interna mediante threads en la ejecución de la máquina virtual o mediante un modelo asíncrono o por eventos con herramientas como [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). No obstante, una máquina virtual aislada tiene una capacidad de crecimiento limitada, así que la aplicación debe ser capaz de dividirse en multiples procesos que se puedan ejecutar en múltiples máquinas físicas. El modelo de procesos muestra todo su potencial cuando llega el momento de escalar. La [naturaleza "share-nothing", divide horizontalmente los procesos de las aplicaciones "twelve-factor"](./processes) y se traduce en un aumento de la concurrencia como una operación simple y fiable. El conjunto de tipos de procesos y el número de procesos de cada tipo es conocido como *juego de procesos*. diff --git a/content/fr/concurrency.md b/content/fr/concurrency.md index aec453b05..f3ff239ba 100644 --- a/content/fr/concurrency.md +++ b/content/fr/concurrency.md @@ -7,7 +7,7 @@ Tout programme informatique, lorsqu'il s'exécute, est représenté par un ou pl **Dans une application 12 facteurs, les processus sont des élèves modèles**. Les processus dans une application 12 facteurs s'inspirent fortement du [modèle de processus unix pour faire fonctionner les daemon (en)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). En utilisant ce modèle, les développeurs peuvent structurer l'application pour gérer différents types de charge en assignant chaque type de travail à un *type de processus*. Par exemple, les requêtes HTTP peuvent être gérées par un processus web, et les tâches d'arrière-plan ayant une longue durée d'exécution peuvent être des processus dits "worker". -Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrones que l'on retrouve dans des outils comme [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. +Chaque processus peut malgré tout et individuellement, gérer son propre multiplexage interne, avec des threads à l'intérieur de la machine virtuelle d'exécution, ou à l'aide du modèle d'évènements asynchrones que l'on retrouve dans des outils comme [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mais une machine virtuelle a individuellement une taille limitée (grandissement vertical), donc l'application doit également pouvoir déclencher plusieurs processus qui tournent sur plusieurs machines physiques. Le modèle de processus prend de l'envergure dès qu'il est question de grossir. La [nature sans partage, avec une partition horizontale des processus des applications 12 facteurs](./processes) signifie qu'ajouter plus de concurrence est une opération simple et fiable. La liste des types de processus et du nombre de processus de chaque type est appelée *formation de processus*. diff --git a/content/it/concurrency.md b/content/it/concurrency.md index c0c851a91..1ea240065 100644 --- a/content/it/concurrency.md +++ b/content/it/concurrency.md @@ -7,7 +7,7 @@ Ogni software, una volta avviato, è rappresentato da uno o più processi. Le we **In un'applicazione twelve-factor, i processi sono "first class citizen"**. La visione del concetto di processo prende spunto dal [concetto, in unix, dedicato all'esecuzione di demoni di servizi](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Attraverso l'uso di questo modello, lo sviluppatore può realizzare la propria applicazione in modo tale da farle gestire senza problemi diversi livelli di carico di lavoro, assegnando ogni tipo di lavoro a un tipo di processo ben definito. Per esempio, le richieste HTTP possono essere gestite da un web process, mentre dei compiti più lunghi (in background) possono essere gestiti da un altro processo separato. -Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo e interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. +Questo non esclude che un certo processo, individualmente, possa gestire in modo autonomo e interno il multiplexing, tramite threading, all'interno della VM in esecuzione, o magari un modello asincrono o basato su eventi come quello di [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), o [Node.js](http://nodejs.org/). Tuttavia, tutto questo può non bastare: l'applicazione deve essere anche adatta all'esecuzione su più macchine fisiche. Il modello di processo così come presentato rende il massimo quando arriva il momento di scalare. La [natura orizzontalmente partizionabile (e non soggetta a condivisioni) di un "processo twelve-factor"](./processes) permette di gestire la concorrenza in modo semplice e affidabile. L'array dei tipi di processo e il numero di processi presenti per ogni tipo è conosciuto come *process formation* (formazione di processi). diff --git a/content/ja/concurrency.md b/content/ja/concurrency.md index be5755c1e..864b47e9c 100644 --- a/content/ja/concurrency.md +++ b/content/ja/concurrency.md @@ -7,7 +7,7 @@ **Twelve-Factor Appではプロセスは第一級市民である。** Twelve-Factor Appにおけるプロセスの考え方は、[サービスのデーモンを実行するためのUnixプロセスモデル](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)から大きなヒントを得ている。このモデルを使い、個々のワークロードの種類を *プロセスタイプ* に割り当てることで、開発者はアプリケーションが多様なワークロードを扱えるように設計することができる。例えば、HTTPリクエストはWebプロセスによって処理し、時間のかかるバックグラウンドタスクはワーカープロセスによって処理することができる。 -このモデルは、ランタイムVM内のスレッドや、[EventMachine](http://rubyeventmachine.com/)、[Twisted](http://twistedmatrix.com/trac/)、[Node.js](http://nodejs.org/)などの非同期イベントモデルによって、個々のプロセスがプロセス内部で多重化することを禁止するわけではない。しかし個々のVMはそれほど大きくなる(垂直にスケールする)ことができないため、アプリケーションは複数の物理マシンで動作する複数のプロセスへと拡大できなければならない。 +このモデルは、ランタイムVM内のスレッドや、[EventMachine](https://github.com/eventmachine/eventmachine)、[Twisted](http://twistedmatrix.com/trac/)、[Node.js](http://nodejs.org/)などの非同期イベントモデルによって、個々のプロセスがプロセス内部で多重化することを禁止するわけではない。しかし個々のVMはそれほど大きくなる(垂直にスケールする)ことができないため、アプリケーションは複数の物理マシンで動作する複数のプロセスへと拡大できなければならない。 このプロセスモデルが真価を発揮するのは、スケールアウトが必要になったときである。[シェアードナッシングで水平分割可能なTwelve-Factor Appプロセスの性質](./processes)は、並行性を高める操作が単純かつ確実なものであることを意味する。プロセスタイプとそれぞれのタイプのプロセス数の配列は、 *プロセスフォーメーション* と言われる。 diff --git a/content/ko/concurrency.md b/content/ko/concurrency.md index 8837f5f89..b388c6a4c 100644 --- a/content/ko/concurrency.md +++ b/content/ko/concurrency.md @@ -1,14 +1,14 @@ ## VIII. 동시성(Concurrency) ### 프로세스 모델을 통한 확장 -모든 컴퓨터 프로그램은 실행되면 하나 이상의 프로세스로 표현됩니다. 웹 애플리케이션은 다양한 프로세스 실행 형태를 취해왔습니다. 예를 들어, PHP 프로세스는 Apache의 자식 프로세스로 실행되며, request의 양에 따라 필요한 만큼 시작됩니다. 자바 프로세스들은 반대 방향에서의 접근법을 취합니다. JVM은, 시작될 때 큰 시스템 리소스(CPU와 메모리) 블록을 예약하는 하나의 거대한 부모 프로세스를 제공하고, 내부 쓰레드를 통해 동시성(concurrency)을 관리합니다. 두 경우 모두 실행되는 프로세스는 애플리케이션 개발자에게 최소한으로 노출됩니다. +모든 컴퓨터 프로그램은 실행되면 하나 이상의 프로세스로 표현됩니다. 웹 애플리케이션은 다양한 프로세스 실행 형태를 취해왔습니다. 예를 들어, PHP 프로세스는 Apache의 자식 프로세스로 실행되며, request의 양에 따라 필요한 만큼 시작됩니다. 자바 프로세스들은 반대 방향에서의 접근법을 취합니다. JVM은, 시작될 때 큰 시스템 리소스(CPU와 메모리) 블록을 예약하는 하나의 거대한 부모 프로세스를 제공하고, 내부 쓰레드를 통해 동시성(concurrency)을 관리합니다. 두 경우 모두 실행되는 프로세스는 애플리케이션 개발자에게 최소한으로 노출됩니다. ![Scale는 실행되는 프로세스의 갯수로 표현되고, Workload Diversity는 프로세스의 타입으로 표현됩니다. ](/images/process-types.png) **Twelve-Factor App에서 프로세스들은 일급 시민입니다.** Twelve-Factor App에서의 프로세스는 [서비스 데몬들을 실행하기 위한 유닉스 프로세스 모델](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)에서 큰 힌트를 얻었습니다. 이 모델을 사용하면 개발자는 애플리케이션의 작업을 적절한 *프로세스 타입*에 할당함으로서 다양한 작업 부하를 처리할 수 있도록 설계할 수 있습니다. 예를 들어, HTTP 요청은 웹 프로세스가 처리하며, 시간이 오래 걸리는 백그라운드 작업은 worker 프로세스가 처리하도록 할 수 있습니다. -이는 런타임 VM 내부의 쓰레드나 [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. +이는 런타임 VM 내부의 쓰레드나 [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/)에서 구성된 것 처럼 async/evented 모델처럼 개별 프로세스가 내부적으로 동시에 처리하는 것을 금지하는 것은 아닙니다. 하지만 개별 VM이 너무 커질 수 있습니다.(수직 확장) 따라서 애플리케이션은 여러개의 물리적인 머신에서 돌아가는 여러개의 프로세스로 넓게 퍼질 수 있어야만 합니다. -프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](./processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. +프로세스 모델이 진정으로 빛나는 것은 수평적으로 확장하는 경우입니다. [아무것도 공유하지 않고, 수평으로 분할할 수 있는 Twelve-Factor App 프로세스의 성질](./processes)은 동시성을 높이는 것은 간단하고 안정적인 작업이라는 것을 의미 합니다. 프로세스의 타입과 각 타입별 프로세스의 갯수의 배치를 *프로세스 포메이션*이라고 합니다. Twelve-Factor App 프로세스는 [절대 데몬화해서는 안되며](http://dustin.github.com/2010/02/28/running-processes.html) PID 파일을 작성해서는 안됩니다. 대신, OS의 프로세스 관리자(예: [systemd](https://www.freedesktop.org/wiki/Software/systemd/))나 클라우드 플랫폼의 분산 프로세스 매니저, 혹은 [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) 같은 툴에 의존하여 [아웃풋 스트림](./logs)을 관리하고, 충돌이 발생한 프로세스에 대응하고, 재시작과 종료를 처리해야 합니다. diff --git a/content/pl/concurrency.md b/content/pl/concurrency.md index f30dcf955..37375252f 100644 --- a/content/pl/concurrency.md +++ b/content/pl/concurrency.md @@ -7,7 +7,7 @@ Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jed **W aplikacji 12factor, procesy są typem pierwszoklasowym** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych. -Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku maszyny wirtualnej lub w asynchronicznym modelu wydarzeń, którego implementację możemy znaleźć wśród narzędzi takich jak [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), albo [Node.js](http://nodejs.org/). Należy pamiętać, że pojedyncza maszyna wirtualna może z czasem wymagać coraz więcej zasobów (skala pionowa), dlatego aplikacja musi być również w stanie pracować w oparciu o wiele procesów działających na wielu fizycznych maszynach. +Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku maszyny wirtualnej lub w asynchronicznym modelu wydarzeń, którego implementację możemy znaleźć wśród narzędzi takich jak [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), albo [Node.js](http://nodejs.org/). Należy pamiętać, że pojedyncza maszyna wirtualna może z czasem wymagać coraz więcej zasobów (skala pionowa), dlatego aplikacja musi być również w stanie pracować w oparciu o wiele procesów działających na wielu fizycznych maszynach. Największa zaleta modelu procesów objawia się w momencie skalowania. [Niezależność oraz dzielenie się na podprocesy](./processes) umożliwia proste i bezproblemowe dodawanie wiekszej liczby równolegle działajacych procesów. Tablica typów procesów i liczba procesów nazywana jest ich *formacją*. diff --git a/content/pt_br/concurrency.md b/content/pt_br/concurrency.md index c7b5b0a73..0bdca1eac 100644 --- a/content/pt_br/concurrency.md +++ b/content/pt_br/concurrency.md @@ -7,7 +7,7 @@ Qualquer programa de computador, uma vez executado, está representado por um ou **Na aplicação doze-fatores, processos são cidadãos de primeira classe.** Processos na aplicação doze-fatores utilizam fortes sugestões do modelo de processos UNIX para execução de serviços daemon, o desenvolvedor pode arquitetar a aplicação dele para lidar com diversas cargas de trabalho, atribuindo a cada tipo de trabalho a um *tipo de processo*. Por exemplo, solicitações HTTP podem ser manipuladas para um processo web, e tarefas background de longa duração podem ser manipuladas por um processo trabalhador. -Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. +Isto não exclui processos individuais da manipulação de sua própria multiplexação interna, por threads dentro do runtime da VM, ou o modelo async/evented encontrado em ferramentas como [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), ou [Node.js](http://nodejs.org/). Mas uma VM individual pode aumentar (escala vertical), de modo que a aplicação deve ser capaz de abranger processos em execução em várias máquinas físicas. O modelo de processo realmente brilha quando chega a hora de escalar. O [compartilhar-nada, natureza horizontal particionada de um processo da aplicação doze-fatores](./processes) significa que a adição de mais simultaneidade é uma operação simples e de confiança. A matriz de tipos de processo e número de processos de cada tipo é conhecida como o *processo de formação*. diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index 675c63bcd..c33a979dd 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -7,7 +7,7 @@ **В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. -Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. +Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. diff --git a/content/tr/concurrency.md b/content/tr/concurrency.md index 972efde74..0d9a628a0 100644 --- a/content/tr/concurrency.md +++ b/content/tr/concurrency.md @@ -7,7 +7,7 @@ Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha f **On iki faktör uygulamasında, süreçler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki süreçler [arka planda çalışan servis programları için olan unix süreç modelinden](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) güçlü ipuçları alır. Bu modeli kullanarak geliştirici uygulamasını her bir tip işe bir *süreç tipi* atayarak, ayrı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web süreçleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi süreçler tarafından işlenir. -Bu, bireysel süreçlerin kendi dahili çoklu işlemelerini içermiyor değil, çalışma zamanı içindeki iş parçacıkları aracılığıyla VM, veya [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron model. Fakat bireysel VM yalnızca çok aşırı büyüyebilir (dikey ölçekte), bu yüzden uygulama aynı zamanda çoklu fiziksel makinelerde çalışan çoklu süreçleri içerebilmelidir. +Bu, bireysel süreçlerin kendi dahili çoklu işlemelerini içermiyor değil, çalışma zamanı içindeki iş parçacıkları aracılığıyla VM, veya [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron model. Fakat bireysel VM yalnızca çok aşırı büyüyebilir (dikey ölçekte), bu yüzden uygulama aynı zamanda çoklu fiziksel makinelerde çalışan çoklu süreçleri içerebilmelidir. Bu süreç modeli, konu ölçeklendirme zamanına geldiğinde gerçekten çok başarılıdır. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama süreçleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir işlem olduğu anlamına gelir. Süreç tipleri dizisi ve her bir tipin süreçlerinin numarası *süreç oluşumu* olarak bilinir. diff --git a/content/uk/concurrency.md b/content/uk/concurrency.md index e13f83b00..de609a2c8 100644 --- a/content/uk/concurrency.md +++ b/content/uk/concurrency.md @@ -7,8 +7,8 @@ **В застосунку дванадцяти факторів, процеси є сутностями першого класу.** Процеси в застосунку дванадцяти факторів взяли сильні сторони від [моделі процесів UNIX для запуску сервісів](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Використовуючи цю модель, розробник може спроектувати свій застосунок таким чином, що для обробки різних робочих навантажень необхідно призначити кожному виду робіт свій *тип процесу*. Наприклад, HTTP-запити можуть бути оброблені за допомогою веб-процесу (web process), а тривалі фонові завдання оброблені робочим процесом (worker process). -Це не виключає можливості використання індивідуального мультиплексування для окремих процесів через потоки виконання віртуальної машини або асинхронні/подієві моделі в таких інструментах, як [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/) або [Node.js](http://nodejs.org/). Але індивідуальна віртуальна машина може масшабуватися тільки обмежено (вертикальне масшабування), тому застосунок також повинен мати можливість бути запущеним як декілька процесів на декількох фізичних машинах. +Це не виключає можливості використання індивідуального мультиплексування для окремих процесів через потоки виконання віртуальної машини або асинхронні/подієві моделі в таких інструментах, як [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) або [Node.js](http://nodejs.org/). Але індивідуальна віртуальна машина може масшабуватися тільки обмежено (вертикальне масшабування), тому застосунок також повинен мати можливість бути запущеним як декілька процесів на декількох фізичних машинах. Модель, побудована на процесах, дійсно показує себе з найкращого боку, коли постає необхідність масштабування. [Відсутність розділених даних і горизонтальне розділення процесів застосунку дванадцяти факторів](./processes) означає, що додавання більшої конкурентності є простою і надійною операцією. Масив типів процесів і кількість процесів кожного типу називається *формацією процесів*. -Процеси застосунку дванадцяти факторів [ніколи не мають демонізуватися](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), реагування на падіння процесів і обробку ініційованих користувачем перезавантаження чи завершення роботи. \ No newline at end of file +Процеси застосунку дванадцяти факторів [ніколи не мають демонізуватися](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), реагування на падіння процесів і обробку ініційованих користувачем перезавантаження чи завершення роботи. diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index 89a5e4d4b..87524a50a 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -7,7 +7,7 @@ **在 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](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 +这并不包括个别较为特殊的进程,例如通过虚拟机的线程处理并发的内部运算,或是使用诸如 [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈(垂直扩展),所以应用程序必须可以在多台物理机器间跨进程工作。 上述进程模型会在系统急需扩展时大放异彩。 [12-Factor 应用的进程所具备的无共享,水平分区的特性](./processes) 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 *进程构成* 。 From a79aa792f5a0f7352c5b8ac39d6400bd305e0d2c Mon Sep 17 00:00:00 2001 From: gitbreaker222 <4787651+gitbreaker222@users.noreply.github.com> Date: Tue, 27 Nov 2018 12:21:34 +0100 Subject: [PATCH 415/472] small translation update (de) targeting translation *"granular controls":* - The used translation "Kontrollschraube" does not exist. Instead use "Stellschraube" https://www.dict.cc/?s=Stellschraube - keep "granular" like used in english https://www.dict.cc/englisch-deutsch/granular.html --- content/de/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/config.md b/content/de/config.md index f70c8a9c0..641ab0ec5 100644 --- a/content/de/config.md +++ b/content/de/config.md @@ -20,4 +20,4 @@ Als Konfiguration könnte man auch Dateien verwenden, die nicht ins Versionsmana 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. +In einer Zwölf-Faktor-App sind Umgebungsvariablen granulare Stellschrauben 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. From 00ae41520a205a43c7c043803170b8ab21f9ee2e Mon Sep 17 00:00:00 2001 From: iphayao Date: Sat, 1 Dec 2018 18:28:29 +0700 Subject: [PATCH 416/472] Added Thai translation and translated home page --- content/th/admin-processes.md | 14 ++++++ content/th/background.md | 10 +++++ content/th/backing-services.md | 14 ++++++ content/th/build-release-run.md | 19 +++++++++ content/th/codebase.md | 18 ++++++++ content/th/concurrency.md | 14 ++++++ content/th/config.md | 22 ++++++++++ content/th/dependencies.md | 12 ++++++ content/th/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/th/disposability.md | 14 ++++++ content/th/intro.md | 12 ++++++ content/th/logs.md | 16 +++++++ content/th/port-binding.md | 14 ++++++ content/th/processes.md | 14 ++++++ content/th/toc.md | 38 +++++++++++++++++ content/th/who.md | 4 ++ locales/th.yml | 7 +++ 17 files changed, 318 insertions(+) create mode 100644 content/th/admin-processes.md create mode 100644 content/th/background.md create mode 100644 content/th/backing-services.md create mode 100644 content/th/build-release-run.md create mode 100644 content/th/codebase.md create mode 100644 content/th/concurrency.md create mode 100644 content/th/config.md create mode 100644 content/th/dependencies.md create mode 100644 content/th/dev-prod-parity.md create mode 100644 content/th/disposability.md create mode 100644 content/th/intro.md create mode 100644 content/th/logs.md create mode 100644 content/th/port-binding.md create mode 100644 content/th/processes.md create mode 100644 content/th/toc.md create mode 100644 content/th/who.md create mode 100644 locales/th.yml diff --git a/content/th/admin-processes.md b/content/th/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/th/admin-processes.md @@ -0,0 +1,14 @@ +## 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. diff --git a/content/th/background.md b/content/th/background.md new file mode 100644 index 000000000..fc4e1744c --- /dev/null +++ b/content/th/background.md @@ -0,0 +1,10 @@ +ประวัติ +========== + +ผู้มีส่วนร่วมของเอกสารนี้ได้มีส่วนเกี่ยวข้องโดยตรงกับการพัฒนาและการใช้งานแอพพลิเคชันจำนวนมาก และเกี่ยวข้องทางอ้อมสำหรับการพัฒนา การดำเนินงาน และการขยายขนาดของแอพพลิเคชันจำนวมมหาศาลผ่านงานของเราที่แพลตฟอร์ม Heroku + +เอกสารนี้สังเคราะห์จากประสบการณ์และการสังเกตทั้งหมดของพวกเราบนแอพพลิเคชัน software-as-a-service ที่หลากหลายจำนวนมาก เป็นสามเหลียมของแนวทางปฏิบัตในอุดมคติสำหรับการพัฒนาแอพพลิเคชัน ให้ความสนใจเป็นพิเศษกับพลวัตของการเจริญเติบโตของแอพพลิเคชันในช่วงเวลาหนึ่ง พลวัตของการมีส่วนร่วมระหว่างนักพัฒนาที่ทำงานกับ codebase ของแอพพลิเคชัน และหลีกเลี่ยงการใช้จ่ายของซอฟต์แวร์. + +แรงจูงใจของเราเพื่อสร้างความตระหนักของปัญหาระบบบางอย่างที่เราเห็นในการพัฒนาแอพพลิเคชันสมัยใหม่ เพื่อให้คำศัพย์ที่ใช้ร่วมกันสำหรับการพูดคุยเกี่ยวกับปัญหาเหล่านี้ และนำเสนอแนวทางแก้ไขแนวกว้างสำหรับปัญหาเหล่านี้พร้อมกับคำศัพท์ที่ใช้ประกอบกัน รูปแบบนี้ได้รับแรงบันดาลใจจากหนังสือของ Martin Fowler *Patterns of Enterprise Application Architecture* และ *Refactoring*. + + diff --git a/content/th/backing-services.md b/content/th/backing-services.md new file mode 100644 index 000000000..732a69b90 --- /dev/null +++ b/content/th/backing-services.md @@ -0,0 +1,14 @@ +## IV. Backing services +### Treat backing services as attached resources + +A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). + +Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). + +**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. + +Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. + +A production deploy attached to four backing services. + +Resources can be attached to and detached from deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. diff --git a/content/th/build-release-run.md b/content/th/build-release-run.md new file mode 100644 index 000000000..83525c1ec --- /dev/null +++ b/content/th/build-release-run.md @@ -0,0 +1,19 @@ +## V. Build, release, run +### Strictly separate build and run stages + +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: + +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) + +**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. + +Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. + +Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. + +Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. + diff --git a/content/th/codebase.md b/content/th/codebase.md new file mode 100644 index 000000000..234ad6725 --- /dev/null +++ b/content/th/codebase.md @@ -0,0 +1,18 @@ +## I. Codebase +### One codebase tracked in revision control, many deploys + +A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. + +A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). + +![One codebase maps to many deploys](/images/codebase-deploys.png) + +There is always a one-to-one correlation between the codebase and the app: + +* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. +* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). + +There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. + +The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. + diff --git a/content/th/concurrency.md b/content/th/concurrency.md new file mode 100644 index 000000000..32c8dab02 --- /dev/null +++ b/content/th/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrency +### Scale out via the process model + +Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. + +![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) + +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. + +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. + +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. + +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [systemd](https://www.freedesktop.org/wiki/Software/systemd/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/th/config.md b/content/th/config.md new file mode 100644 index 000000000..0bc603b82 --- /dev/null +++ b/content/th/config.md @@ -0,0 +1,22 @@ +## III. Config +### Store config in the environment + +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: + +* Resource handles to the database, Memcached, and other [backing services](./backing-services) +* Credentials to external services such as Amazon S3 or Twitter +* Per-deploy values such as the canonical hostname for the deploy + +Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. + +A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. + +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. + +Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. + +**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. + +Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. + +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. diff --git a/content/th/dependencies.md b/content/th/dependencies.md new file mode 100644 index 000000000..d53fd4cd8 --- /dev/null +++ b/content/th/dependencies.md @@ -0,0 +1,12 @@ +## 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. diff --git a/content/th/dev-prod-parity.md b/content/th/dev-prod-parity.md new file mode 100644 index 000000000..0eef17945 --- /dev/null +++ b/content/th/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod parity +### Keep development, staging, and production as similar as possible + +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: + +* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The personnel gap**: Developers write code, ops engineers deploy it. +* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. + +**The twelve-factor app is designed for [continuous deployment](http://avc.com/2011/02/continuous-deployment/) by keeping the gap between development and production small.** Looking at the three gaps described above: + +* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. +* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. +* Make the tools gap small: keep development and production as similar as possible. + +Summarizing the above into a table: + + + + + + + + + + + + + + + + + + + + + + +
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
+ +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. + +**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. + +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Docker](https://www.docker.com/) and [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. + +Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/th/disposability.md b/content/th/disposability.md new file mode 100644 index 000000000..085f2d721 --- /dev/null +++ b/content/th/disposability.md @@ -0,0 +1,14 @@ +## 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](http://kr.github.com/beanstalkd/), 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). + + diff --git a/content/th/intro.md b/content/th/intro.md new file mode 100644 index 000000000..56e45ded9 --- /dev/null +++ b/content/th/intro.md @@ -0,0 +1,12 @@ +บทนำ +============ + +ในยุคสมัยใหม่ ซอฟต์แวร์ถูกส่งมอบทั่วไปเป็นบริการ: เรียกว่า *web apps*, หรือ *software-as-service*. twelve-factor app เป็นหลัการสำหรับสร้างแอพพลิเคชัน software-as-a-service ที่: + +* ใช้รูปแบบ **declarative** สำหรับติดตั้งระบบอัตโนมัต เพื่อลดเวลาและค่าใช้จ่ายสำหรับนักพัฒนาใหม่ที่เข้าร่วมกับโครงการ; +* มี **clean contract** กับระบบปฏิบัติการที่แอพพลิเคชันทำงานด้วย นำเสนอ **maximun portibility** ระหว่างสิ่งแวดล้อมที่ระบบทำงาน; +* เหมาะสมสำหรับ **deployment** บน **cloud platforms** สมัยใหม่, ลดความต้องการของเซิร์ฟเวอร์และผู้ดูแลระบบ; +* **Maximized divergence** ระหว่างการพัฒนาและการใช้งานจริง ด้วยการใช้ **continuous deployment** เพื่อเพิ่มความเร็วสูงสุด; +* และสามารถ **scale up** โดยปราศจากการเปลี่ยนแปลงของ เครื่องมือ สถาปัตยกรรม หรือแนวทางปฏิบัตของการพัฒนา + +หลักการ twelve-factor สามารถประยุกต์ใช้ได้กับแอพพลิเคชันที่เขียนด้วยภาษาใดๆ และซึ่งใช้ร่วมกับบริการสนับสนุนใดๆ (ฐานข้อมูล, คิว, หน่วยความจำเคช เป็นต้น). \ No newline at end of file diff --git a/content/th/logs.md b/content/th/logs.md new file mode 100644 index 000000000..22e3404e7 --- /dev/null +++ b/content/th/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Treat logs as event streams + +*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. + +Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluentd](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/th/port-binding.md b/content/th/port-binding.md new file mode 100644 index 000000000..b12de8b15 --- /dev/null +++ b/content/th/port-binding.md @@ -0,0 +1,14 @@ +## VII. Port binding +### Export services via port binding + +Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). + +**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. + +In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. + +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://www.eclipse.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. + +HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). + +Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/th/processes.md b/content/th/processes.md new file mode 100644 index 000000000..f63957def --- /dev/null +++ b/content/th/processes.md @@ -0,0 +1,14 @@ +## VI. Processes +### Execute the app as one or more stateless processes + +The app is executed in the execution environment as one or more *processes*. + +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). + +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. + +The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. + +Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. + +Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). diff --git a/content/th/toc.md b/content/th/toc.md new file mode 100644 index 000000000..2e0fb2380 --- /dev/null +++ b/content/th/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Codebase](./codebase) +### มีเพียง codebase เดียวที่ติดตามด้วย version control, มีหลาย deploy + +## [II. Dependencies](./dependencies) +### มีการประกาศและแยกการอ้างอิง (dependency) ทั้งหมดอย่างชัดเจน + +## [III. Config](./config) +### จัดเก็บการตั้งค่า (config) ไว้ในสิ่งแวดล้อมของระบบ + +## [IV. Backing services](./backing-services) +### จัดการกับบริการสนับสนุน (backing service) ให้เป็นทรัพยากรที่แนบมา + +## [V. Build, release, run](./build-release-run) +### แยกขั้นตอนของการ build และ run อย่างเคร่งครัด + +## [VI. Processes](./processes) +### รันแอพพลิเคชันเป็นหนึ่งหรือมากกว่าให้เป็น stateless processes + +## [VII. Port binding](./port-binding) +### นำออกบริการด้วยการเชื่อมโยง port + +## [VIII. Concurrency](./concurrency) +### ขยายออกของแอพพลิเคชันด้วยรูปแบบ process + +## [IX. Disposability](./disposability) +### เพิ่มความแข็งแกร่งด้วยการเริ่มต้นระบบอย่างรวดเร็วและปิดระบบอย่างนุ่มนวล + +## [X. Dev/prod parity](./dev-prod-parity) +### รักษา development, staging และ production ให้มีความใกล้เคียงกันที่สุด + +## [XI. Logs](./logs) +### จัดการ logs ให้เป็นแบบ event stream + +## [XII. Admin processes](./admin-processes) +### รันงานของผู้ดูแลระบบ/การจัดการให้เป็นกระบวนการแบบครั้งเดียว diff --git a/content/th/who.md b/content/th/who.md new file mode 100644 index 000000000..2f7d1fd66 --- /dev/null +++ b/content/th/who.md @@ -0,0 +1,4 @@ +ใครควรจะอ่านเอกสารนี้? +============================== + +นักพัฒนาที่สร้างแอพพลิเคชันซึ่งทำงานเป็นเซอร์วิซ (service) วิศวกรดำเนินงานผู้ซึ่งปรับใช้ (deploy) หรือจัดการแอพพลิเคชันดังกล่าว diff --git a/locales/th.yml b/locales/th.yml new file mode 100644 index 000000000..ec1ba28de --- /dev/null +++ b/locales/th.yml @@ -0,0 +1,7 @@ +th: + # Name of language listed in locales menu + language: ภาษาไทย (th) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "แปลภาษาไทย" From 3565524c2ed40130f5a25e2cdb52ed19838cb7e1 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sun, 2 Dec 2018 20:36:21 +0700 Subject: [PATCH 417/472] Add more Thai translations --- content/th/admin-processes.md | 18 ++++++------ content/th/backing-services.md | 12 ++++---- content/th/build-release-run.md | 18 ++++++------ content/th/codebase.md | 16 +++++------ content/th/concurrency.md | 13 +++++---- content/th/config.md | 24 ++++++++-------- content/th/dependencies.md | 12 ++++---- content/th/dev-prod-parity.md | 50 +++++++++++++++++---------------- content/th/disposability.md | 13 ++++----- content/th/logs.md | 19 +++++++------ content/th/port-binding.md | 14 ++++----- content/th/processes.md | 14 ++++----- 12 files changed, 113 insertions(+), 110 deletions(-) diff --git a/content/th/admin-processes.md b/content/th/admin-processes.md index 870a56096..63a375d77 100644 --- a/content/th/admin-processes.md +++ b/content/th/admin-processes.md @@ -1,14 +1,16 @@ ## 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: +[process formation](./concurrency) เป็นอาร์เรย์ของ process ที่ใช้ในการทำธุรกิจปรกติของ app (เช่นการจัดการ reqeust ของเว็บ) ขณะทำงาน developer มักต้องการทำการดูแลหรือบำรุงรักษาเพียงคนเดียวสำหรับ app เช่น: -* 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`). +* รันการย้ายข้อมูลฐานข้อมูล (เช่น `manage.py migrate` ใน Django, `rake db:migrate` ใน Rails) +* รันคอนโซล (เป็นที่รู้จักในชื่อ [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) เพื่อรัน code แบบทันทีทันใดหรือตรวจสอบโมเดลของ app ที่ติดต่อกับฐานข้อมูลทันที ภาษาคอมพิวเตอร์ส่วนใหญ่มี REPL โดยการรัน interpreter โดยไม่ต้องมี argument ใดๆ (เช่น `python` หรือ `perl`) หรือในบางกรณีมีการแยกคำสั่ง (เช่น `irb` สำหรับ Ruby, `rails console` สำหรับ Rails) +* รันสคริปต์ครั้งเดียวที่ commit ไปที่ repo ของ app (เช่น `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. +การดูแล process ครั้งเดียวควรจะทำงานในสภาพแวดล้อมที่เหมือนกับทั้วไป [long-running processes](./processes) สำหรับ app ซึ่งทำงานกับ [release](./build-release-run) ใช้ [codebase](./codebase) and [การตั้งค่า](./config) เดียวกันกับ process ใดๆที่ทำงานกับ release ผู้ดูแลระบบของ code จำเป็นต้อง ship ด้วย application code เพื่อหลีกเลี่ยงปัญหาการประสาน (synchronization) + +เทคนิค [dependency isolation](./dependencies) เดียวกันควรจะใช้กับชนิดของ process ทั้งหมด ตัวอย่างเช่น ถ้า Ruby web process ใช้คำสั่ง `bundle exec thin start` ดังนั้นการย้ายข้อมูลฐานข้อมูลควรจะใช้คำสั่ง `bundle exec rake db:migrate` ในทำนองเดียวกันกับ Python program ใช้ Virtualenv ควรจะใช้คำสั่ง `bin/python` สำหรับทำงานทั้ง Tornado webserver และการดูแลระบบ process `manage.py` ใดๆ + +Twelve-factor ชื่นชอบภาษาคอมพิวเตอร์ที่มี PERL shell out of the box เป็นอย่างมาก และซึ่งทำให้ง่ายสำหรับรันสคริปต์ครั้งเดียว ใน local deploy, developer ใช้กระบวนการดูแลระบบครั้งเดียวโดยใช้คำสั่ง shell ข้างใน app ใน production deploy, developer สามารถใช้ ssh หรือคำสั่งรีโมทอื่นที่กลไกกำทำงานโดยสภาพแวดล้อมการดำเนินงานของ deploy เพื่อรัน process -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. diff --git a/content/th/backing-services.md b/content/th/backing-services.md index 732a69b90..4e32cb5a3 100644 --- a/content/th/backing-services.md +++ b/content/th/backing-services.md @@ -1,14 +1,14 @@ ## IV. Backing services -### Treat backing services as attached resources +### จัดการกับบริการสนับสนุน (backing service) ให้เป็นทรัพยากรที่แนบมา -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). +*บริการสนับสนุน (backing service)** เป็นบริการใดๆ ที่ app ใช้บริการผ่านระบบเครือข่ายซึ่งเป็นส่วนหนึ่งของการดำเนินงาน (operation) ตัวอย่างเช่น รวมที่เก็บข้อมูล (datastore) (เช่น [MySQL](http://dev.mysql.com/) หรือ [CouchDB](http://couchdb.apache.org/)), ระบบ messaging/queueing (เช่น [RabbitMQ](http://www.rabbitmq.com/) หรือ [Beanstalkd](https://beanstalkd.github.io)), บริการ SMTP สำหรับส่งอีเมล์ออก (เช่น [Postfix](http://www.postfix.org/)), และระบบ caching (เช่น [Memcached](http://memcached.org/)) -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). +บริการสนับสนุนอย่างเช่นฐานข้อมูลเป็นการจัดการแบบดั่งเดิมด้วยผู้จัการระบบเดียวกันกับ app ที่ทำงานหลังจาก deploy เพิ่มเติมจากบริการจัดการภายใน, app อาจจะมีบริการที่ให้บริการและจัดการโดยบริการภายนอก (third parties) ตัวอย่างเช่น รวมบริการ SMTP (เช่น [Postmark](http://postmarkapp.com/)), บริการ metrics-gathering (เช่น [New Relic](http://newrelic.com/) หรือ [Loggly](http://www.loggly.com/)), บริการ binary asset (เช่น [Amazon S3](http://aws.amazon.com/s3/)), และแม้แต่บริการ API-accessible consumer (เช่น [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), หรือ [Last.fm](http://www.last.fm/api)). -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. +**code สำหรับ twelve-factor app จะไม่มีความแตกต่างระหว่างบริการภายใน (local) และบริการภายนอก (third party)** ใน app ทั้งสองบริการจะเป็นทรัพยากรที่แนบอยู่ใน app และเข้าถึงได้ด้วย URL หรือที่เก็บ locator/credentials อื่นๆใน [การตั้งค่า](./config). [deploy](./codebase) ของ twelve-factor app ควรจะส่ามารถสลับสับเปลี่ยนฐานข้อมูล MySQL ใน app ด้วยบริการภายนอก (เช่น [Amazon RDS](http://aws.amazon.com/rds/)) โดยไม่ต้องเปลี่ยน code ของ app เหมือนกับ SMTP ภายใน app ควรสามารถสลับสับเปลี่ยนด้วยบริการ SMTP ภายนอกได้ (เช่น Postmark) โดยไม่ต้องเปลี่ยน code ในทั้งสองกรณีทรัพยากรจัดการด้วยการตั้งค่าที่จะต้องเปลี่ยนเท่านั้น -Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. +สิ่งที่แตกต่างกันของบริการสนับสนุนคือ *ทรัพยากร* ตัวอย่างเช่น ฐานข้อมูล MySQL เป็นทรัพยากร; ฐานข้อมูล MySQL 2 ฐานข้อมูล (ใช้สำหรับ sharding ใน application layer) มีคุณสมบัติเป็นทรัพยากรที่แตกต่างกัน 2 แหล่ง, twelve-factor app จักการฐานข้อมูลเป็น *ทรัพยากรแนบ (attached resouces)* ซึ่งเป็นการระบุ loose coupling กับ deploy ที่ทรัพยากรเหล่านี้แนบใช้งาน A production deploy attached to four backing services. -Resources can be attached to and detached from deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. +ทรัพยากรสามารถแนบและถอดออกจาก deploy ได้ ตัวอย่างเช่น ถ้าฐานข้อมูลของ app ทำงานผิดปรกติเนื่องจากปัญหาของฮาร์ดแวร์ ผู้ดูแลระบบของ app อาจจะ spin up เซิร์ฟเวอร์ฐานข้อมูลขึ้นมาใหม่จากการข้อมูลที่สำรองล่าสุด ฐานข้อมูลของ production ปัจจุบันควรจะถอดออกและแนบด้วยฐานข้อมูลใหม่ -- ทั้งหมดนี้ไม่มีการเปลี่ยนแปลง code diff --git a/content/th/build-release-run.md b/content/th/build-release-run.md index 83525c1ec..04366e58b 100644 --- a/content/th/build-release-run.md +++ b/content/th/build-release-run.md @@ -1,19 +1,19 @@ ## V. Build, release, run -### Strictly separate build and run stages +### แยกขั้นตอนของการ build และ run อย่างเคร่งครัด -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: +[codebase](./codebase) จะเปลี่ยนแปลงไปเป็น (non-development) deploy ด้วย 3 ขั้นตอน: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches vendors [dependencies](./dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. +* *ขั้นตอนการ build* เป็นการแปลงซึ่งเป็นการเปลี่ยน code repo ไปเป็นโปรแกรมที่ทำงานได้ (executable bundle) เรียกว่าการ *build* ใช้ version ของ code ที่ระบุ commit ด้วยกระบวนการ deployment ซึ่งขั้นตอนการ build นี้จะดึง[การอ้างอิง](./dependencies) และ compile เป็น binariy และ assets. +* *ขั้นตอนการ release* จะนำ build ที่ได้จากขั้นตอนการ build และรวามเข้ากับ [การตั้งค่า](./config) ของ deploy ซึ่งจะได้ *release* ที่มีทั้ง build และ การตั้งค่า ที่พร้อมจะทำงานได้ในสิ่งแวดล้อมการทำงาน +* *ขั้นตอนการ run* (หรือเรียกว่า "runtime") เป็นการทำให้ app ทำงานในสิ่งแวดล้อมการทำงาน ด้วยการเริ่มใช้งานบางเซตของ app [processes](./processes) ด้วย release ที่ถูกเลือก ![Code becomes a build, which is combined with config to create a release.](/images/release.png) -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. +**Twelve-factor app ใช้การแยกขั้นตอนการ build, release และ run ออกจากกันอย่างเคร่งครัด** ตัวอย่างเช่น เป็นไปไม่ได้ที่ทำการเปลี่ยนแปลงของ code ในขณะทำงาน เนื่องจากไม่มีวิธีใดในการเผยแพร่การเปลี่ยนแปลงกลับสู่สถานะ build -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. +เครื่องมื่อสำหรับ deployment โดยทั่วไปจะมีเครื่องมือจัดการการ release อยู่แล้ว และส่วนใหญ่จะมีความสามารถ roll back กลับสู่ release ก่อนหน้าได้ ตัวอย่างเช่น [Capistrano](https://github.com/capistrano/capistrano/wiki) เป็นเครื่องมือ deployment ที่เก็บการ release ในไดเรกทอรีย่อยชื่อว่า `releases` ที่ซึ่ง release ปัจจุบันเชื่อมโยงเข้ากับไดเรกทอรี release ปัจจุบัน สามารถใช้คำสั่ง `rollback` เพื่อทำให้มัน roll back กลับไปเป็น release ก่อนหน้าอย่างรวดเร็ว -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. +ทุกๆ release ควรจะมี release ID เฉพาะเสมอ เช่น timestamp ของ release (เช่น `2011-04-06-20:32:17`) หรือจำนวนนับที่เพิ่มขึ้น (เช่น `v100`), release เป็นบัญชีแยกประเภทที่เพิ่มขึ้นได้เท่านั้นและ release ไม่สามารถแก้ไขได้เมื่อถูกสร้างขึ้นแล้ว ทุกๆ การเปลี่ยนแปลงจำเป็นต้องสร้าง release ใหม่เสมอ -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. +การ build เริ่มต้นโดย developer ของ app เมื่อไรก็ตามที่ code ใหม่ถูก deploy, การทำงานในขณะทำงาน ในทางตรงกันข้าม สามารถเกิดขึ้นได้โดยอัตโนมัติในกรณีที่ server reboot หรือ crashed process ถูก restart โดย process manager ดังนั้นขั้นตอนการ run ถูกทำให้มีขั้นตอนน้อยที่สุดเท่าที่จะเป็นไปได้ เพื่อป้องกันปัญหา app สามารถหยุดการทำงานได้ในเวลาตอนกลางคืนเมื่อไม่มี developer อยู่ทำงาน ขั้นตอนการ build สามารถเป็นขั้นตอนที่ซับซ้อนได้ ในเมื่อ error จะแสดงต่อ developer ผู้ซึ่งทำการ deploy มัน diff --git a/content/th/codebase.md b/content/th/codebase.md index 234ad6725..6888ce90c 100644 --- a/content/th/codebase.md +++ b/content/th/codebase.md @@ -1,18 +1,18 @@ ## I. Codebase -### One codebase tracked in revision control, many deploys +### มีเพียง codebase เดียวที่ติดตามด้วย version control, มีหลาย deploy -A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. +Twelve-factor app สามารถติดตามได้เสมอด้วย version control เช่น [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), หรือ [Subversion](http://subversion.apache.org/) สำเนาของฐานข้อมูลติดตาม version เรียกว่า *code repository* หรือเรียกสั้นๆว่า *code repo* หรือเรียกเพียงแค่ *repo* -A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). +*codebase* เป็น repo เดียวใดๆ (ในระบบ version control ที่มีศูนย์กลางอย่างเช่น Subversion) หรือเป็นเซตของ repo ซึ่งแบ่งปัน root commit (ในระบบ version control ที่ไม่มีศูนย์กลางอย่างเช่น Git) ![One codebase maps to many deploys](/images/codebase-deploys.png) -There is always a one-to-one correlation between the codebase and the app: +มีความสัมพันธ์แบบ หนี่ง-ต่อ-หนึ่ง เสมอ ระหว่าง codebase และ app: -* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. -* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). +* ถ้ามีหลาย codebase, จะไม่เป็น app -- จะเป็นระบบกระจาย (distributed system) แต่ละคอมโพแนนท์ในระบบกระจายเป็น app, และแต่ล่ะคอมโพแนนท์จะปฏิบัติตาม twelve-factor +* ถ้ามีหลาย app ที่ใช้งาน code เดียวกันจะเป็นการละเมิด twelve-factor วิธีแก้ปัญหาในที่นี้คือเอา code ที่ใช้ร่วมกันทำเป็น libraries ซึ่งสามารถเข้ากับ factor [dependency manager](./dependencies) -There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. +มีเพียงหนึ่ง codebase ต่อ app แต่มีหลาย deploy หรือการนำไปใช้งานของ app, หนึ่ง *deploy* จะรัน instance ของ app นี่เป็น production site และมีหนึ่งหรือมากว่า staging site เพิ่มเติม, developer ทุกคนจะมีสำเนาเดียวของ app ที่ทำงานอยู่บนสิ่งแวดล้อมพัฒนาในเครื่องของตนเอง ซึ่งจัดได้ว่าเป็น deploy ด้วยเช่นกัน -The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. +Codebase จะเหมือนกันตลอดทั้ง deploy ทั้งหมด แม้ว่า version จะแตกต่างกันอาจจะทำงานในแต่ล่ะ deploy ตัวอย่างเช่น developer มีบาง commit ที่ยังไม่ได้ deploy ไปยัง staging ซึ่ง staging จะมีบาง commit ที่ยังไม่ได้ deploy ไปยัง production แต่ทั้งหมดจะใช้ codebase เดียวกัน ดังนั้นจะต้องทำให้ระบุตัวตนได้ว่าเป็น deploy ที่แตกต่างกันของ app เดียวกัน diff --git a/content/th/concurrency.md b/content/th/concurrency.md index 32c8dab02..2d616b786 100644 --- a/content/th/concurrency.md +++ b/content/th/concurrency.md @@ -1,14 +1,15 @@ ## VIII. Concurrency -### Scale out via the process model +### ขยายออกของแอพพลิเคชันด้วยรูปแบบ process -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. +โปรแกรมคอมพิวเตอร์ใดๆ เมื่อทำงานแล้วจะถูกแทนที่ด้วย 1 หรือมากกว่า process เว็บแอพมีหลายรูปแบบของ process-execution ตัวอย่างเช่น PHP process ทำงานเป็น process ลูกของ Apache, เริ่มต้นตามความต้องการตามปริมาณคำขอ, Java process มีวิธีที่ตรงกันข้ามซึ่ง JVM จะใช้หนึ่ง uberprocess ขนาดใหญ่ที่สงวนบล็อกขนาดใหญ่สำหรับทรัพยากรระบบ (CPU และหน่วยความจำ) ในตอนเริ่มต้น ซึ่งจัดการ concurrency ภายในด้วย thread ทั้งสองกรณี process ที่ทำงานเป็นส่วนที่มองเห็นน้อยมากสำหรับ developer ของ app ![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**ใน twelve-factor app, process เป็นพลเมืองชั้นหนึ่ง** Process ใน twelve-factor app จะใช้คำแนะนำจาก [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) การใช้รูปแบบนี้ developer สามารถออกแบบ app เพื่อจัดการกับ workload ที่หลากหลายโดยการกำหนดให้ work แต่ละชนิดเป็น *process type** ตัวอย่างเช่น HTTP request อาจจะจัดการด้วย web process และ long-running background tasks จัดการด้วย worker process -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +ไม่รวม process ย่อยจากการจัดการ multiplexing ภายใน ด้วย thread ข้างใน runtim VM หรือ async/evnted model ที่พบในเครื่องมือเช่น [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) หรือ [Node.js](http://nodejs.org/) แต่ VM แต่ละตัวสามารถเติบโตได้มากเท่านั้น (การขยายแนวตั้ง) ดังนั้น application จำเป็นต้องสามารถขยายเป็นหลาย process ทำงานบนหลายเครื่องได้ -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +รูปแบบ process ดีมากเมือมากับ time to scale out [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) หมายความว่าเพิ่ม concurrency ได้ง่ายและทำงานได้น่าเชื่อถือ อาเรย์ชนิดของ process และจำนวนของ process ของแต่ละชนิด รู้จักกันใน *process formation* + +Process ของ twelve-factor app [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) หรือเขียนไฟล์ PID แต่จะขึ้นอยู่กับตัวจัดการ process ของระบบปฏิบัติการแทน (เช่น [systemd](https://www.freedesktop.org/wiki/Software/systemd/), ตัวจัดการ process กระจายบน cloud platform หรือเครื่องมือ อย่างเช่น [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) ใน development) เพื่อจัดการ [output streams](./logs) ตอบสนองต่อ process ที่ล้มเหลว และจัดการ user-initiated restarts และ shutdowns -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [systemd](https://www.freedesktop.org/wiki/Software/systemd/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/th/config.md b/content/th/config.md index 0bc603b82..d094dd929 100644 --- a/content/th/config.md +++ b/content/th/config.md @@ -1,22 +1,22 @@ ## III. Config -### Store config in the environment +### จัดเก็บการตั้งค่า (config) ไว้ในสิ่งแวดล้อมของระบบ -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: +*การตั้งค่า (config)* ของ app เป็นสิ่งที่เปลี่ยนแปลงระหว่าง [deploys](./codebase) (staging, production, developer environments เป็นต้น) รวมทั้ง: -* Resource handles to the database, Memcached, and other [backing services](./backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy +* ทรัพยากรที่จัดการกับฐานข้อมูล, Memcached, และ [backing services](./backing-services) อื่นๆ +* ข้อมูลประจำตัว (credentials) สำหรับบริการภายนอก อย่างเช่น Amazon S3 หรือ Twitter +* ค่า Pre-deploy อย่างเช่น canonical hostname สำหรับ deploy -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. +บางครั้ง app เก็บการตั้งค่าเป็นค่าคงทีใน code เป็นการละเมิด twelve-factor ซึ่งต้องการให้ **แยกการตั้งค่าออกจาก code อย่างสมบูรณ์** การตั้งค่าสามารถเปลี่ยนแปลงได้ตาม deploy ที่ไม่อยู่ใน code -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. +การทดสอบ litmus เพื่อดูว่า app มีการเอาการตั้งค่าทั้งหมดออกจาก code ถูกต้องหรือไม่ ทำให้ codebase สามารถ open source ได้ตลอดเวลา โดยไม่กระทบกับ credential ใดๆ -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. +โปรดทราบว่าการนิยามนี้ของ "การตั้งค่า" **ไม่**รวมการตั้งค่า 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 -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. +อีกวิธีการหนึ่งของการตั้งค่าคือการใช้ไฟล์การตั้งค่าซึ่งไม่รวมไว้ใน revision control อย่างเช่น `config/database.yml` ใน Reals ซึ่งเป็นการพัฒนาสำหรับการใช้ค่าคงที่ซึ่งถูกรวมเข้าไปใน code repo แต่ก็ยังมีจุดอ่อนคือมันจะเกิดความผิดพลาดจากการที่รวมค่าการตั้งค่านี้เข้าไปใน repo จะทำให้มีแนวโน้มที่การไฟล์การตั้งค่าจะกระจายอยู่ในที่แตกต่างกันและแตกต่างรูปแบบ ทำให้มันยากที่จะดูแลและจัดการการตั้งค่าทั้งหมดในหนึ่งที่ นอกจากนี้รูปแบบเหล่านี้ยังขึ้นอยู่กับภาษาคอมพิวเตอร์ หรือ เฉพาะ framework. -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. +**Twelve-factor app เก็บการตั้งค่าไว้ใน *environment variable*** (เรียกสั้นๆ ว่า *env vars* หรือ *env*) Env vars จะทำให้ง่ายที่จะเปลี่ยนแปลงระหว่าง deloy โดยปราศจากการเปลี่ยนแปลงของ code ใดๆ ไม่เหมือนกับไฟล์การตั้งค่าที่จะมีโอการผิดพลาดที่จะรวมเข้าไปใน code repo ได้ และไม่เหมือนกับไฟล์การตั้งค่าที่กำหนดเองหรือกลไกการตั้งค่าอื่นๆ อย่างเช่น Java System Properties ที่เป็ของภาษาคอมพิวเตอร์ และมาตรฐานของระบบปฏิบัติการ (OS-agnostic) -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. +อีกแง่มุมของการจัดการการตั้งค่าคือการจัดกลุ่ม (Grouping) บางครั้งการตั้งค่า app แบบกลุ่ม (batch) ในชื่อของกลุ่ม (เรียกว่า "environment") หลังจาก deploy เฉพาะ อย่างเช่น `development`, `test` และ `production` environment ใน Rails วิธีการนี้ทำให้การขยายไม่เรียบร้อยทำให้มี deploy ของ app ถูกสร้างมากขึ้น, จำเป็นต้องตั้งชื่อของ environment ใหม่ อย่างเช่น `staging` หรือ `qa` เป็นตั้น เมื่อ project โตขึ้น developer อาจจะเพิ่ม environments เฉพาะของตัวเองขึ้นมา เช่น `joes-staging` ผมก็คือมีการตั้งค่าจำนวนมากเกินไปซึ่งทำให้จัดการ deploy ของ app ทำได้ยากมาก -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +ใน twelve-factor app, env vars เป็นรากฐานการควบควมของแต่ล่ะ evn vars อื่นๆ ไม่เคยมีการจัดกลุ่มเป็น "environments" แต่จะจัดการแบบอิสระสำหรับแต่ล่ะ deploy แทน นี่เป็นรูปแบบที่การขยายทำได้อย่างราบรื่นของ app เป็นการขยายโดยธรรมชาติของ deploy มากขึ้นตลอดอายุการทำงานของ app. diff --git a/content/th/dependencies.md b/content/th/dependencies.md index d53fd4cd8..652695987 100644 --- a/content/th/dependencies.md +++ b/content/th/dependencies.md @@ -1,12 +1,12 @@ ## II. Dependencies -### Explicitly declare and isolate dependencies +### มีการประกาศและแยกการอ้างอิง (dependency) ทั้งหมดอย่างชัดเจน -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"). +ภาษาโปรแกรมส่วนใหญ่จะมีระบบ packaging สำหรับรองรับ library ต่างๆ อย่างเช่น [CPAN](http://www.cpan.org/) สำหรับ Perl หรือ [Rubygems](http://rubygems.org/) สำหรับ Ruby, Library จะถูกติดตั้งผ่านทางระบบ packaging สามารถติดตั้ง system-wide (เรียกว่า "site packages") หรือกำหนดขอบเขตเป็นไดเรกทรอรีที่มี app (เรียกว่า "vendoring" หรือ "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. +**twelve-factor app ไม่ขึ้นอยู่กับ implicit existence of system-wide packages.** โดยประกาศการอ้างอิงทั้งหมด อย่างครบถ้วน และอย่างแน่นอน ด้วย *dependency declaration* manifest นอกจากนี้ใช้เครื่องมือ *dependency isolation* ระหว่างทำงานเพื่อให้แน่ใจว่าไม่มีการอ้างอิงแบบปริยาย "รั่ว (leak in)" จากระบบรอบๆ, รายละเอียดการอ้างอิงที่ครบถ้วนและชัดเจนใช้รูปแบบเดียวกันทั้ง production และ 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. +ตัวอย่างเช่น [Bundler](https://bundler.io/) สำหรับ Ruby มีรูปบบ `Gemfile` manifest สำหรับประการการอ้างอิง และ `bundle exec` สำหรับแยกการอ้างอิง ใน Python มีเครื่องมือ 2 ตัวสำหรับแต่ละขั้นตอน -- [Pip](http://www.pip-installer.org/en/latest/) ใช้สำหรับประกาศอ้างอิง และ [Virtualenv](http://www.virtualenv.org/en/latest/) สำหรับแยกการอ้างอิง แม้อย่าง C มี [Autoconf](http://www.gnu.org/s/autoconf/) สำหรับประการการอ้างอิง และ static linking สามารถทำแยกการอ้างอิงได้ ไม่ว่าจะใช้เครื่องมืออะไรก็ตามแต่การประการศและแยกการอ้างอิงจำเป็นเสมอที่ใช้ร่วมกัน -- ถ้ามีเพียงหนึ่งหรืออื่นๆ ไม่เพียงพอที่ตรงตาม 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`. +ประโยชน์อย่างหนึ่งของการประกาศการอ้างอิงที่ชัดเจนคือลดความยุ่งยากในการติดตั้งสำหรับ developer ใหม่สำหรับ app, developer ใหม่สามารถ check out codebase ของ app มายังเครื่องที่ใช้ development ต้องการเพียงแค่ติดตั้ง language runtime และ dependency manager เป็นข้อกำหนดเบื้องต้น พวกเขาจะสามามารถติดตั้งทุกสิ่งที่ต้องการเพื่อจะรัน code ของ app ด้วย *build command* ตัวอย่างเช่น ใช้ build command สำหรับ Ruby/Bundler คือ `bundle install` ขณะที่ Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) คือ `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. +Twelve-factor app ยังคงไม่ขึ้นอยู่กับเครื่องมือที่มีอยู่แล้ว ตัวอย่างเช่นใช้ shell out ไปยัง ImageMagick หรือ `curl` ขณะที่เครื่องมือเหล่านี้อาจจะมีอยู่บนระบบส่วนใหญ่แล้ว ซึ่งจะไม่รับประกันว่าจะมีอยู่บนเครื่องทั้งหมดซึ่ง app จะทำงานในอนาคต หรือ version ที่หาเจอในเครื่องที่จะไปทำงานในอนาคตจะเข้ากันได้กับ app ถ้า app จำเป็น shell out ใช้เครื่องมือของเครื่อง ที่เครื่องมืออาจจะ vendord ให้ app diff --git a/content/th/dev-prod-parity.md b/content/th/dev-prod-parity.md index 0eef17945..ef98f74c8 100644 --- a/content/th/dev-prod-parity.md +++ b/content/th/dev-prod-parity.md @@ -1,19 +1,19 @@ ## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +### ทำให้ development, staging และ production ให้มีความใกล้เคียงกันที่สุด -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +ในอดีต มีช่องว่างที่มากมายระหว่าง development (developer แก้ไข app ในเครื่องตัวเอง [deploy](./codebase)) และ production (deploy ที่ทำงานและใช้งานโดยผู้ใช้งานที่แท้จริง) ช่องว่างที่ชัดเจนมี 3 เรื่่อง: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. +* **ช่องว่างของเวลา** developer จะทำงานบน code ที่ใช้เวลาเป็นวัน, เป็นอาทิตย์ หรือเป็นเดือนที่จะเอาขึ้นสู่ production +* **ช่องว่างของบุคคล** developer เขียน code แต่วิศวกร ops ทำการ deploy code +* **ช่องว่างของเครื่องมือ** developer อาจจะใช้ stack อย่างเช่น Nginx, SQLite และ OSX ขณะที่ production deploy ใช้ Apache, MySQL และ Linux -**The twelve-factor app is designed for [continuous deployment](http://avc.com/2011/02/continuous-deployment/) by keeping the gap between development and production small.** Looking at the three gaps described above: +**Twelve-factor app ถูกออกแบบสำหรับ [การ deployment อย่างต่อเนื่อง (continuous deployment)](http://avc.com/2011/02/continuous-deployment/) ด้วยการรักษาช่องว่างระหว่าง development และ production ให้แคบที่สุด** โดยพิจารณาจากช่องว่าง 3 เรื่องด้านบน: -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. +* ทำให้เวลาสั้นลง: developer อาจจะเขียน code และทำการ deploy ในเวลาเพียงชั่วโมงเดียวหรือเพียงไม่กี่นาทีหลังจากเขียน code เสร็จ +* ทำให้ช่องว่างบุคคลแคบลง: developer เป็นคนเขียน code และเป็นคนที่ deploy code เองและเป็นคนที่ดูใน production เอง +* ทำให้ช่องว่างเครื่องมือแคบลง: ทำให้ใช้เครื่องมือ developement และ production เหมือนกันมากที่สุดเท่าที่จะทำได้ -Summarizing the above into a table: +สรุปข้างบนเป็นตาราง: @@ -22,23 +22,23 @@ Summarizing the above into a table: - - - + + + - - - + + + - - - + + +
Twelve-factor app
Time between deploysWeeksHoursเวลาระหว่าง deploysสัปดาห์ชั่วโมง
Code authors vs code deployersDifferent peopleSame peopleคนเขียน code vs คน deploy code คนละคนคนเดียวกัน
Dev vs production environmentsDivergentAs similar as possibleสภาพแวดล้อม Dev vs productionแตกต่างกันเหมือนกันมากที่สุด
-[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[Backing services](./backing-services) อย่างเช่น ฐานข้อมูลของ app, ระบบคิว, หรือ ระบบแคช เป็นสิ่งที่ dev/prod ควรมีควมคล้ายคลึงกันมากที่สุด หลายภาษามี library ซึ่งทำให้เข้าถึง backing service ได้ง่าย รวมทั้ง *adapter* กับบริการที่แตกต่างกัน ตัวอย่างบางส่วนในตารางนี้: @@ -67,10 +67,12 @@ Summarizing the above into a table:
-Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. +Developer บางครั้งหาวิธีที่ใช้ backing service ง่ายๆ ในเครื่องตัวเอง ในขณะที่ backing service ใช้งานอย่างเคร่งครัดและแข็งแกร่งใน production ตัวอย่างเช่น ใช้ SQLite ในเครื่องพัฒนา และใช้ PostgreSQL ใน production หรือใช้ local process memory สำหรับแคชใน development และ Memcached ใน production -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. +**Twelve-factor developer ต่อต้านกำใช้งาน backing service ที่แตกต่างกันระหว่าง development และ production** แม้ว่าเมื่อใช้ adapter ในทางทฤษฎีแล้วไม่มีความแตกต่างกันใน backing service ความแตกต่างระหว่าง backing service หมายความว่าความไม่เข้ากันเพียงเล็กน้อยที่เป็นสาเหตุให้ code ทำงานได้และผ่านการทดสอบใน development หรือ staging แต่ไปทำงานผิดพลาดใน production ความผิดหลาดเหล่านี้สร้างความไม่ลงรอยกันกับการ delopyment อย่างต่อเนื่อง และราคาของความไม่ลงรอยกันนี้และความผันผวนตามมาของการ deployment อย่างต่อเนื่องสูงมากเมื่อพิจารณาตลอดอายุการทำงานของ application + +Lightweight local service ไม่น่าสนใจมากเหมือนเมื่อก่อน ด้วย backing service สมัยใหม่อย่างเช่น Memcached, PostgreSQL และ RabbitMQ ไม่มีความแตกต่างกันในการติดตั้งและทำงาน ต้องขอบคุณระบบ packaging สมัยใหม่ อย่างเช่น [Homebrew](http://mxcl.github.com/homebrew/) และ [apt-get](https://help.ubuntu.com/community/AptGet/Howto) อีกทางเลือกหนึ่ง เครืองมือจัดเตรียมที่เปิดเผยอย่างเช่น [Chef](http://www.opscode.com/chef/) และ [Puppet](http://docs.puppetlabs.com/) รวม light-weight สิ่งแวดล้อมเสมือนอย่างเช่น [Docker](https://www.docker.com/) และ [Vagrant](http://vagrantup.com/) ทำให้ developer รัน app ในสิ่งแวดล้องของเครื่องได้ใกล้เคียงกับสิ่งแวดล้อมของ production มากที่สุด และค่าใช้จ่ายของการติดตั้งและใช้งานระบบเหล่านี้ต่ำมากถ้าเทียบกับประโยชน์ที่ได้รับสำหรับความเท่าเทียมกันของ dev/prod และการ deployment ที่ต่อเนื่อง + +Adapter ไปยัง backing service ที่แตกต่างกันยังคงมีประโยชน์อยู่ เพราะว่าจะทำให้ port ไปใช้กับ backing service ใหม่ๆ ได้อย่างง่ายดาย แต่การ deploy ทั้งหมดของ app (developer environment, staging, production) ควรจะใช้ชนิดและเวอร์ชันที่เหมือนกันของแต่ล่ะ backing service. -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Docker](https://www.docker.com/) and [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/th/disposability.md b/content/th/disposability.md index 085f2d721..13a884dc9 100644 --- a/content/th/disposability.md +++ b/content/th/disposability.md @@ -1,14 +1,13 @@ ## 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. +**Process ของ twelve-factor app จะต้อง **disposable**, หมายความว่าสามารถเริ่มต้นหรือหยุดในขณะที่แจ้งให้ทราบล่วงหน้า** นี่ส่งเสริมให้ขนายยื่ดหยุ่นอย่างรวดเร็ว, deployment ของการเปลี่ยนแปลง [code](./codebase) หรือ [การตั้งค่า](./config) อย่างรวดเร็ว และแข็งแกร่งสำหรับ production deploy -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. +Process ควรจะมุ่งมั่นที่จะ **ลดเวลาเริ่มต้น** จะเป็นการดีถ้า process ใช้เวลาไม่กี่วินาทีจากคำสั่งเปิดใช้งานถูกประมวลผลจนกระทั่ง process ทำงานและพร้อมสำหรับรับ request หรือ job, การใช้เวลาเริ่มต้นที่สั้นนี้จะทำให้คล่องตัวสำหรับกระบวนการ [release](./build-release-run) และขยายออก และช่วยให้แข็งแกร่งเพราะเป็นการรับประกันว่าตัวจัดการ process สามารถย้าย process ไปยังเครื่องใหม่ได้ง่าย -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. +Process จะต้อง **ปิดระบบอย่างนุ่มนวลเมื่อรับสัญญาณ [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** จากตัวจัดการ process สำหรับ process ของเว็บ การปิดระบบอย่างอย่างนุ่มนวลสำเร็จได้ด้วยสิ้นสุดการเฝ้าดู service port (ปฏิเสธ request ที่เข้ามาใหม่) ประมวลผล request ที่รับเข้ามาแล้วให้เสร็จ และออกจากโปรแกรม โดยนัยในรูปแบบนี้คือ HTTP request จะสั้นมาก (ไม่มากไปกว่าสองสามวินาที) หรือในกรณีของการประมวลผลที่ยาวนาน, client ควรจะพยายามต่อเนื่องที่จะติดต่ออีกครั้งเมื่อการเชื่อมต่อขาดหายไป -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](http://kr.github.com/beanstalkd/), 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). +สำหรับ worker process การปิดระบบอย่างนุมนวลสำเร็จได้ด้วยการคืนงานที่ทำอยู่กลับให้ work queue ตัวอย่างเช่น บน [RabbitMQ](http://www.rabbitmq.com/) worker สามารถส่ง [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack), บน [Beanstalkd](https://beanstalkd.github.io) งานจะถูกส่งกลับไปยัง queue อัตโนมัติเมือใดก็ตามที่ worker ขาดการติดต่อ ระบบ Lock-based เช่น [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) จำเป็นต้องทำให้แน่ใจว่าปล่อยงานที่ลํอกไว้ออกให้หม โดยนัยในรูปแบบนี้งานทั้งหมดเป็น [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) ซึ่งโดยปรกติจะสำเร็จด้วยการห่อผลลัพธ์ใน transaction หรือสร้างตัวดำเนินงาน [idempotent](http://en.wikipedia.org/wiki/Idempotence) +Process ควรจะ **ทนทานต่อการหยุดการทำงานอย่างฉับพลัน** ในกรณีนี้ความผิดพลาดที่เกิดขึ้นในฮาร์ดแวร์ ในขณะที่กรณีนี้เกิดขึ้นน้อยมากกว่าการปิดระบบอย่างนุ่มนวลด้วย `SIGTERM` มันก็ยังมีโอกาสเกิดขึ้นได้ วิธีที่แนะนำคือใช้ robust queueing backend อย่างเช่น Beanstalkd ที่จะส่งกลับงานไปยัง queue เมื่อ client ขาดการติดต่อหรือหมดเวลา ทั้งสองวิธี twelve-factor app จะถูกออกแบบให้จัดการกับสิ่งที่คาดไม่ถึง, มีการปิดที่ผิดปรกติ [Crash-only design](http://lwn.net/Articles/191059/) ใช้แนวคิดนี้กับ [logical conclusion](http://docs.couchdb.org/en/latest/intro/overview.html) diff --git a/content/th/logs.md b/content/th/logs.md index 22e3404e7..dc866e0f8 100644 --- a/content/th/logs.md +++ b/content/th/logs.md @@ -1,16 +1,17 @@ ## XI. Logs -### Treat logs as event streams +### จัดการ logs ให้เป็นแบบ event stream -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. +*Logs* จะทำให้เห็นได้ว่า app ทำงานอย่างไร ในสภาพแวดล้อม server-based โดยทั่วไปจะเขียนเป็นไฟล์บนดิสก์ (ใน "logfile") แต่นี่เป็นเพียง output format เท่านั้น -Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +Logs เป็น [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) ของการรวบรวม, time-ordered events ที่รวมรวมจาก output stream ของ process ทั้งหมดที่ทำงานอยู่และ backing service, Log ในรูปแบบเดิมโดยปรกติเป็นรูปแบบข้อความด้วยหนึ่ง event ต่อบรรทัด (แม้กระทั้ง backtrace จาก exception ที่มีหลายบรรทัด) Log ไม่มีจุดเริ่มต้นหรือสิ้นสุดที่แน่นอน แต่มีการไหลอย่างต่อเนื่องตราบใดที่ app ทำงานอยู่ -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +**Twelve-factor app ไม่เคยกังวลกับการกำหนดเส้นทางหรือการจัดเก็บสตรีมข้อมูลขาออก** ไม่ควรพยายามเขียนหรือจัดการ logfile แทนที่, แต่ล่ะ process ที่ทำงานจะเขียน event stream ไม่มีการบัฟเฟอร์ ด้วย `stdout` ในระหว่าง local development, developer จะดูสตรีมนี้ในเบื้องหลังของ terminal เพื่อสังเกตุพฤติกรรมของ app -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluentd](https://github.com/fluent/fluentd)) are available for this purpose. +ใน staging หรือ production deploy แต่ละสตรีมของ process จะตรวจจับโดยสภาพแวดล้อมการดำเนินงาน รวบรวมเข้าด้วยกันกับสตรีมอื่นๆ จาก app และเชื่อมเส้นทางไปที่จุดหมายปลายทางสุดท้ายที่ใช้ดูและเก็บถาวรในระยะยาว จุดหมายที่เก็บถาวรเหล่านี้ไม่สามารถมองเห็นหรือกำหนดค่าโดย app และแทนจะได้รับการจัดการอย่างสมบูรณ์โดยสภาพแวดล้อมการดำเนินงาน, Open-source log routers (เช่น [Logplex](https://github.com/heroku/logplex) และ [Fluentd](https://github.com/fluent/fluentd)) มีไว้เพื่อการนี้ -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: +สตรีมเหตุการณ์สำหรับ app สามารถกำหนดเส้นทางไปที่ไฟล์ หรือดูได้ผ่านเรียลไทม์ใน terminal สตรีมสามารถส่งไป log indexing และระบบวิเคราะห์ เช่น [Splunk](http://www.splunk.com/) หรือ ระบบคลังข้อมูลทั่วไป เช่น [Hadoop/Hive](http://hive.apache.org/) ระบบเหล่านี้มีพลังมากและยืดหยุ่นในการตรวจสอบพฤติกรรมของ app ในช่วงเวลาหนึ่ง, รวมทั้ง: + +* ค้นหาเหตุการณ์เฉพาะที่ผ่านมา +* กราฟขนาดใหญ่สำหรับแสดงแนวโน้ม (เช่น จำนวน request ต่อนาที) +* การแจ้งเตือนแบบแอคทีฟตามการวิเคราะห์พฤติกรรมที่ผู้ใช้ระบุ (เช่น การแจ้งเตือนเมื่อจำนวน error ต่อนาทีเกินเกณฑ์ที่กำหนด) -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/th/port-binding.md b/content/th/port-binding.md index b12de8b15..967e82063 100644 --- a/content/th/port-binding.md +++ b/content/th/port-binding.md @@ -1,14 +1,12 @@ ## VII. Port binding -### Export services via port binding +### นำออกบริการด้วยการเชื่อมโยง port -Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). +เว็บแอพ (Web App) บางครั้งทำงานข้างใน webserver container. ตัวอย่างเช่น PHP app จะทำงานเป็นโมดูลข้างใน [Apache HTTPD](http://httpd.apache.org/) หรือ Java app จะทำงานข้างใน [Tomcat](http://tomcat.apache.org/) เป็นต้น -**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. +**Twelve-factor app เป็น self-contained โดยสมบูรณ์** และไม่ขึ้นอยู่กับ runtime injection ของ webserver เข้ามายังสภาพแวดล้อมการดำเนินงานเพิ่อสร้าง web-facing service. เว็บแอพ **นำออก HTTP เป็นบริการโดยเชื่อมโยงกับ port** และคอยตรวจสอบ request ที่เข้ามาจาก port นั้น -In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. +นี้เป็นการทำงานปรกติโดยใช้ [ประกาศการอ้างอิง](./dependencies) เพื่อเพิ่ม webserver library ของ app, เช่น [Tornado](http://www.tornadoweb.org/) สำหรับ Python, [Thin](http://code.macournoyer.com/thin/) สำหรับ Ruby หรือ [Jetty](http://www.eclipse.org/jetty/) สำหรับ Java และภาษา JVM-based อื่นๆ เกิดขึ้นใน *user space* นั้นคือภายใน code ของ app ซึ่งสัญญากับสภาพแวดล้อมการดำเนินงานที่เชื่อมโยงกับ port เพื่อบริการ request ที่เข้ามา -This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://www.eclipse.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. +HTTP ไม่เป็นเพียง service ที่สามารถนำออกโดยการเชื่อมโยง port, server software เกือบทุกชนิดสามารถทำงานผ่านการเชื่อมโยง process ไปยัง port และรอ request ที่เข้ามา, ตัวอย่างรวมทั้ง ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), และ [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)) -HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). - -Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. +หมายเหตุ, วิธีการเชื่อมโยง port หมายความว่า app จะกลายเป็น [backing service](./backing-services) สำหรับ app อื่นๆ โดยการให้ URL กับ backing app เป็นตัวจัดการทรัพยากรใน [การตั้งค่า](./config) สำหรับใช้งาน app diff --git a/content/th/processes.md b/content/th/processes.md index f63957def..85bee3cea 100644 --- a/content/th/processes.md +++ b/content/th/processes.md @@ -1,14 +1,14 @@ ## VI. Processes -### Execute the app as one or more stateless processes +### รันแอพพลิเคชันเป็นหนึ่งหรือมากกว่าให้เป็น stateless processes -The app is executed in the execution environment as one or more *processes*. +App ทำงานในสภาพแวดล้อมการดำเนินงานด้วยหนึ่งหรือมากกว่า *processes* -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). +ในกรณีที่ง่ายที่สุดคือ code คือ stand-alone script, สภาพแวดล้อมการดำเนินงานคือเครื่องคอมพิวเตอร์อง developer ที่ติดตั้ง language runtime และวิธีการคือเปิด app ด้วยคำสั่ง (ตัวอย่างเช่น `python my_script.py`) ในอีกด้านหนึ่ง app ที่ซับซ้อนที่ deploy บน production ใช้หลาย [process types, instantiated into zero or more running processes](./concurrency) -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. +**Twelve-factor processes เป็น stateless และ [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** ข้อมูลใดๆที่จำเป็นต้องเก็บแบบถาวรจำเป็นต้องเก็บไว้ใน stateful [backing service](./backing-services) โดยปรกติจะเป็นฐานข้อมูล -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. +พื้นที่หน่วยความจำหรือระบบไฟล์ของ process สามารถใช้เป็นช่วงสั้นๆ ได้, single-transaction cache. ตัวอย่างเช่น, การดาวน์โหลดไฟล์ขนาดใหญ่, ดำเนินงานกับไฟล์นั้น และเก็บผลลัพธ์ของการดำเนินงานไว้ในฐานข้อมูล twelve-factor app ไม่เคยสมมติว่ามีอะไรแคชในหน่วยความจำหรือบน disk จะพร้อมใช้งานใน request หรือ job ในอนาคต -- มีหลาย process ทำงานมีโอกาสสูงมากที่ในอนาคต request จะทำงานบน process ที่แตกต่างกัน แม้ว่าทำงาน process เดียว เมื่อมีการ restart (trigger โดย code deploy, config change หรือเปลี่ยนสภาพแวดล้อมการทำงาน) จะลบสภานะของ app ทั้งหมดอย่างสมบูรณ์ (เช่น หน่วยความจำ และระบบไฟล์) -Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. +Asset packagers อย่างเช่น [django-assetpackager](http://code.google.com/p/django-assetpackager/) ใช้ระบบไฟล์เป็นแคชของการ compiled asset. Twelve-factor app ชอบที่จะทำ compiling เช่นนี้ในระหว่าง [ขั้นตอนการ build](/build-release-run) Asset packagers อย่างเช่น [Jammit](http://documentcloud.github.com/jammit/) และ [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) สามารถตั้งค่าให้ pacakge asset ระหว่างขั้นตอนการ build ได้ -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +บางระบบเว็บขึ้นอยู่กับ ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- นั้นคือ, ทำการแคชขอมูล user session ในหน่วยความจำของ app สำหรับดำเนินการในอนาคตจากผู้เยี่ยมชมเดียวกันที่เชื่อมโยงกับ process เดียวกัน, Sticky session เป็นการละเมิด twelve-factor และไม่ควรใช้หรือพึ่งพา, ข้อมูลสถานะ Session เป็นสิ่งที่เหมาะสมอย่างมากสำหรับที่เก็บข้อมูลที่มีการหมดเวลา (time-expireation) อย่างเช่น [Memcached](http://memcached.org/) หรือ [Redis](http://redis.io/) From 7194211390719c8a66b1285bedd3070c1c7a7654 Mon Sep 17 00:00:00 2001 From: Mattia Capitanio Date: Sat, 8 Dec 2018 18:08:54 +0100 Subject: [PATCH 418/472] fix(content/it): corrected an Italian typo --- content/it/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/dev-prod-parity.md b/content/it/dev-prod-parity.md index 7e1218f30..77e6cedc4 100644 --- a/content/it/dev-prod-parity.md +++ b/content/it/dev-prod-parity.md @@ -67,7 +67,7 @@ I [backing service](./backing-services), come il database dell'applicazione o la -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 produzone. Ancora, un sistema di cache in locale in fase di sviluppo e Memcached in produzione. +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. From ca75ab4300209bcf87281d96da8f08a73dcb1ff1 Mon Sep 17 00:00:00 2001 From: "C.J. Jameson" Date: Wed, 2 Jan 2019 12:02:14 -0800 Subject: [PATCH 419/472] clarify sysadmin wording (English) --- content/en/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/backing-services.md b/content/en/backing-services.md index 3474e1165..c8f59945e 100644 --- a/content/en/backing-services.md +++ b/content/en/backing-services.md @@ -3,7 +3,7 @@ A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](https://beanstalkd.github.io)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). +Backing services like the database are traditionally managed by the same systems administrators who deploy the app's runtime. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). **The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. From a0cb81d592b6705a104cc06f53779bd35c5182fe Mon Sep 17 00:00:00 2001 From: Guillaume Husta Date: Fri, 4 Jan 2019 14:58:13 +0100 Subject: [PATCH 420/472] Fix typos in dev-prod-parity.md --- content/fr/dev-prod-parity.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index d0a58cdc2..31ffb8c55 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -10,8 +10,8 @@ Historiquement, il y a eu un fossé conséquent entre le développement (un dév **Les applications 12 facteurs sont conçues pour le [déploiement continu (en)](http://avc.com/2011/02/continuous-deployment/) en gardant un fossé étroit entre le développement et la production.** Si l'on regarde les trois fossés décrits plus haut : * Réduire le fossé temporel : un développeur peut écrire du code et le déployer quelques heures ou même juste quelques minutes plus tard. -* Réduire le fossé des personnes : les personnes qui écrivent le code sont impliquées dans son déploiement et pour surveiller son comportement en production -* Réduire le fossé des outils : réduire, autant que possible, les différences entre le développement et la production +* Réduire le fossé des personnes : les personnes qui écrivent le code sont impliquées dans son déploiement et pour surveiller son comportement en production. +* Réduire le fossé des outils : réduire, autant que possible, les différences entre le développement et la production. Si l'on résume cela en un tableau : @@ -24,7 +24,7 @@ Si l'on résume cela en un tableau : Temps entre les déploiements Semaines - heures + Heures Auteurs du code et ceux qui le déploient @@ -44,7 +44,7 @@ Si l'on résume cela en un tableau : Type Langage - Librarie + Librairie Adaptateurs From 8aca9b98b50e5003662cd6b3aa5755b44b6f10d1 Mon Sep 17 00:00:00 2001 From: Guillaume Husta Date: Fri, 4 Jan 2019 15:05:21 +0100 Subject: [PATCH 421/472] Adding Docker next to Vagrant (french translation) Sync with PR #118 --- content/fr/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/dev-prod-parity.md b/content/fr/dev-prod-parity.md index d0a58cdc2..25f9d1bcf 100644 --- a/content/fr/dev-prod-parity.md +++ b/content/fr/dev-prod-parity.md @@ -71,6 +71,6 @@ Les développeurs trouvent parfois agréable d'utiliser des services externes l **Les développeurs des applications 12 facteurs résistent au besoin d'utiliser des services externes différents entre le développement local et la production**, même lorsque les adaptateurs permettent d'abstraire en théorie beaucoup de différences entre les services externes. Les différences entre les services externes signifient que de petites incompatibilités surviennent, ce qui va faire que du code qui fonctionnait et qui passait les tests durant le développement ou la validation ne fonctionnera pas en production. Ce type d'erreurs crée de la friction en défaveur du déploiement continu. Le coût de cette friction et son impact négatif sur le déploiement continu est extrêmement élevé lorsqu'il est cumulé sur toute la vie de l'application. -Les services locaux légers sont moins attirants aujourd'hui qu'ils ne l'étaient autrefois. Les services externes modernes tels que Memcached, PostgreSQL, et RabbitMQ ne sont pas difficiles à installer et à faire fonctionner grâce aux systèmes de paquets modernes comme [Homebrew](http://mxcl.github.com/homebrew/) et [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Autre possibilité, des outils de provisionnement comme [Chef](http://www.opscode.com/chef/) et [Puppet](http://docs.puppetlabs.com/), combinés à des environnements virtuels légers comme [Vagrant](http://vagrantup.com/) permettent aux développeurs de faire fonctionner des environnements locaux qui reproduisent de très près les environnements de production. Le coût d'installation et d'utilisation de ces systèmes est faible comparé aux bénéfices d'une bonne parité développement/production et du déploiement continu. +Les services locaux légers sont moins attirants aujourd'hui qu'ils ne l'étaient autrefois. Les services externes modernes tels que Memcached, PostgreSQL, et RabbitMQ ne sont pas difficiles à installer et à faire fonctionner grâce aux systèmes de paquets modernes comme [Homebrew](http://mxcl.github.com/homebrew/) et [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Autre possibilité, des outils de provisionnement comme [Chef](http://www.opscode.com/chef/) et [Puppet](http://docs.puppetlabs.com/), combinés à des environnements virtuels légers comme [Docker](https://www.docker.com/) et [Vagrant](http://vagrantup.com/) permettent aux développeurs de faire fonctionner des environnements locaux qui reproduisent de très près les environnements de production. Le coût d'installation et d'utilisation de ces systèmes est faible comparé aux bénéfices d'une bonne parité développement/production et du déploiement continu. Les adaptateurs à ces différents systèmes externes sont malgré tout utiles, car ils rendent le portage vers de nouveaux services externes relativement indolores. Mais tous les déploiements de l'application (environnement de développement, validation, production) devraient utiliser le même type et la même version de chacun de ces services externes. From 55d8cc61608bdf6c3482d7a2cfc2ff6fb667089c Mon Sep 17 00:00:00 2001 From: Filip Hanes Date: Mon, 18 Mar 2019 17:15:40 +0100 Subject: [PATCH 422/472] add slovak translation --- Readme.md | 19 ++++++++- content/sk/admin-processes.md | 14 ++++++ content/sk/background.md | 9 ++++ content/sk/backing-services.md | 14 ++++++ content/sk/build-release-run.md | 19 +++++++++ content/sk/codebase.md | 17 ++++++++ content/sk/concurrency.md | 14 ++++++ content/sk/config.md | 22 ++++++++++ content/sk/dependencies.md | 12 ++++++ content/sk/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/sk/disposability.md | 14 ++++++ content/sk/intro.md | 12 ++++++ content/sk/logs.md | 16 +++++++ content/sk/port-binding.md | 14 ++++++ content/sk/processes.md | 14 ++++++ content/sk/toc.md | 38 +++++++++++++++++ content/sk/who.md | 4 ++ locales/sk.yml | 7 +++ 18 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 content/sk/admin-processes.md create mode 100644 content/sk/background.md create mode 100644 content/sk/backing-services.md create mode 100644 content/sk/build-release-run.md create mode 100644 content/sk/codebase.md create mode 100644 content/sk/concurrency.md create mode 100644 content/sk/config.md create mode 100644 content/sk/dependencies.md create mode 100644 content/sk/dev-prod-parity.md create mode 100644 content/sk/disposability.md create mode 100644 content/sk/intro.md create mode 100644 content/sk/logs.md create mode 100644 content/sk/port-binding.md create mode 100644 content/sk/processes.md create mode 100644 content/sk/toc.md create mode 100644 content/sk/who.md create mode 100644 locales/sk.yml diff --git a/Readme.md b/Readme.md index 7ad77407e..95657346e 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,24 @@ Daigle, Mark Imbriaco, Keith Rarick, Will Leinweber, Jesper Jørgensen, James Ward, Adam Seligman, Phil Hagelberg, Jon Mountjoy, Matthew Turland, Daniel Jomphe, Mattt Thompson, Anand Narasimhan, Lucas Fais, Pete Hodgson -Translations and edits by: [@sigerello](https://github.com/sigerello), [@mahnunchik](https://github.com/mahnunchik), [@francescomalatesta](https://github.com/francescomalatesta), [@astralhpi](https://github.com/astralhpi), [@liangshan](https://github.com/liangshan), [@orangain](https://github.com/orangain), [@Keirua](https://github.com/Keirua), Clément Camin, Bob Marteen, [@dmathieu](https://github.com/dmathieu), [@fernandes](https://github.com/fernandes), [@gwmoura](https://github.com/gwmoura), [@lfilho](https://github.com/lfilho), [@Arturszott](https://github.com/Arturszott), [@melikeyurtoglu](https://github.com/melikeyurtoglu) and [more](https://github.com/heroku/12factor/graphs/contributors). +Translations and edits by: +[@sigerello](https://github.com/sigerello), +[@mahnunchik](https://github.com/mahnunchik), +[@francescomalatesta](https://github.com/francescomalatesta), +[@astralhpi](https://github.com/astralhpi), +[@liangshan](https://github.com/liangshan), +[@orangain](https://github.com/orangain), +[@Keirua](https://github.com/Keirua), +Clément Camin, +Bob Marteen, +[@dmathieu](https://github.com/dmathieu), +[@fernandes](https://github.com/fernandes), +[@gwmoura](https://github.com/gwmoura), +[@lfilho](https://github.com/lfilho), +[@Arturszott](https://github.com/Arturszott), +[@melikeyurtoglu](https://github.com/melikeyurtoglu), +[@filiphanes](https://github.com/filiphanes) +and [more](https://github.com/heroku/12factor/graphs/contributors). Released under the MIT License: https://opensource.org/licenses/MIT diff --git a/content/sk/admin-processes.md b/content/sk/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/sk/admin-processes.md @@ -0,0 +1,14 @@ +## 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. diff --git a/content/sk/background.md b/content/sk/background.md new file mode 100644 index 000000000..9be3f1677 --- /dev/null +++ b/content/sk/background.md @@ -0,0 +1,9 @@ +Background +========== + +The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the Heroku platform. + +This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and avoiding the cost of software erosion. + +Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *Patterns of Enterprise Application Architecture* and *Refactoring*. + diff --git a/content/sk/backing-services.md b/content/sk/backing-services.md new file mode 100644 index 000000000..3474e1165 --- /dev/null +++ b/content/sk/backing-services.md @@ -0,0 +1,14 @@ +## IV. Backing services +### Treat backing services as attached resources + +A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](https://beanstalkd.github.io)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). + +Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). + +**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. + +Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. + +A production deploy attached to four backing services. + +Resources can be attached to and detached from deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. diff --git a/content/sk/build-release-run.md b/content/sk/build-release-run.md new file mode 100644 index 000000000..83525c1ec --- /dev/null +++ b/content/sk/build-release-run.md @@ -0,0 +1,19 @@ +## V. Build, release, run +### Strictly separate build and run stages + +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: + +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) + +**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. + +Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. + +Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. + +Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. + diff --git a/content/sk/codebase.md b/content/sk/codebase.md new file mode 100644 index 000000000..e4e911b35 --- /dev/null +++ b/content/sk/codebase.md @@ -0,0 +1,17 @@ +## I. Zdrojový kód +### Jeden zdrojový kód vo verzionovacom systéme, veľa nasadení + +Dvanásť faktorová aplikácia je vždy uložená vo verzionovacom systéme ako napríklad [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), alebo [Subversion](http://subversion.apache.org/). Kópia databázy verzionovacieho systému sa nazýva *repozitár kódu*, často skrátene *repozitár* alebo len *repo*. + +*Zdrojový kód* je akýkoľvek repozitár (v centralizovanom verzionovacom systéme ako napr. Subversion), alebo akákoľvek skupina repozitárov, ktoré majú spoločný koreňový commit (v decentralizovanm verzionovacom systéme ako napr. Git). + +![Jeden zdrojový kód má viacero nasadení](/images/codebase-deploys.png) + +Vždy existuje korelácia jedna k jednej medzi zdrojovým kódom a aplikáciou: + +* Ak je to viacero zdrojových kódov, nie je to aplikácia -- je to distribuovaný systém. Každý komponent v distribuovanom systéme je aplikácia, a každá môže osobitne spĺňať dvanásť faktorov. +* Viaceré aplikácie zdieľajúce jeden kód je porušenie dvanástich faktorov. Riešenie je oddelenie zdieľaného kódu do knižníc, ktoré sa pripoja pomocou [správy závislostí](./dependencies). + +Každá aplikácia má len jeden zdrojový kód, ale nasadení jednej aplikácie bude viacero. *Nasadenie* je bežiaca inštancia aplikácie. Typicky je to produkčný web a jeden alebo viacero testovacích webov. Navyše, každý developer má kópiu bežiacej aplikácie vo svojom vlastnom vývojovom prostredí, z ktorých každé sa ráta ako nasadenie. + +Zdrojový kód je rovnaký na všetkých nasadeniach, aj keď samozrejvie rôzne verzie môžu byť aktívne na rôznych nasadeniach. Napríklad, developer má niekoľko commitov, ktoré nie sú nasadené na testovacom prostredí a na testovacom prostredí sú commity, ktoré ešte nie sú na produkcii. Ale všetky zdieľajú jeden zdrojový kód a dá sa teda povedať, že sú rôznymi nasadeniami jednej aplikácie. diff --git a/content/sk/concurrency.md b/content/sk/concurrency.md new file mode 100644 index 000000000..9e7426fcf --- /dev/null +++ b/content/sk/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrency +### Scale out via the process model + +Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. + +![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) + +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. + +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. + +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. + +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [systemd](https://www.freedesktop.org/wiki/Software/systemd/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/sk/config.md b/content/sk/config.md new file mode 100644 index 000000000..0bc603b82 --- /dev/null +++ b/content/sk/config.md @@ -0,0 +1,22 @@ +## III. Config +### Store config in the environment + +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: + +* Resource handles to the database, Memcached, and other [backing services](./backing-services) +* Credentials to external services such as Amazon S3 or Twitter +* Per-deploy values such as the canonical hostname for the deploy + +Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. + +A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. + +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. + +Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. + +**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. + +Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. + +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. diff --git a/content/sk/dependencies.md b/content/sk/dependencies.md new file mode 100644 index 000000000..d019b44b0 --- /dev/null +++ b/content/sk/dependencies.md @@ -0,0 +1,12 @@ +## II. Závislosti +### Explicitne deklarované a izolované závislosti + +Väčšina programovacích jazykov poskytuje distribučný systém knižníc, napríklad [CPAN](http://www.cpan.org/) pre Perl alebo [Rubygems](http://rubygems.org/) pre Ruby. Knižnice nainštalované cez balíčkovací systém sa dajú nainštalovať pre celý systém (nazývané "site packages") alebo len v rámci priečinka s aplikáciou (nazýva sa "vendoring" alebo "bundling"). + +**Dvanásť faktorová aplikácia sa nikdy nespolieha na implicitnú existenciou systémových balíčkov.** Svoje závislosti deklaruje úplne a presne, pomocou *deklaráciu závislostí*. Ďalej používa nástroj na *izoláciu závislostí*, pre istotu, aby žiadne implicitné závislosti "nepretiekli" z vonkajšieho systému. Špecifikácia závislostí je úplná a explicitná a používa sa rovnako na produkcii tak aj pri vývoji. + +Napríklad, [Bundler](https://bundler.io/) pre Ruby poskytuje `Gemfile` manifest format na deklaráciu závislostí a `bundle exec` na izoláciu závislostí. V pythone sú na to dva rôzne nástroje -- [Pip](http://www.pip-installer.org/en/latest/) sa používa na deklaráciu a [Virtualenv](http://www.virtualenv.org/en/latest/) na izoláciu. Dokonca aj C má [Autoconf](http://www.gnu.org/s/autoconf/) na deklaráciu závislostí, a statické linkovanie poskytuje izoláciu závislostí. Nezáleží na nástrojoch, deklarácia závislostí a izolácia sa musia vždy používať spolu -- len jedno alebo druhé nestačí na splnenie dvanástich faktorov. + +Jednou z výhod explicitnej deklarácie závislosí je to, že zjednodušuje rozbehanie aplikácie pre nových developerov. Nový developer si len naklonuje repozitár aplikácie do svojho vývojárskeho prostredia a ako prerekvizity mu stačí mať nainštalovaný kompilátor jazyka a manažér závislostí. Všetko potrebné na rozbehanie aplikácie sa dotiahne deterministickým *build príkazom*. Napríklad, build príkaz pre Ruby/Bundler je `bundle install`, pre Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) je to `lein deps`. + +Dvanásť faktorová aplikácia nezávisí na implicitnej existencii akéhokoľvek systémového nástroja. Príkladom môže byť spustenie ImageMagick alebo `curl` cez shell. Napriek tomu, že tieto nástroje môžu existovať na veľa alebo aj väčšine systémov, neexistuje záruka, že budú existovať na všetkých systémoch, na ktorých bude aplikácia bežať v budúcnosti, alebo, že verzia na budúcom systéme bude kompatibilná s aplikáciou. Ak aplikácia potrebuje spúšťať systémový nástroj cez shell, daný nástroj by mal byť zahrnutý do aplikácie. diff --git a/content/sk/dev-prod-parity.md b/content/sk/dev-prod-parity.md new file mode 100644 index 000000000..0eef17945 --- /dev/null +++ b/content/sk/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod parity +### Keep development, staging, and production as similar as possible + +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: + +* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The personnel gap**: Developers write code, ops engineers deploy it. +* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. + +**The twelve-factor app is designed for [continuous deployment](http://avc.com/2011/02/continuous-deployment/) by keeping the gap between development and production small.** Looking at the three gaps described above: + +* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. +* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. +* Make the tools gap small: keep development and production as similar as possible. + +Summarizing the above into a table: + + + + + + + + + + + + + + + + + + + + + + +
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
+ +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. + +**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. + +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Docker](https://www.docker.com/) and [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. + +Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/sk/disposability.md b/content/sk/disposability.md new file mode 100644 index 000000000..4725ef581 --- /dev/null +++ b/content/sk/disposability.md @@ -0,0 +1,14 @@ +## 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). + + diff --git a/content/sk/intro.md b/content/sk/intro.md new file mode 100644 index 000000000..2f0d0c655 --- /dev/null +++ b/content/sk/intro.md @@ -0,0 +1,12 @@ +Úvod +============ + +V modernej dobe sa zvyčajne softvér dodáva ako služba: nazýva sa *webová aplikácia*, alebo *software-as-a-service*. Dvanásť faktorová aplikácia je metodológia na budovanie software-as-a-service aplikácií, ktoré: + +* Používajú **deklaratívne** formáty na automatizáciu nastavení, a minimalizáciu času a nákladov pre nových developerov, ktorí sa začlenia do projektu; +* Obsahuje **jasnú zmluvu** s operačným systémom, nad ktorým bežia, čím umožňujú **maximálnu portabilitu** medzi rôznymi prostrediami; +* Sú vhodné na **nasadenie** na moderné **cloudové platformy**, čím vylučujú potrebu serverov a systémových administrátorov; +* **Minimalizujú rozdiely** medzi vývojom a produkciou, čím umôžňujú **continuous deployment** s maximálnou agilnosťou; +* A sú **škálovateľné** bez významných zmien v nástrojoch, architektúre alebo vývojárskych postupoch. + +Dvanásť faktorová metodológia sa dá použiť na aplikácie písané v akomkoľvek programovacom jazyku, ktoré používajú akúkoľvek kombináciu podporných služieb (databáza, fronta, pamäťová cache, atď). diff --git a/content/sk/logs.md b/content/sk/logs.md new file mode 100644 index 000000000..22e3404e7 --- /dev/null +++ b/content/sk/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Treat logs as event streams + +*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. + +Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluentd](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/sk/port-binding.md b/content/sk/port-binding.md new file mode 100644 index 000000000..b12de8b15 --- /dev/null +++ b/content/sk/port-binding.md @@ -0,0 +1,14 @@ +## VII. Port binding +### Export services via port binding + +Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). + +**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. + +In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. + +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://www.eclipse.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. + +HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). + +Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/sk/processes.md b/content/sk/processes.md new file mode 100644 index 000000000..f63957def --- /dev/null +++ b/content/sk/processes.md @@ -0,0 +1,14 @@ +## VI. Processes +### Execute the app as one or more stateless processes + +The app is executed in the execution environment as one or more *processes*. + +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). + +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. + +The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. + +Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. + +Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). diff --git a/content/sk/toc.md b/content/sk/toc.md new file mode 100644 index 000000000..c99537bb6 --- /dev/null +++ b/content/sk/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Zdrojový kód](./codebase) +### Jeden zdrojový kód vo verzionovacom systéme, veľa nasadení + +## [II. Závislosti](./dependencies) +### Explicitne deklarované a izolované závislosti + +## [III. Konfigurácia](./config) +### Konfigurácia uložená v prostredí + +## [IV. Podporné služby](./backing-services) +### Podporné služby sú pripojené zdroje + +## [V. Build, release, run](./build-release-run) +### Jasne oddelené fázy budovania, vydani a behu + +## [VI. Procesy](./processes) +### Aplikácia sa vykonáva ako jeden alebo viac bezstavových procesov + +## [VII. Port binding](./port-binding) +### Export služieb cez porty + +## [VIII. Concurrency](./concurrency) +### Škálovanie pomocou modelu procesov + +## [IX. Disposability](./disposability) +### Maximalizácia robustnosti rýchlym štartom a vhodným vypnutím + +## [X. Dev/prod parity](./dev-prod-parity) +### Vývojové testovacie a produkčné prostredie sú čo najpodobnejšie ako sa dá + +## [XI. Logy](./logs) +### Logy sú prúdy udalostí + +## [XII. Admin procesy](./admin-processes) +### Spúštanie admininstrátorských/správcovských úloh ako jednorazových procesov diff --git a/content/sk/who.md b/content/sk/who.md new file mode 100644 index 000000000..c6b834828 --- /dev/null +++ b/content/sk/who.md @@ -0,0 +1,4 @@ +Kto by si mal prečítať tento dokument? +============================== + +Každý vývojár pracujúci na aplikácii, ktorá beží ako služba. Systémoví administrátori, ktorý také aplikácie nasadzujú. diff --git a/locales/sk.yml b/locales/sk.yml new file mode 100644 index 000000000..4f9294028 --- /dev/null +++ b/locales/sk.yml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: Slovensky (sk) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: " - slovenská verzia" From 478a5114c4106ddb8f405c07da00b3ea8e156f26 Mon Sep 17 00:00:00 2001 From: Filip Hanes Date: Mon, 1 Apr 2019 22:16:53 +0200 Subject: [PATCH 423/472] slovak config and backing-services --- content/sk/backing-services.md | 16 ++++++++-------- content/sk/config.md | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/content/sk/backing-services.md b/content/sk/backing-services.md index 3474e1165..70acf4144 100644 --- a/content/sk/backing-services.md +++ b/content/sk/backing-services.md @@ -1,14 +1,14 @@ -## IV. Backing services -### Treat backing services as attached resources +## IV. Podporné služby +### Spravovanie podporných služieb ako pripojených zdrojov -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](https://beanstalkd.github.io)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). +*Podporná služba* je akákoľvek služba, ktorú aplikácia konzumuje cez sieť ako súčasť je normálneho behu. Príklady zahŕňajú databázy (ako napr. [MySQL](http://dev.mysql.com/) alebo [CouchDB](http://couchdb.apache.org/)), messaging/queueing systémy (napr. [RabbitMQ](http://www.rabbitmq.com/) alebo [Beanstalkd](https://beanstalkd.github.io)), SMTP služby pre odchádzajúce emaily (napr. [Postfix](http://www.postfix.org/)), a cachovacie systémy (napr. [Memcached](http://memcached.org/)). -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), or [Last.fm](http://www.last.fm/api)). +Podporné služby ako databázy sú tradične spravované tými istými systémovými administrátormi ako nasadenia aplikácie. Popri lokálne spravovaných službách, može mať aplikácia služby spravované tretími stranami. Príklady zahŕňajú SMTP služby (napr. [Postmark](http://postmarkapp.com/)), služby na zbieranie metrík (napr. [New Relic](http://newrelic.com/) alebo [Loggly](http://www.loggly.com/)), úložiskové služby (napr. [Amazon S3](http://aws.amazon.com/s3/)), alebo dokonca služby prístupné cez API (napr. [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), alebo [Last.fm](http://www.last.fm/api)). -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. +**Kód v dvanásť faktorovej aplikácii nerozlišuje medzi službou lokálnou a od tretej strany.** Pre aplikáciu sú obidve pripojené zdroje, prístupné cez URL alebo iné prístupové/prihlasovacie údaje uložené v [konfigurácii](./config). [Nasadenie](./codebase) dvanásť faktorovej aplikácie by malo byť schopné vymeniť lokálnu MySQL databázu s databázou spravovanou treťou stranou (napr. [Amazon RDS](http://aws.amazon.com/rds/)) bez akýchkoľvek zmien v kóde aplikácie. Podobne, lokálny SMTP server môže by vymenený SMTP službou od tretej strany (napr. Postmark) bez zmeny v kóde. V obidvoch prípado sa zmenia len prístupové a prihlasovacie údaje v konfigurácii. -Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. +Každá podporná služba je osobitným *zdrojom*. Napríklad, MySQL databáza je zdroj; dve MySQL databázy (používané na sharding na úrovni aplikácie) sú dva rôzne zdroje. Dvanásť faktorová aplikácie považuje tieto databázy ako *pripojené zdroje*, čo znamená ich voľné spojenie so súvisiacim nasadením. -A production deploy attached to four backing services. +Produkčné nasadenie pripojené ku štyrom podporným službám. -Resources can be attached to and detached from deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. +Zdroje je možné pripájať a odpájať od nasedení podľa ľubovôle. Napríklad, ak je databáza z dôvodu hardvérových problémov nestabilná, správca aplikácie môže rozbehnúť nový databázový server zo zálohy. Aktuálna produkčná databáza môže byť odpojená a nový databáza pripojená -- všetko bez zmien v kóde. diff --git a/content/sk/config.md b/content/sk/config.md index 0bc603b82..02758b2b8 100644 --- a/content/sk/config.md +++ b/content/sk/config.md @@ -1,22 +1,22 @@ -## III. Config -### Store config in the environment +## III. Konfigurácia +### Konfigurácia uložená v prostredí -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: +*Konfigurácia* aplikácie je všetko, čo sa líši medzi [nasadeniami](./codebase) (staging, produkcia, vývojárske prostredie, atď). To zahŕňa: -* Resource handles to the database, Memcached, and other [backing services](./backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy +* Pripojenia k databázam, Memcached a iným [podporným službám](./backing-services) +* Prihlasovacie údaje k externým službám ako Amazon S3 alebo Twitter +* Špeciálne hodnotu Per-nasadenie values such ako napríklad kanonické názvy hostov. -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. +Aplikácia si niekedy ukladá konštanty v kóde. Toto je porušenie dvanástich faktorov, ktoré vyžaduje **striktné oddelenie konfigurácie od kódu**. Konfigurácia sa medzi nasadeniami podstatne odlišuje, kód nie. -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. +Litmusovým testom správneho oddelenia konfigurácie, je to či by mohla byť v ktoromkoľvek momente open-sourcovaná bez úniku prihlasovacích údajov. -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. +Všimnite si, že definícia "konfigurácie" **nezahŕňa** internú konfiguráciu aplikácie, ako napríklad `config/routes.rb` v Rails, alebo [prepojenie modulov](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) v [Spring](http://spring.io/). Tento typ konfigurácie sa medzi nasadeniami nelíši, a preto je najlepšie ho nechať v kóde. -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. +Ďalšou možnosťou, ako pristupovať ku konfiguráciám je mať konfiguračné súbory, ktoré nie sú uložené v revíznom systéme, ako napríklad `config/database.yml` v Rails. Je to obrovské zlepšenie oproti konštantám uloženým v repozitári, ale stále má slabosť: je veľmi jednoduché omylom tento súbor uložiť do repozitára; je tendencia mať konfiguračné súbory na rôznych miestach a v rôznych formátoch, a preto je ťažké ich spravovať z jedného miesta. Navyše, tieto formáty zvyknú byť špecifické pre jazyk alebo framework. -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. +**Dvanásť faktorová aplikácia konfiguráciu ukladá v *premenných prostredia*** (často skrátané na *env vars* alebo *env*). Premenné prostredia sa dajú jednoducho meniť pri nasadeniach bez potreby zmeny v kóde; na rozdiel od konfiguračných súborov je minimálna šanca, že ich niekto omylom uloží do repozitára; a narozdiel od rôznych konfiguračných súborov, alebo iných konfiguračných mechanizmov ako napr. Java System Properties, premenné prostredia sú nezávislé na jazyku alebo OS. -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. +Ďalším pohľadom na správu konfigurácie je zoskupovanie. Niekedy aplikácie zoskupia konfigurácie do pomenovaných skupín (často nazývaných called "prostredia") a sú pomenované podľa jednotlivých typov nasadení, ako napríklad `development`, `test`, a `production` prostredia v Rails. Tento spôsob je náročné škálovať čistým spôsobom: ako pribúdajú ďalšie typy nasadení, je potrebné vytvárať nové názvy prostredí, ako napríklad `staging` alebo `qa`. Ako projekt ďalej rastie, developeri môžu pridávať ďalšie vlastné špeciálne prostredia ako `joes-staging`, a výsledkom je kombinatorická explózia konfiguračných prostredí a tým sa stáva spravovanie nasadení veľmi citlivé. -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +V dvanásť faktorovej aplikácii sú premenné prostredia granulárne nastavenia, každé ortogonálne k inej premennej prostredia. Nikdy sa nezoskupujú spolu do pomenovaných "prostredí", ale namiesto toho sú nezávisle spravované pre každé nasadenie. Tento model sa plynule škáluje počas prirodzeného rastu aplikácie ako pribúdajú ďalšie typy nasadení. From 7b90efb93bddf378380cabc27b12418920f4245d Mon Sep 17 00:00:00 2001 From: namiha Date: Fri, 15 Mar 2019 17:31:16 +0900 Subject: [PATCH 424/472] link error dependency -> dependencies --- content/ko/port-binding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/ko/port-binding.md b/content/ko/port-binding.md index f1ae94487..b3293d4b8 100644 --- a/content/ko/port-binding.md +++ b/content/ko/port-binding.md @@ -7,8 +7,8 @@ 로컬 개발 환경에서는 `http://localhost:5000`과 같은 주소를 통해 개발자가 애플리케이션 서비스에 접근할 수 있습니다. 배포에서는 라우팅 레이어가 외부에 공개된 호스트명으로 들어온 요청을 포트에 바인딩된 웹 프로세스에 전달 합니다. -이는 일반적으로 [종속선 선언](./dependency)에 웹서버 라이브러리를 추가함으로써 구현됩니다. 예를 들어, 파이썬의 [Tornado](http://www.tornadoweb.org/)나 루비의 [Thin](http://code.macournoyer.com/thin/)이나 자바와 JVM 기반 언어들을 위한 [Jetty](http://www.eclipse.org/jetty/)가 있습니다. 이것들은 전적으로 *유저 스페이스* 즉, 애플리케이션의 코드 내에서 처리됩니다. 실행 환경과의 규약은 요청을 처리하기 위해 포트를 바인딩하는 것입니다. +이는 일반적으로 [종속선 선언](./dependencies)에 웹서버 라이브러리를 추가함으로써 구현됩니다. 예를 들어, 파이썬의 [Tornado](http://www.tornadoweb.org/)나 루비의 [Thin](http://code.macournoyer.com/thin/)이나 자바와 JVM 기반 언어들을 위한 [Jetty](http://www.eclipse.org/jetty/)가 있습니다. 이것들은 전적으로 *유저 스페이스* 즉, 애플리케이션의 코드 내에서 처리됩니다. 실행 환경과의 규약은 요청을 처리하기 위해 포트를 바인딩하는 것입니다. 포트 바인딩에 의해 공개되는 서비스는 HTTP 뿐만이 아닙니다. 거의 모든 종류의 서버 소프트웨어는 포트를 바인딩하고 요청이 들어오길 기다리는 프로세스를 통해 실행될 수 있습니다. 예를 들면, [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/)을 따름)나 [Redis](http://redis.io/) ([Redis protocol](http://redis.io/topics/protocol)을 따름) 등이 있습니다. -포트 바인딩을 사용한다는 것은 하나의 앱이 다른 앱을 위한 백엔드 서비스가 될 수 있다는 것을 의미한다는 점에 주목합시다. 백엔드 앱의 URL을 사용할 앱의 [설정](./config)의 리소스 핸들로 추가하는 방식으로 앱이 다른 앱을 백엔드 서비스로 사용할 수 있습니다. \ No newline at end of file +포트 바인딩을 사용한다는 것은 하나의 앱이 다른 앱을 위한 백엔드 서비스가 될 수 있다는 것을 의미한다는 점에 주목합시다. 백엔드 앱의 URL을 사용할 앱의 [설정](./config)의 리소스 핸들로 추가하는 방식으로 앱이 다른 앱을 백엔드 서비스로 사용할 수 있습니다. From 5a03b7f526ffab156bfbfb0c590c503bfcb59216 Mon Sep 17 00:00:00 2001 From: Kaan Karaca Date: Fri, 5 Apr 2019 11:32:04 +0300 Subject: [PATCH 425/472] fixed square brackets typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit from [tekrar girişlidir][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), to [tekrar girişlidir] [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), need space after [tekrar girişlidir] for markdown link. --- content/tr/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/tr/disposability.md b/content/tr/disposability.md index 8618c1670..9a115d56d 100644 --- a/content/tr/disposability.md +++ b/content/tr/disposability.md @@ -7,6 +7,6 @@ Süreçler **başlangıç zamanını küçültmeye* çabalamalıdır. İdeal ola Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, incelikli kapanır.** Web süreci için incelikli kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), herhangi bir o anki isteklerin bitmesine izin verilmesi ve daha sonra çıkılmasıyla sonuçlanır. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. -Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. +Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir] [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. Süreçler esas donanımdaki hata durumlarında **ani kapanmaya karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile incelikli kapamadan daha az yaygın bir olay olduğu için hala olabilir. Önerilen yaklaşım sağlam arkaplan kuyruklama kullanımıdır, Beanstalkd gibi, istemciler oturumu kapattığı zaman veya süre dolduğu zaman işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması incelikli olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only dezaynı](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucunu](http://docs.couchdb.org/en/latest/intro/overview.html) alır. From 6173c7cd2953c7967d982162d6409dc914b6d8da Mon Sep 17 00:00:00 2001 From: Maples7 Date: Fri, 26 Apr 2019 01:26:34 +0800 Subject: [PATCH 426/472] Fix relative path for locale url --- content/zh_cn/port-binding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/port-binding.md b/content/zh_cn/port-binding.md index 3002de3ee..2c217f7c4 100644 --- a/content/zh_cn/port-binding.md +++ b/content/zh_cn/port-binding.md @@ -11,4 +11,4 @@ HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如,使用 [XMPP](http://xmpp.org/) 的 [ejabberd](http://www.ejabberd.im/) , 以及使用 [Redis 协议](http://redis.io/topics/protocol) 的 [Redis](http://redis.io/) 。 -还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](/backing-services) ,调用方将服务方提供的相应 URL 当作资源存入 [配置](/config) 以备将来调用。 +还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 [后端服务](./backing-services) ,调用方将服务方提供的相应 URL 当作资源存入 [配置](./config) 以备将来调用。 From f6063d48307aa547edf614150879499072df34d8 Mon Sep 17 00:00:00 2001 From: Maples7 Date: Fri, 26 Apr 2019 01:29:50 +0800 Subject: [PATCH 427/472] Fix relative URL path for logs in concurrency.md --- content/zh_cn/concurrency.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh_cn/concurrency.md b/content/zh_cn/concurrency.md index 87524a50a..212debfb2 100644 --- a/content/zh_cn/concurrency.md +++ b/content/zh_cn/concurrency.md @@ -11,4 +11,4 @@ 上述进程模型会在系统急需扩展时大放异彩。 [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) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 +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) ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。 From 245a4f868433121ec38cf59543f6d1ab66e782bf Mon Sep 17 00:00:00 2001 From: Youngsub Jee Date: Mon, 29 Apr 2019 21:20:09 +0900 Subject: [PATCH 428/472] Remove a duplicated sentence in Build-Releaes-Run in Korean --- content/ko/build-release-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/build-release-run.md b/content/ko/build-release-run.md index 5002edd67..00ff6aee9 100644 --- a/content/ko/build-release-run.md +++ b/content/ko/build-release-run.md @@ -3,7 +3,7 @@ [코드베이스](./codebase)는 3 단계를 거쳐 (개발용이 아닌) 배포로 변환됩니다. -* *빌드 단계*는 코드 저장소를 코드 저장소를 *빌드*라는 실행 가능한 번들로 변환시키는 단계입니다. 빌드 단계에서는 커밋된 코드 중 배포 프로세스에서 지정된 버전을 사용하며, [종속성](./dependencies)을 가져와 바이너리와 에셋들을 컴파일합니다. +* *빌드 단계*는 코드 저장소를 *빌드*라는 실행 가능한 번들로 변환시키는 단계입니다. 빌드 단계에서는 커밋된 코드 중 배포 프로세스에서 지정된 버전을 사용하며, [종속성](./dependencies)을 가져와 바이너리와 에셋들을 컴파일합니다. * *릴리즈 단계*에서는 빌드 단계에서 만들어진 빌드와 배포의 현재 [설정](./config)을 결합 합니다. 완성된 *릴리즈*는 빌드와 설정을 모두 포함하며 실행 환경에서 바로 실행될 수 있도록 준비됩니다. * *실행 단계*(런타임이라고도 하는)에서는 선택된 릴리즈에 대한 애플리케이션 [프로세스](./processes)의 집합을 시작하여, 애플리케이션을 실행 환경에서 돌아가도록 합니다. From 603927b1554e4258ebd3a44134e7db3b33fcdefa Mon Sep 17 00:00:00 2001 From: David Routen Date: Tue, 18 Jun 2019 16:57:05 -0400 Subject: [PATCH 429/472] Needs two spaces in between brackets. --- content/tr/disposability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/tr/disposability.md b/content/tr/disposability.md index 9a115d56d..05c4ac759 100644 --- a/content/tr/disposability.md +++ b/content/tr/disposability.md @@ -7,6 +7,6 @@ Süreçler **başlangıç zamanını küçültmeye* çabalamalıdır. İdeal ola Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, incelikli kapanır.** Web süreci için incelikli kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), herhangi bir o anki isteklerin bitmesine izin verilmesi ve daha sonra çıkılmasıyla sonuçlanır. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. -Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir] [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. +Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir] [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. Süreçler esas donanımdaki hata durumlarında **ani kapanmaya karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile incelikli kapamadan daha az yaygın bir olay olduğu için hala olabilir. Önerilen yaklaşım sağlam arkaplan kuyruklama kullanımıdır, Beanstalkd gibi, istemciler oturumu kapattığı zaman veya süre dolduğu zaman işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması incelikli olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only dezaynı](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucunu](http://docs.couchdb.org/en/latest/intro/overview.html) alır. From 79b172282edb62f8690dc96c8c55b68c2190098c Mon Sep 17 00:00:00 2001 From: Filip Hanes Date: Wed, 10 Jul 2019 06:24:51 +0200 Subject: [PATCH 430/472] slovak translation of 9 pages --- content/sk/admin-processes.md | 18 ++++----- content/sk/build-release-run.md | 20 +++++----- content/sk/concurrency.md | 14 +++---- content/sk/dev-prod-parity.md | 68 ++++++++++++++++----------------- content/sk/disposability.md | 14 +++---- content/sk/logs.md | 18 ++++----- content/sk/port-binding.md | 15 ++++---- content/sk/processes.md | 14 +++---- content/sk/toc.md | 4 +- 9 files changed, 93 insertions(+), 92 deletions(-) diff --git a/content/sk/admin-processes.md b/content/sk/admin-processes.md index 870a56096..21339f33e 100644 --- a/content/sk/admin-processes.md +++ b/content/sk/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Admin processes -### Run admin/management tasks as one-off processes +## XII. Admin procesy +### Spúštanie administrátorských/správcovských úloh ako jednorazových procesov -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: +[Process formation](./concurrency) je sada procesov, ktoré tvoria bežnú prevádzku aplikácie (napríklad odpovedanie na požiadavky). Na rozdiel od toho, vývojári často chcú spraviť jednorazové administratívne alebo údržbové úlohy, ako napríklad: -* 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`). +* Spustenie databázovej migrácie (e.g. `manage.py migrate` v Django, `rake db:migrate` v Rails). +* Spustenie konzoly (alebo tiež [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) aby mohli spúštať ľubovoľný kód alebo skúmať modely aplikácie voči živej databáze. Väčšina jazykov poskytuje REPL spustením interpretra bez argumentov (napr. `python` alebo `perl`) v niektorých prípadoch majú samostatný príkaz (napr. `irb` pre Ruby, `rails console` pre Rails). +* Spustenie jednorazových skriptov uložených v repozitári aplikácie (napr.. `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. +Jednorazové administračné procesy by sa mali spúštať v identickom prostredí ako bežné dlho [bežiace procesy](./processes) aplikácie. Bežia voči [releasu](./build-release-run), použitím rovnakého [kódu](./codebase) a [konfigurácie](./config) ako ostatné procesy bežiace v rámci releasu. Administračný kód sa musí dodať spolu s kódom aplikácie, aby sa zamedzilo synchronizačným problémom. -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. +Rovnaká technika [izolácie závislostí](./dependencies) by sa mala použiť pre všetky typy procesov. Napríklad, ak Ruby webový proces používa príkaz `bundle exec thin start`, potom databázová migrácia by mala používať `bundle exec rake db:migrate`. A podobne Python program používajúci Virtualenv by mal používať `bin/python` rovnako na spúšťania Tornado webservera aj všetkých `manage.py` administračných procesov. -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. +Dvanásť faktorová aplikácia silne preferuje jazyky, ktoré poskytujú REPL shell už v základe, a ktoré jednoducho umožňujú spúštanie jednorazových skriptov. Vývojári na lokálnom nasadení spúšťajú jednorazové administračné procesy priamym shell príkazom v priečinku aplikácie. V produkčnom nasadení môžu vývojári použiť ssh alebo iný spôsob vzdialeného spúšťania príkazov, ktorý poskytuje dané exekučné prostredie na spustenie takého procesu. diff --git a/content/sk/build-release-run.md b/content/sk/build-release-run.md index 83525c1ec..897146c53 100644 --- a/content/sk/build-release-run.md +++ b/content/sk/build-release-run.md @@ -1,19 +1,19 @@ ## V. Build, release, run -### Strictly separate build and run stages +### Jasne oddelené fázy build, release a run -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: +[Kód](./codebase) sa transformuje do (nevývojárskeho) nasadenia troma krokmi: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches vendors [dependencies](./dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. +* *Krok build* transformuje kód v repozitári na vykonateľný balík nazývaný *build*. Použitím verzie kódu v čase commitu špecifikovaného nasadzovacím procesom, krok build stiahne [závislosti](./dependencies) a skompiluje binárky a assets. +* *Krok release* zoberie build vytvorený predchádzajúcim krokom a skombinuje ho s aktuálnou [konfiguráciou](./config) pre dané nasadenie. Výsledok *release* obsahuje build a konfiguráciu pripravené na okamžité vykonanie v exekučnom prostredí. +* *Krok run* (alebo "runtime") spustí aplikáciu v exekučnom prostredí naštartovaním aplikačných [procesov](./processes) voči danému release. -![Code becomes a build, which is combined with config to create a release.](/images/release.png) +![Kód sa stane buildom, ktorý sa skombinuje s konfiguráciou a vytvorí sa release.](/images/release.png) -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. +**Dvanásť faktorová aplikácia striktne oddeľuje fázy build, release a run.** Napríklad: je nemožné spraviť zmeny v kóde počas jeho behu, keďže neexistuje spôsob, ako by sa tieto zmeny dostali späť do fázy build. -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. +Nástroje na nasadzovanie zvyčajne ponúkajú spôsoby na správu release, hlavne teda možnosť vrátiť sa na predchádzajúci release. Napríklad [Capistrano](https://github.com/capistrano/capistrano/wiki) si ukladá release v podpriečinku s názvom `releases`, kde je aktuálny release symlink na priečinok s aktuálnym releasom. Tento príkaz `rollback` umožňuje jednoducho a rýchlo vrátiť sa na predchádzajúci release. -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. +Každý release by mal vždy mať unikátne release ID, ako napríklad timestamp release (napríklad `2019-04-06-20:32:17`) alebo inkrementálne číslo (napr. `v100`). Releasy sú záznamy, ktoré iba pribúdajú a release sa nedá zmeniť potom jeho vytvorení. Každá zmenu musí vytvoriť nový release. -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. +Buildy inicializujú developeri aplikácie kedykoľvek sa nasadzuje nový kód. Vykonávanie behu sa na rozdiel od buildov vykonáva automaticky v prípade reštartu servera, alebo pri reštarte padnutého procesu správcom procesov. Preto by fáza spustenia mala mať čo najmenej pohyblivých častí, keďže problémy, ktoré so spustením aplikácie môžu nastať v strede noci, keď developeri nie sú k dispozícii. Fáza build môže byť komplexnejšia, keďže chyby sú vždy viditeľné developerom, ktorí spustili nasadenie. diff --git a/content/sk/concurrency.md b/content/sk/concurrency.md index 9e7426fcf..d93c854e5 100644 --- a/content/sk/concurrency.md +++ b/content/sk/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Concurrency -### Scale out via the process model +### Škálovanie pomocou modelu procesov -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. +Každý počítačový program je po spustení reprezentovaný jedným alebo viac procesmi. Webové aplikácie sa objavujú v rôznych formách vykonávania procesov. Napríklad, PHP procesy bežia ako podprocesy Apachu, spustené na požiadanie podľa objemu požiadaviek. Java procesy prevzali opačný prístup, kde JVM poskytuje jeden masívny nadproces, ktorý si vyhradí veľké množstvo systémových prostriedkov (CPU a pamäte) pri spustení a súbežnosť spravuje interne cez vlákna. V obidvoch prípadoch sú bežiace procesy len minimálne viditeľné pre developera aplikácie. -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) +![Škálovanie je vyjadrené bežiacimi procesmi, rôznorodosť funkcionality je vyjadrená typmi procesov.](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**V dvanásť faktorovej aplikácii sú procesy prvotriednymi obyvateľmi.** Procesy v dvanásť faktorovej aplikácii preberajú správanie z [modelu unix procesov pre démony služieb](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Použitím tohoto modelu, developer môže navrhnúť svoju aplikáciu tak, aby rôznu prácu vykonávali rôzne *typy procesov*. Napríklad, HTTP požiadavky môže spravovať webový proces, a dlho bežiace úlohy na pozadí môže spravovať worker proces. -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +Toto nevylučuje, že si individuálne procesy nemôžu spravovať svoj interný multiplexing cez vlákna vnútri VM alebo interpretra, alebo async/event model v nástrojoch ako [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), alebo [Node.js](http://nodejs.org/). Keďže individuálne VM môže rásť len obmedzene (vertikálne škálovanie), aplikáciu musí byť tiež schopná sa rozšíriť na viacero procesov bežiacich na viacerých fyzických strojoch. -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +Procesový model vyniká, keď príde čas rozširovania. [Nezdieľaná, horizontálne particionovateľná podstata procesov dvanásť faktorovej aplikácie](./processes) znamená, že pridanie väčšej súbežnosti je jednoduchá a spoľahlivá operácia. Súhrn typov procesov a počtu procesov každého typu sa nazýva *process formation*. -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [systemd](https://www.freedesktop.org/wiki/Software/systemd/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +Procesty dvanásť faktorovej aplikácie [by sa nikdy nemali démonizovať](http://dustin.github.com/2010/02/28/running-processes.html) alebo zapisovať PID súbory. Namiesto toho by sa mali spoliehať na manažéra procesov operačného systému (ako napr. [systemd](https://www.freedesktop.org/wiki/Software/systemd/), distribuovaného manažéra procesov na cloudovej platforme, alebo nástroji ako [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) počas vývoja) na spravovanie [výstupných streamov](./logs), reakcie na spadnuté procesy, a spravovanie userom iniciovaných reštartov a zastavení. diff --git a/content/sk/dev-prod-parity.md b/content/sk/dev-prod-parity.md index 0eef17945..f460e049d 100644 --- a/content/sk/dev-prod-parity.md +++ b/content/sk/dev-prod-parity.md @@ -1,60 +1,60 @@ ## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +### Vývojové, testovacie a produkčné prostredie sú čo najpodobnejšie ako sa dá -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +Historicky bývali podstatné rozdiely medzi vývojovým prostredím (developer upravoval živé lokálne [nasadenie](./codebase)) a produkčným prostredím (bežiace nasadenie aplikácie, na ktoré pristupujú používatelia). Tieto rozdiely sa prejavujú v týchto troch oblastiach: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. +* **Časový rozdiel:** Developer môže pracovať na kóde, ktorý trvá dni, týždne alebo dokonca mesiace pred tým ako sa dostane na produkciu. +* **Personálny rozdiel**: Developeri píšu kód, systémový administrátory ho nasadzujú. +* **Nástrojový rozdiel**: Developeri môžu používať Nginx, SQLite, a OS X, pričom na produkcii beží Apache, MySQL, a Linux. -**The twelve-factor app is designed for [continuous deployment](http://avc.com/2011/02/continuous-deployment/) by keeping the gap between development and production small.** Looking at the three gaps described above: +**Dvanásť faktorová aplikácia je navrhnutá pre [continuous deployment](http://avc.com/2011/02/continuous-deployment/) tak, že udržiava rozdiely medzi vývojom a produkciou.** Keď sa pozrieme na tri rozdiely popísané vyššie: -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. - -Summarizing the above into a table: +* Zmenšite časový rozdiel: developer napíše kód a nasadí ho v priebehu hodín alebo dokonca minút. +* Zmenšite personálny rozdiel: developeri, ktorí kód píšu by mali byť prítomní pri nasadzovaní a sledovaní správania na produkcii. +* Zmenšite nástrojvý rozdiel: udržujte vývojové a produkčné prostredie nakoľko sa dá rovnaké. +Súhrn vyššie napísaného v tabuľke: + - - + + - - - + + + - - - + + + - - - + + +
Traditional appTwelve-factor appTradičná aplikáciaDvanásť faktorová aplikácia
Time between deploysWeeksHoursČas medzi nasadeniamiTýždneHodiny
Code authors vs code deployersDifferent peopleSame peopleAutori kódu vs nasadzovači kóduRôzni ľudiaRovnakí ľudia
Dev vs production environmentsDivergentAs similar as possibleVývojárske vs produkčné prostredieRozdielneČo najpodobnejšie
-[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[Podporné služby](./backing-services) ako napríklad databáza, fronty alebo cache sú oblasťou, kde je zhodnosť vývojárskeho-produkčného prostredia dôležitá. Veľa jazykov poskytuje knižnice, ktoré uľahčujú prístup k podporným službám, vrátane *adaptérov* k rôznym typom služieb. Niektoré príklady sú v tabuľke nižšie. - - - - + + + + - + - + @@ -63,14 +63,14 @@ Summarizing the above into a table: - +
TypeLanguageLibraryAdaptersTypJazykKnižnicaAdapér
DatabaseDatabáza Ruby/Rails ActiveRecord MySQL, PostgreSQL, SQLite
QueueFronta Python/Django Celery RabbitMQ, Beanstalkd, RedisCache Ruby/Rails ActiveSupport::CacheMemory, filesystem, MemcachedPamäť, súborový systém, Memcached
-Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. +Developeri niekedy radi používajú odľahčené podporné služby na lokálny vývoj, pričom na produkcii sú robustnejšie podporné služby. Napríklad používajú SQLite lokálne a PostgreSQL na produkcii; alebo pamäť lokálneho procesu počas vývoja a Memcached na produkcii. -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. +**Dvanásť faktorový vývojár odoláva nutkaniu používať rôzne podporné služby medzi vývojom a produkciou**, aj v prípade, že adaptéry teoreticky abstrahujú rozdiely medzi službami. Rozdiely medzi službami znamenajú, že sa vyskytnú maličné nekompatibility a spôsobia, že kód prejde cez testy pri vývoji alebo testovaní a zlyhá na produkcii. Tieto typy chýb vytvárajú trenie, ktoré spomaľuje priebežné nasadzovanie. Cena tohoto trenia a následné spomalenie priebežného nasadzovania je extrémne vysoká, keď ju sčítame cez celú životnosť aplikácie. -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Docker](https://www.docker.com/) and [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. +Odľahčené lokálne služby už nie sú také príťažlivé ako boli. Moderné podporné služby ako Memcached, PostgreSQL a RabbitMQ nie je ťažké nainštalovať a spustiť vďaka moderným balíčkovacím systémom ako [Homebrew](http://mxcl.github.com/homebrew/) a [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatívne deklaratívne nástroje ako [Chef](http://www.opscode.com/chef/) a [Puppet](http://docs.puppetlabs.com/) skombinované s odľahčenými virtuálnymi prostrediami ako [Docker](https://www.docker.com/) a [Vagrant](http://vagrantup.com/) umôžňujú vývojárom vytvoriť lokálne prostredie, ktoré tesne aproximuje produkčné prostredie. Cena inštalácie a používania týchto systémov je nízka v porovnaní s výhodami rovnakého prostredia vývoj/produkcia. -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. +Adaptéry k rôznym podporným službám sú stále užitočné, pretože umožňujú plynulú migráciu na nové podporné služby. Ale všetky nasadenia aplikácia (vývojárske prostredie, testovacie, produkcia) by mali používať rovnaký typ a verziu každej podpornej služby. diff --git a/content/sk/disposability.md b/content/sk/disposability.md index 4725ef581..d791c3cbc 100644 --- a/content/sk/disposability.md +++ b/content/sk/disposability.md @@ -1,14 +1,14 @@ -## IX. Disposability -### Maximize robustness with fast startup and graceful shutdown +## IX. Zahoditeľnosť +### Maximalizácia robustnosti rýchlym štartom a vhodným vypnutím -**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. +**[Procesy](./processes) dvanásť faktorovej aplikácie sú *zahoditeľné*, čo znamená, že sa kedykoľvek dajú spustiť alebo zastaviť.** Umožňuje to elastické škálovanie, rýchly vývoj [kódu](./codebase) alebo zmeny v [konfigurácii](./config), a robustnosť produkčných nasadení. -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. +Procesy by sa mali snažiť **minimalizovať čas spustenia**. Ideálne, procesu zaberie len pár sekúnd od spustenia príkazu do kým je proces pripravený prijímať požiadavky alebo úlohy. Krátky čas spustenia poskytuje väčšiu agility pre [release](./build-release-run) proces a škálovanie; a pomáha tiež robustnosti, lebo manažér procesov, môže jednoduchšie presúvať procesy na nové fyzické stroje v prípade potreby. -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. +Procesy **sa vhodne vypnú po prijatí signálu [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od správcu procesov. Pre webový proces, vhodné vypnutie znamená, že prestane počúvať na porte (teda začne odmietať nové požiadavky), aktuálne bežiace požiadaviek nechá dobehnúť a vypne sa. V tomto modeli predpokladáme, že HTTP požiadavky sú krátke (nie viac ako pár sekúnd). V prípade dlhotrvajúcich spojení by sa mal klient vedieť po strate spojenia znova pripojiť. -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). +Pre proces workera, je vhodné vypnutie dosiahnuté vrátením aktuálnej úlohy do pracovnej fronty. For a worker process, graceful shutdown is achieved by returning the current job to the work queue. Napríklad pri [RabbitMQ](http://www.rabbitmq.com/) worker môže poslať [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); pri [Beanstalkd](https://beanstalkd.github.io) sa úloha vrátiť do fronty keď sa worker odpojí. Systéme postavené na zamkýnaní, ako napr. [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) musia uvoľniť zamknutie pre záznam svojej úlohy. V tomto modeli predpokladáme, že všetky úlohy sú [opakovateľné](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), čo sa zvyčajne dosiahne obalením výsledkov do transakcie alebo spravením operácie [idempotentnou](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). +Procesy by mali byť tiež **robustné proti náhlej smrti**, v prípade zlyhanie hardvéru. Aj keď je toto vyskytuje oveľa menej často ako vypnutie signálom `SIGTERM`, môže sa to stať. Odporúčaný prístup je použitie robustnej fronty, ako napr. Beanstalkd, ktorá vracia úlohy do fronty pri odpojení klienta alebo vypršaní časového limitu. V každom prípade, dvanásť faktorová aplikácia je navrhnutá, aby zvládla neočakávané, nevhodné ukončenia. [Crash-only design](http://lwn.net/Articles/191059/) tento koncept vedie k [logickým záverom](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/sk/logs.md b/content/sk/logs.md index 22e3404e7..2d98128d1 100644 --- a/content/sk/logs.md +++ b/content/sk/logs.md @@ -1,16 +1,16 @@ ## XI. Logs -### Treat logs as event streams +### Logy sú prúdy udalostí -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. +*Logy* poskytujú náhľad do správania sa bežiacej aplikácie. V prostredí serverov sa zvyčajne zapisujú do súboru na disk (tzv. "logfile"); ale toto je len výstupný formát. -Logs are the [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +Logy sú [prúd](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) agregovaných, časovo zoradených udalostí pozbierané z výstupných prúdov všetkých bežiacich procesov a podporných služieb. Logy sú vo svojej surovej forme zvyčajne v textovom formáte s jednou udalosťou na riadok (thougaj keď výpisy výnimiek môžu zaberať viac riadkov). Logy nemajú pevný začiatok ani koniec, ale plynule prúdia počas behu aplikácie. -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +**Dvanásť faktorová aplikácia sa nikdy nestará o routovanie alebo ukladanie svojho výstupného prúdu.** Nemala by sa pokúšať zapisovať alebo spravovať logsúbory. Namiesto toho každý bežiaci proces zapisuje svoje udalosti nebufferované do `stdout`. Počas lokálneho vývoja vývojár vidí tento prúd udalostí vo svojom termináli a sleduje správanie aplikácie. -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluentd](https://github.com/fluent/fluentd)) are available for this purpose. +V testovacom a produkčnom prostredí, sa prúd každého procesu zachytáva exekučné prostredie, spája s ostatnými prúdmi z aplikácie a presmeruje do cieľovej destinácie na prehliadanie a dlhodobejšie uloženie. Tieto destinácie nie sú konfigurovateľné aplikáciou, ale namiesto toho sú kompletne spravované exekučným prostredím. Open-sourcové smerovače logov (ako napr. [Logplex](https://github.com/heroku/logplex) a [Fluentd](https://github.com/fluent/fluentd)) sú vytvorené na tento účel. -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: +Prúd udalostí z aplikácie sa dá presmerovať do súboru, alebo sledovať priamo v termináli. Čo je ešte dôležitejšie je, že tento prúd sa dá poslať do systému na indexovanie a analýzu logov ako napr. [Splunk](http://www.splunk.com/), alebo univerzálne uložiská ako [Hadoop/Hive](http://hive.apache.org/). Tieto systému sú mocné a flexibilné na skúmanie správania aplikácie v čase, vrátane: -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). +* Nájdenie špecifických udalostí v minulosti. +* Veľkoplošné grafovanie trendov (ako napr. počet požiadaviek za minútu). +* Aktívne upozorňovanie podľa zadaných pravidiel (napríklad keď množstvo chýb za minútu presiahne určitú hranicu). diff --git a/content/sk/port-binding.md b/content/sk/port-binding.md index b12de8b15..ac15abd15 100644 --- a/content/sk/port-binding.md +++ b/content/sk/port-binding.md @@ -1,14 +1,15 @@ ## VII. Port binding -### Export services via port binding +### Export služieb cez port binding -Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). +Webové aplikácie sú niekedy vykonávané vnútri webserverového kontainera. Napríklad PHP aplikácie bežia ako modul vnútri [Apache HTTPD](http://httpd.apache.org/), alebo Java aplikácie môžu bežať vnútri [Tomcat](http://tomcat.apache.org/). -**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. +**Dvanásť faktorová aplikácia je úplne sebestačn** a nespolieha sa na vsunutie webservera v exekučnom prostredí na to, aby vytvorila webovú službu. Webová aplikácia **exportuje HTTP ako službu bindovaním na port**, a počúvaním požiadaviek prichádzajúcich na daný port. -In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. +V lokálnom vývojárskom prostredí developer pristupuje na službu exportovanú jeho aplikáciou cez URL napríklad `http://localhost:5000/`. Pri nasadení, smerovacia vrstva presmerúva požiadavky z verejnej domény na port web procesu. -This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://www.eclipse.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. +Toto sa typicky implementuje použitím [deklarácie závislostí](./dependencies) a pridá sa tak knižnica webservera do aplikácie. Napríklad [Tornado](http://www.tornadoweb.org/) pre Python, [Thin](http://code.macournoyer.com/thin/) pre Ruby, alebo [Jetty](http://www.eclipse.org/jetty/) pre Javu a iných jazykoch bežiacich na JVM. Deje sa to úplne v *používateľskom priestore*, takže v kóde aplikácie. Dohoda s exekučným prostredím je je bindovanie na port na ktorom bude obsluhovať požiadavky. -HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). +HTTP nie je jediná služba, ktorú je možné exportovať bindovaním na port. Skoro každý serverový softvér môže bežať na otvorenom porte a čakať na prichádzajúce požiadavky. Príklady zahŕňajú [ejabberd](http://www.ejabberd.im/) (protokol [XMPP](http://xmpp.org/)), a [Redis](http://redis.io/) (protokol [Redis](http://redis.io/topics/protocol)). + +Všimnite si, že pripojenie na port znamená, že aplikácia sa môže stať [podpornou službou](./backing-services) pre inú aplikáciu, poskytnutím URL na podpornú službu ako zdroj v [configu](./config) pre konzumujúcu aplikáciu. -Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/sk/processes.md b/content/sk/processes.md index f63957def..071498b51 100644 --- a/content/sk/processes.md +++ b/content/sk/processes.md @@ -1,14 +1,14 @@ -## VI. Processes +## VI. Procesy ### Execute the app as one or more stateless processes -The app is executed in the execution environment as one or more *processes*. +Aplikácia sa vykonáva v exekučnom prostredí ako jeden alebo viac *procesov*. -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). +V najjednoduchšom prípade je kód jednoduchý skript, exekučné prostredie je laptop developera s nainštalovaným kompilátorom/interpretrom jazyka, a proces sa spúšta z príkazového riadka (napríklad, `python my_script.py`). Na druhej strane spektra, produkčné nasadenie sofistikovanej aplikácie môže mať viacero [typov procesov, inštancovaných do jedného alebo viacerých procesov](./concurrency). -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. +**Dvanásť faktorové procesy sú bezstavové a [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Akékoľvek dáta, ktoré treba zachovať, musia byť uložené v stavovej [podpornej službe](./backing-services), typicky databáze. -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. +Priestor pamäte alebo súborového systému procesu sa môže použiť ako krátka cache pre jednu transakciu. Napríklad, stiahnutie veľkého súboru, práca nad ním a uloženie výsledkov operácie do databázy. Dvanásť faktorová aplikácia nikdy neočakáva, že by bolo čokoľvek nacachované v pamäti alebo na disku pre budúce požiadavky alebo úlohy -- je vysoká šanca, že pri viacerých bežiacich procesoch bude ďalšia požiadavka vykonaná iným procesom. Aj keď beží len jeden process, reštart (spustený nasadením kódu, zmenou konfigurácie, alebo exekučným prostredím premiestni proces na iné fyzické miesto) zvyčajne vymaže všetky lokálne (napr. pamäť a súborový systém) stavy. -Asset packagers like [django-assetpackager](http://code.google.com/p/django-assetpackager/) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](/build-release-run). Asset packagers such as [Jammit](http://documentcloud.github.com/jammit/) and the [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) can be configured to package assets during the build stage. +Balíčkovače ako napríklad [django-assetpackager](http://code.google.com/p/django-assetpackager/) používajú súborový systém ako cache na kompilované súbory. Dvanásť faktorová aplikácia preferuje túto kompiláciu počas [fázy build](/build-release-run). Balíčkovače [Jammit](http://documentcloud.github.com/jammit/) a [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) sa dajú nakonfigurovať, tak, že zabalia súbory počas fázy build. -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +Niektoré webové systémy sa spoliehajú na ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- teda cachovanie údajov o používateľskom sedení v pamäti procesu a očakávajú, že ďalšie požiadavky od daného návštevníka budú presmerované na ten istý proces. Sticky sessions sú porušením dvanástich faktorov a nemali by sa nikdy používať ani na ne spoliehať. Stav sedenia je dobrým kandidátom pre úložisko, ktoré poskytuje vypršanie po čase, ako napr. [Memcached](http://memcached.org/) alebo [Redis](http://redis.io/). diff --git a/content/sk/toc.md b/content/sk/toc.md index c99537bb6..4b84ea62d 100644 --- a/content/sk/toc.md +++ b/content/sk/toc.md @@ -29,10 +29,10 @@ The Twelve Factors ### Maximalizácia robustnosti rýchlym štartom a vhodným vypnutím ## [X. Dev/prod parity](./dev-prod-parity) -### Vývojové testovacie a produkčné prostredie sú čo najpodobnejšie ako sa dá +### Vývojové, testovacie a produkčné prostredie sú čo najpodobnejšie ako sa dá ## [XI. Logy](./logs) ### Logy sú prúdy udalostí ## [XII. Admin procesy](./admin-processes) -### Spúštanie admininstrátorských/správcovských úloh ako jednorazových procesov +### Spúštanie administrátorských/správcovských úloh ako jednorazových procesov From e97ba6c11d478373e6429e7e1bef7c3a407719ce Mon Sep 17 00:00:00 2001 From: David Routen Date: Mon, 15 Jul 2019 12:55:32 -0400 Subject: [PATCH 431/472] Update Ruby to 2.6.3 --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ruby-version b/.ruby-version index aedc15bb0..ec1cf33c3 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.3 +2.6.3 diff --git a/Gemfile b/Gemfile index 74131e760..ffe4ab7a0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.5.3' +ruby '2.6.3' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index 516f82ffa..f5b7a45fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.5.3p105 + ruby 2.6.3p62 BUNDLED WITH - 1.16.6 + 1.17.2 From f18152445f72952d183a1deb149516d7075fbe6d Mon Sep 17 00:00:00 2001 From: David Routen Date: Mon, 15 Jul 2019 13:24:37 -0400 Subject: [PATCH 432/472] This outta do the trick! --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f53bbd4a..18a88fd77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.5.3 + - 2.6.3 script: exit 0 sudo: false From 65a5939f6d7a6ec308cb5a5ba0662351238f02bb Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Mon, 15 Jul 2019 19:42:32 +0200 Subject: [PATCH 433/472] Remove Travis YAML file --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 18a88fd77..000000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: ruby -rvm: - - 2.6.3 -script: exit 0 -sudo: false From 804f20e57d74aa70f4edc95ca7a31d0ca03053f5 Mon Sep 17 00:00:00 2001 From: Andrea Di Stefano Date: Thu, 25 Jul 2019 12:13:28 +0200 Subject: [PATCH 434/472] Edit typo in italian Intro --- content/it/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/intro.md b/content/it/intro.md index a67cc79d4..a3dcf5450 100644 --- a/content/it/intro.md +++ b/content/it/intro.md @@ -5,7 +5,7 @@ Nell'era moderna, il software viene fornito sempre più di frequente come serviz * Seguono un formato **dichiarativo** per l'automazione della configurazione, minimizzando tempi e costi di ingresso per ogni sviluppatore che si aggiunge al progetto; * **Si interfacciano in modo pulito** con il sistema operativo sottostante, in modo tale da offrire la **massima portabilità** sui vari ambienti di esecuzione; -* Sono **adatti allo sviluppo** sulle più recenti **cloud platform**, ovviando alla necessità di server e amministrazioni di sistema; +* Sono **adatte allo sviluppo** sulle più recenti **cloud platform**, ovviando alla necessità di server e amministrazioni di sistema; * **Minimizzano la divergenza** tra sviluppo e produzione, permettendo il **contiuous deployment** per una massima "agilità"; * Possono **scalare significativamente** senza troppi cambiamenti ai tool, all'architettura e al processo di sviluppo; From d2dd5404bb29329b574468536637e8ab868f93b5 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Fri, 23 Aug 2019 07:56:19 +0200 Subject: [PATCH 435/472] Restore .travis.yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..18a88fd77 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: ruby +rvm: + - 2.6.3 +script: exit 0 +sudo: false From 3d8e726a2f8d28b4ee5dce980b76a1f2ffdc503b Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 3 Sep 2019 12:28:31 +0200 Subject: [PATCH 436/472] Correct key of the Slovenish locale Fixes #232 --- locales/sk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/sk.yml b/locales/sk.yml index 4f9294028..795b517f8 100644 --- a/locales/sk.yml +++ b/locales/sk.yml @@ -1,4 +1,4 @@ -en: +sk: # Name of language listed in locales menu language: Slovensky (sk) From f86fd24b5871c6fdbf391717300b7c68f00fe795 Mon Sep 17 00:00:00 2001 From: Andrea Di Stefano Date: Fri, 23 Aug 2019 20:35:56 +0200 Subject: [PATCH 437/472] Edit another typo in content/it/intro.md contiuous -> continuous --- content/it/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/it/intro.md b/content/it/intro.md index a3dcf5450..29ecae8ea 100644 --- a/content/it/intro.md +++ b/content/it/intro.md @@ -6,7 +6,7 @@ Nell'era moderna, il software viene fornito sempre più di frequente come serviz * Seguono un formato **dichiarativo** per l'automazione della configurazione, minimizzando tempi e costi di ingresso per ogni sviluppatore che si aggiunge al progetto; * **Si interfacciano in modo pulito** con il sistema operativo sottostante, in modo tale da offrire la **massima portabilità** sui vari ambienti di esecuzione; * Sono **adatte allo sviluppo** sulle più recenti **cloud platform**, ovviando alla necessità di server e amministrazioni di sistema; -* **Minimizzano la divergenza** tra sviluppo e produzione, permettendo il **contiuous deployment** per una massima "agilità"; +* **Minimizzano la divergenza** tra sviluppo e produzione, permettendo il **continuous deployment** per una massima "agilità"; * Possono **scalare significativamente** senza troppi cambiamenti ai tool, all'architettura e al processo di sviluppo; La metodologia twelve-factor può essere applicata a ogni software, scritto in qualsiasi linguaggio di programmazione, che fa uso di una serie di servizi come database, code, cache e così via. From d4b77e37c5411b24c2d88482f87964799c507215 Mon Sep 17 00:00:00 2001 From: Nikos M Date: Sat, 12 Oct 2019 11:51:45 +0300 Subject: [PATCH 438/472] Greek Translation (el) --- content/el/admin-processes.md | 14 ++++++ content/el/background.md | 9 ++++ content/el/backing-services.md | 14 ++++++ content/el/build-release-run.md | 19 +++++++++ content/el/codebase.md | 18 ++++++++ content/el/concurrency.md | 14 ++++++ content/el/config.md | 22 ++++++++++ content/el/dependencies.md | 12 ++++++ content/el/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/el/disposability.md | 14 ++++++ content/el/intro.md | 12 ++++++ content/el/logs.md | 16 +++++++ content/el/port-binding.md | 14 ++++++ content/el/processes.md | 14 ++++++ content/el/toc.md | 38 +++++++++++++++++ content/el/who.md | 4 ++ locales/el.yml | 7 +++ 17 files changed, 317 insertions(+) create mode 100644 content/el/admin-processes.md create mode 100644 content/el/background.md create mode 100644 content/el/backing-services.md create mode 100644 content/el/build-release-run.md create mode 100644 content/el/codebase.md create mode 100644 content/el/concurrency.md create mode 100644 content/el/config.md create mode 100644 content/el/dependencies.md create mode 100644 content/el/dev-prod-parity.md create mode 100644 content/el/disposability.md create mode 100644 content/el/intro.md create mode 100644 content/el/logs.md create mode 100644 content/el/port-binding.md create mode 100644 content/el/processes.md create mode 100644 content/el/toc.md create mode 100644 content/el/who.md create mode 100644 locales/el.yml diff --git a/content/el/admin-processes.md b/content/el/admin-processes.md new file mode 100644 index 000000000..0d57dae7a --- /dev/null +++ b/content/el/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Διεργασίες διαχείρισης +### Εκτέλεση εργασιών διαχείρισης ως διεργασίες μια και έξω + +Ο [σχηματισμός διεργασιών (process formation)](./concurrency) είναι η συστοιχία των διεργασιών που κάνουν τη συνήθη εργασία της εφαρμογής (όπως να χειρίζονται αιτήσεις ιστού) καθώς τρέχει. Ξεχωριστά, οι προγραμματιστές θα θέλουν συχνά να κάνουν διαχειριστικές εργασίες ή εργασίες συντήρησης μια και έξω, όπως: + +* Να τρέξουν αλλαγές στη βάση δεδομένων (database migrations) (π.χ. `manage.py migrate` στο Django, `rake db:migrate` στο Rails). +* Να τρέξουν μια κονσόλα (επίσης γνωστή ως κέλυφος [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) για να εκτελέσουν οποιοδήποτε κώδικα ή να επιθεωρήσουν τα μοντέλα της εφαρμογής σε σχέση με μια ζωντανή βάση δεδομένων. Οι περισσότερες γλώσσες προγραμματισμού προσφέρουν ένα REPL μέσω της εκτέλεσης του διερμηνέα χωρίς άλλα ορίσματα (π.χ. `python` ή `perl`) ή σε ορισμένες περιπτώσεις έχουν μια ξεχωριστή εντολή (π.χ. `irb` για τη Ruby, `rails console` για το Rails). +* Να τρέξουν σενάρια εντολών μια και έξω τα οποία είναι εισηγμένα στο αποθετήριο της εφαρμογής (π.χ. `php scripts/fix_bad_records.php`). + +Οι διεργασίες διαχείρισης μια και έξω θα πρέπει να εκτελούνται σε ένα πανομοιότυπο περιβάλλον όπως το κανονικό περιβάλλον των [διεργασιών μακράς διάρκειας](./processes) της εφαρμογής. Εκτελούνται πάνω σε μια [έκδοση (release)](./build-release-run), χρησιμοποιώντας την ίδια [βάση κώδικα (codebase)](./codebase) και [παραμέτρους (config)](./config) όπως κάθε διεργασία που εκτελείται με βάση την ίδια έκδοση της εφαρμογής. Ο κώδικας διαχείρισης πρέπει να εξάγεται μαζί με τον κώδικα της εφαρμογής για να αποφευχθούν ζητήματα συγχρονισμού. + +Οι ίδιες τεχνικές [απομόνωσης εξαρτήσεων](./dependencies) θα πρέπει να χρησιμοποιούνται σε όλους τους τύπους διεργασιών. Για παράδειγμα, εάν η διεργασία ιστού της Ruby χρησιμοποιεί την εντολή `bundle exec thin start`, τότε μια αλλαγή της βάσης δεδομένων (database migration) θα πρέπει να χρησιμοποιήσει τη `bundle exec rake db:migrate`. Παρομοίως, ένα πρόγραμμα Python που χρησιμοποιεί το Virtualenv θα πρέπει να χρησιμοποιήσει το προμηθευμένο (vendored) `bin/python` για να τρέξει και τον εξυπηρετητή ιστού Tornado και οποιαδήποτε διεργασία διαχείρισης τύπου `manage.py`. + +ΟΙ δώδεκα παράγοντες έχουν ισχυρή προτίμηση στις γλώσσες προγραμματισμού που προσφέρουν ένα κέλυφος REPL έτοιμο για χρήση, και το οποίο καθιστά εύκολο να τρέξουν σενάρια εντολών μια και έξω. Σε μια τοπική ανάπτυξη (local deploy), οι προγραμματιστές καλούν τις διεργασίες διαχείρισης μια και έξω μέσω μιας εντολής απευθείας στο κέλυφος εντολών (shell) μέσα στο φάκελο του αποθετηρίου της εφαρμογής. Σε μια ανάπτυξη παραγωγής (production deploy), οι προγραμματιστές μπορούν να χρησιμοποιήσουν το ssh ή άλλο μηχανισμό απομακρυσμένης εκτέλεσης εντολών ο οποίος παρέχεται από το περιβάλλον εκτέλεσης για να τρέξουν μια τέτοια διεργασία. diff --git a/content/el/background.md b/content/el/background.md new file mode 100644 index 000000000..e690a2d4e --- /dev/null +++ b/content/el/background.md @@ -0,0 +1,9 @@ +Πλαίσιο +======= + +Οι συγγραφείς αυτού του κειμένου έχουν άμεσα εμπλακεί στην υλοποίηση και ανάπτυξη εκατοντάδων εφαρμογών, και έχουν έμμεσα γίνει μάρτυρες της υλοποίησης, λειτουργίας, και κλιμάκωσης εκατοντάδων χιλιάδων εφαρμογών μέσω της εργασίας τους στη πλατφόρμα Heroku. + +Αυτό το κείμενο συνθέτει όλη την εμπειρία μας και τις παρατηρήσεις μας σε μια ευρεία ποικιλία απο εφαρμογές λογισμικού-ως-υπηρεσίας εκεί έξω. Είναι μια τριγωνοποίηση σε ιδανικές πρακτικές για υλοποίηση εφαρμογών, δίνωντας ιδιαίτερη προσοχή στην δυναμική της οργανικής ανάπτυξης μιας εφαρμογής στο χρόνο, της δυναμικής της συνεργασίας μεταξύ προγραμματιστών που δουλέυουν πάνω στη βάση κώδικα της εφαρμογής, και της αποφυγής του κόστους διάβρωσης του λογισμικού. + +Το κίνητρό μας είναι να αυξήσουμε τη συνειδητότητα για μερικά συστημικά προβλήματα που έχουμε δει στην υλοποίηση μοντέρνων εφαρμογών, να παρέχουμε ένα κοινό λεξιλόγιο για να συζητήσουμε αυτά τα προβλήματα, και να προσφέρουμε ένα σύνολο από ευρείς εννοιολογικές λύσεις μαζί με την συνάδουσα ορολογία. Η μορφή είναι εμπνευσμένη απο τα βιβλία του Martin Fowler *Patterns of Enterprise Application Architecture* και *Refactoring*. + diff --git a/content/el/backing-services.md b/content/el/backing-services.md new file mode 100644 index 000000000..4761a1cdc --- /dev/null +++ b/content/el/backing-services.md @@ -0,0 +1,14 @@ +## IV. Υπηρεσίες υποστήριξης +### Υπηρεσίες υποστήριξης ως επισυναπτόμενοι πόροι + +Μία *υπηρεσία υποστήριξης* (*backing service*) είναι οποιαδήποτε υπηρεσία την οποία η εφαρμογή καταναλώνει μέσω του δικτύου ως μέρος της κανονικής λειτουργίας της. Παραδείγματα περιλαμβάνουν τις αποθήκες δεδομένων (datastores) (όπως η [MySQL](http://dev.mysql.com/) ή η [CouchDB](http://couchdb.apache.org/)), τα συστήματα μηνυμάτων/ουρών (messaging/queueing systems) (όπως το [RabbitMQ](http://www.rabbitmq.com/) ή το [Beanstalkd](https://beanstalkd.github.io)), τις υπηρεσίες SMTP για εξερχόμενη ηλεκτρονική αλληλογραφία (όπως το [Postfix](http://www.postfix.org/)), και συστήματα προσωρινής μνήμης (caching systems) (όπως το [Memcached](http://memcached.org/)). + +Υπηρεσίες υποστήριξης όπως η βάση δεδομένων παραδοσιακά διαχειρίζονται από τους ίδιους διαχειριστές συστημάτων που εγκαθιστούν την εφαρμογή. Πρόσθετα σε αυτές τις τοπικά διαχειριζόμενες υπηρεσίες, η εφαρμογή μπορεί επίσης να έχει και υπηρεσίες που προσφέρονται και διαχειρίζονται από τρίτους. Παραδείγματα περιλαμβάνουν υπηρεσίες SMTP (όπως το [Postmark](http://postmarkapp.com/)), υπηρεσίες στατιστικών εφαρμογής (όπως το [New Relic](http://newrelic.com/) ή το [Loggly](http://www.loggly.com/)), υπηρεσίες δυαδικών επισυναπτόμενων αρχείων (binary asset services) (όπως το [Amazon S3](http://aws.amazon.com/s3/)), και ακόμα καταναλωτικές υπηρεσίες προσβάσιμες μέσω API (όπως το [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), ή το [Last.fm](http://www.last.fm/api)). + +**Ο κώδικας μιας εφαρμογής δώδεκα παραγόντων δεν κάνει καμία διάκριση μεταξύ τοπικών υπηρεσιών και υπηρεσιών τρίτων.** Για την εφαρμογή, και οι δύο είναι επισυναπτόμενοι πόροι, προσβάσιμοι μέσω ενός URL ή μέσω άλλων εντοπιστών/διαπιστευτηρίων που αποθηκέυονται ως [παράμετροι (config)](./config). Μία [ανάπτυξη](./codebase) της εφαρμογής δώδεκα παραγόντων θα πρέπει να είναι ικανή να αντικαταστήσει μια τοπική βάση δεδομένων MySQL με μία άλλη διαχειριζόμενη από τρίτους (όπως η [Amazon RDS](http://aws.amazon.com/rds/)) χωρίς καμία αλλαγή στον κώδικα της εφαρμογής. Παρομοίως, ένας τοπικός εξυπηρετητής SMTP μπορεί να αντικατασταθεί από μία υπηρεσία SMTP από τρίτους (όπως το Postmark) χωρίς αλλαγές στον κώδικα. Και στις δύο περιπτώσεις, μόνο το αναγνωριστικό του πόρου (resource handle) στις παραμέτρους πρέπει να αλλάξει. + +Κάθε διακριτή υπηρεσία υποστήριξης είναι ένας *πόρος* (*resource*). Για παράδειγμα, μία βάση δεδομένων MySQL είναι ένας πόρος, δύο βάσεις δεδομένων MySQL (που χρησιμοποιούνται για κομμάτιασμα στο επίπεδο εφαρμογής) είναι δύο διακριτοί πόροι. Η εφαρμογή δώδεκα παραγόντων φέρεται σε αυτές τις βάσεις δεδομένων σαν να είναι *επισυναπτόμενοι πόροι* (*attached resources*), το οποίο σηματοδοτεί την χαλαρή σύνδεση (loose coupling) με την ανάπτυξη της εφαρμογής (deploy) στην οποία επισυνάπτονται. + +Μια ανάπτυξη παραγωγής στην οποία επισυνάπτονται τέσσερις υπηρεσίες υποστήριξης. + +Οι πόροι μπορεί να προστεθούν και να καταργηθούν από μία ανάπτυξη της εφαρμογής κατά βούληση. Για παράδειγμα, εάν η βάση δεδομένων της εφαρμογής λανθάνει λόγω αστοχίας του υλικού (hardware issue), ο διαχειριστής της εφαρμογής μπορεί να σηκώσει ένα νέο εξυπηρετητή βάσης δεδομένων από ένα πρόσφατο αντίγραφο ασφαλείας. Η τρέχουσα βάση δεδομένων της παραγωγής μπορεί να καταργηθεί, και η νέα βάση δεδομένων να προστεθεί -- όλα χωρίς καμία αλλαγή στον κώδικα. diff --git a/content/el/build-release-run.md b/content/el/build-release-run.md new file mode 100644 index 000000000..b9ab494e5 --- /dev/null +++ b/content/el/build-release-run.md @@ -0,0 +1,19 @@ +## V. Κατασκευή, έκδοση, εκτέλεση +### Αυστηρός διαχωρισμός μεταξύ των σταδίων μεταγλώττισης/κατασκευής και εκτέλεσης + +Μια [βάση κώδικα](./codebase) μετασχηματίζεται σε μια ανάπτυξη εφαρμογής (deploy) (όχι για υλοποίηση) μέσω τριών σταδίων: + +* Το *στάδιο κατασκευής* (*build stage*) είναι ένας μετασχηματισμός που μετατρέπει ένα αποθετήριο κώδικα σε μία εκτελέσιμη δέσμη γνωστή ως *κατασκευή* (*build*). Χρησιμοποιώντας μια έκδοση του κώδικα σε κάποιο σημείο δοσμένο απο τη διεργασία ανάπτυξης, το στάδιο κατασκευής μαζέυει τις όποιες [εξαρτήσεις](./dependencies) που πρέπει να προμηθευθούν στην εφαρμογή και μεταγλωττίζει και συνενώνει τα δυαδικά αρχεια και άλλα πρόσθετα. +* Το *στάδιο έκδοσης* (*release stage*) παίρνει το αποτέλεσμα του σταδίου κατασκευής και το συνδυάζει με τις τρέχουσες [παραμέτρους](./config) της ανάπτυξης της εφαρμογής. Η τελική *έκδοση* (*release*) περιέχει την κατασκευή και τις παραμέτρους και είναι έτοιμη για άμεση εκτέλεση στο περιβάλλον εκτέλεσης. +* Το *στάδιο εκτέλεσης* (*run stage*) (επίσης γνωστό ως "εκτελέσιμο", "runtime") τρέχει την εφαρμογή στο περιβάλλον εκτέλεσης, ξεκινώντας ένα σύνολο απο τις [διεργασίες](./processes) της εφαρμογής με βάση μια επιλεγμένη έκδοση της εφαρμογής. + +![Ο κώδικας γίνεται κατασκευή, η οποία συνδυάζεται με παραμέτρους για να δημιουργήσει μια έκδοση της εφαρμογής.](/images/release.png) + +**Η εφαρμογή δώδεκα παραγόντων διαχωρίζει αυστηρά τα στάδια κατασκευής, έκδοσης και εκτέλεσης.** Για παράδειγμα, είναι αδύνατο να πραγματοποιηθούν αλλαγές στον κώδικα κατά την εκτέλεση, καθώς δεν υπάρχει τρόπος να περάσουν αυτές οι αλλαγές πίσω στο στάδιο κατασκευής. + +Τα εργαλεία ανάπτυξης εφαρμογών (deployment tools) τυπικά προσφέρουν εργαλεία διαχείρισης εκδόσεων (release management tools), κυρίως την ικανότητα να γυρίσουν πίσω σε μία προηγούμενη έκδοση της εφαρμογής. Για παράδειγμα, το εργαλείο [Capistrano](https://github.com/capistrano/capistrano/wiki) αποθηκέυει τις εκδόσεις σε ένα υποφάκελο με όνομα `releases`, όπου η τρέχουσα έκδοση είναι ένας συμβολικός σύνδεσμος στο φάκελο της τρέχουσας έκδοσης. Με την εντολή του `rollback` έυκολα και γρήγορα γυρίζει πίσω σε μία προηγούμενη έκδοση της εφαρμογής. + +Κάθε έκδοση της εφαρμογής θα πρέπει πάντα να φέρει ένα μοναδικό αναγνωριστικό έκδοσης (release ID), όπως μια χρονοσφραγίδα της έκδοσης (όπως το `2011-04-06-20:32:17`) ή έναν άυξοντα αριθμό (όπως το `v100`). Οι εκδόσεις της εφαρμογής είναι σαν ένα λογιστικό βιβλίο όπου μόνο προσθέσεις μπορούν να γίνουν και μία έκδοση δεν μπορεί να μεταβληθεί αφού έχει δημιουργηθεί. Κάθε μεταβολή πρέπει να δημιουργήσει μια νέα έκδοση της εφαρμογής. + +Οι κατασκευές (builds) ξεκινούν απο τους προγραμματιστές της εφαρμογής όποια στιγμή καινούργιος κώδικας αναπτύσσεται (deployed). Η εκτέλεση, αντιθέτως, μπορεί να συμβεί αυτόματα σε περιπτώσεις όπως επανεκκίνηση εξυπηρετητή (server restart), ή όταν μια διεργασία που έχει καταρρέυσει επανεκκινείται από τον διαχειριστή διεργασιών (process manager). Επομένως, το στάδιο εκτέλεσης θα πρέπει να έχει όσο πιο λίγα κινούμενα μέρη γίνεται, καθώς προβλήματα που μπορεί να εμποδίσουν μία εφαρμογή απο το να τρέξει μπορεί να την κάνουν να καταρρέυσει εν τω μέσω της νυκτός όπου δεν θα υπάρχει κανένας προγραμματιστής διαθέσιμος. Το στάδιο κατασκευής μπορεί να είναι πιο περίπλοκο, καθώς τα σφάλματα είναι πάντα στο προσκήνιο για ένα προγραμματιστή που καθοδηγεί την ανάπτυξη της εφαρμογής (deploy). + diff --git a/content/el/codebase.md b/content/el/codebase.md new file mode 100644 index 000000000..714c3ae85 --- /dev/null +++ b/content/el/codebase.md @@ -0,0 +1,18 @@ +## I. Βάση Κώδικα +### Μία βάση κώδικα με έλεγχο εκδόσεων, πολλές αναπτύξεις + +Μια εφαρμογή δώδεκα παραγόντων είναι πάντα διαχειριζόμενη από ένα σύστημα ελέγχου εκδόσεων κώδικα (version control system), όπως το [Git](http://git-scm.com/), το [Mercurial](https://www.mercurial-scm.org/), ή το [Subversion](http://subversion.apache.org/). Ένα αντίγραφο της βάσης αλλαγών του συστήματος είναι γνωστό ως *αποθετήριο κώδικα* (*code repository*), συχνά συντομευμένο σε *αποθετήριο* (*code repo* ή *repo*). + +Μια *βάση κώδικα* (*codebase*) είναι είτε ένα οποιοδήποτε αποθετήριο (σε ένα κεντρικά διαχειριζόμενο σύστημα όπως το Subversion), είτε ένα οποιοδήποτε σύνολο από αποθετήρια τα οποία μοιράζονται μία κοινή ρίζα εισαγωγής κώδικα (σε ένα αποκεντρωμένο σύστημα διαχείρισης όπως το Git). + +![Μία βάση κώδικα αναλογεί σε πολλές αναπτύξεις της εφαρμογής](/images/codebase-deploys.png) + +Υπάρχει πάντα μια σχέση ένα-προς-ένα μεταξύ της βάσης κώδικα και της εφαρμογής: + +* Αν υπάρχουν πολλαπλές βάσεις κώδικα, δεν είναι εφαρμογή -- είναι ενα κατανεμημένο σύστημα. Κάθε μέρος του κατανεμημένου συστήματος είναι εφαρμογή, και το καθένα ξεχωριστά μπορεί να συνάδει με τους δώδεκα παράγοντες. +* Πολλαπλές εφαρμογές οι οποίες μοιράζονται τον ίδιο κώδικα συνιστά παράβαση των δώδεκα παραγόντων. Η λύση εδώ είναι να παραγοντοποιηθεί ο κοινός κώδικας σε βιβλιοθήκες οι οποίες μπορούν να εισαχθούν μέσω του [διαχειριστή εξαρτήσεων](./dependencies). + +Υπάρχει μόνο μία βάση κώδικα ανά εφαρμογή, αλλά θα υπάρξουν πολλές αναπτύξεις της εφαρμογής. Μια *ανάπτυξη* (*deploy*) της εφαρμογής, είναι μία εκτελούμενη ενσάρκωση της εφαρμογής. Αυτό τυπικά είναι μία τοποθεσία παραγωγής (production site), και μία ή περισσότερες τοποθεσίες ελέγχου (staging sites). Επιπλέον, κάθε προγραμματιστής έχει ένα αντίγραφο της εφαρμογής εκτελούμενο τοπικά στο περιβάλλον του, το οποίο επίσης συνιστά μια ανάπτυξη. + +Η βάση κώδικα είναι η ίδια για όλες τις αναπτύξεις, παρόλαυτά διαφορετικές εκδόσεις κώδικα μπορεί να είναι ενεργές ανά ανάπτυξη. Για παράδειγμα, ο προγραμματιστής έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην τοποθεσία ελέγχου, η τοποθεσία ελέγχου έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην παραγωγή. Αλλά όλα μοιράζονται την ίδια βάση κώδικα, έτσι μπορούν να ταυτοποιηθούν ως διαφορετικές αναπτύξεις της ίδιας εφαρμογήε. + diff --git a/content/el/concurrency.md b/content/el/concurrency.md new file mode 100644 index 000000000..372ed8a2f --- /dev/null +++ b/content/el/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Παραλληλία +### Κλιμάκωση προς τα έξω μέσω του μοντέλου διεργασιών + +Κάθε πρόγραμμα υπολογιστή, όταν εκτελείται, αντιπροσωπεύεται από μία ή περισσότερες διεργασίες. Οι εφαρμογές ιστου (web apps) έχουν λάβει μία ποικιλία μορφών εκτέλεσης διεργασιών. Για παράδειγμα, οι διεργασίες PHP τρέχουν ως διεργασίες απόγονοι (child processes) του Apache, που εκκινούνται κατά ανάγκη του όγκου αιτημάτων. Οι διεργασίες Java χρησιμοποιούν την αντίθετη προσέγγιση, με τη JVM να παρέχει μια μαζική υπερδιεργασία που δεσμέυει ένα μεγάλο κομμάτι των πόρων συστήματος (CPU και μνήμη) κατά την εκκίνηση, με την παραλληλία να διαχειρίζεται εσωτερικά μέσω ινών εκτέλεσης (threads). Και στις δυο περιπτώσεις, οι εκτελούμενες διεργασίες είναι μόνο ελάχιστα ορατές στους προγραμματιστές της εφαρμογής. + +![Η κλιμάκωση εκφράζεται από εκτελούμενες διεργασίες, η διαφοροποίηση του φόρτου εργασίας εκφράζεται από τύπους διεργασιών.](/images/process-types.png) + +**Στην εφαρμογή δώδεκα παραγόντων, οι διεργασίες είναι πολίτες πρώτης τάξης.** Οι διεργασίες στην εφαρμογή δώδεκα παραγόντων προσιδιάζουν σε αρκετά στοιχεία το [μοντέλο διεργασιών του unix (unix process model) για την εκτέλεση δαιμόνων διαχείρισης (service daemons)](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Χρησιμοποιώντας αυτό το μοντέλο, ο προγραμματιστής μπορεί να δομήσει την εφαρμογή έτσι ώστε να διαχειριστεί μια ποικιλία φόρτου εργασίας με το να αναθέτει κάθε τύπο εργασίας σε ένα *τύπο διεργασίας* (*process type*). Για παράδειγμα, τις αιτήσεις HTTP μπορεί να τις χειριστεί μια διεργασία ιστού (web process), και τις μακρά εκτελούμενες εργασίες παρασκηνίου μπορεί να τις χειριστεί μια διεργασία εργάτη (worker process). + +Αυτό δεν αποκλείει μεμονωμένες διεργασίες από το να διαχειριστούν την δική τους εσωτερική πολυπλεξία, μέσω ινών εκτέλεσης (threads) μέσα στην εκτελούμενη VM, είτε μέσω του μοντέλου async/evented όπως βρίσκεται σε εργαλεία όπως το [EventMachine](https://github.com/eventmachine/eventmachine), το [Twisted](http://twistedmatrix.com/trac/), ή το [Node.js](http://nodejs.org/). Αλλά μια μεμονωμένη VM μπορεί να κλιμακωθεί μόνο τόσο (κάθετη κλιμάκωση, vertical scale), οπότε η εφαρμογή πρέπει επίσης να μπορεί να εξαπλωθεί σε περισσότερες διεργασίες εκτελούμενες σε πολλαπλά φυσικά μηχανήματα. + +Το μοντέλο διεργασιών (process model) πραγματικά λάμπει όταν είναι η ώρα για κλιμάκωση προς τα έξω (scale out). Η [φύση των διεργασιών δώδεκα παραγόντων όπου είναι οριζόντια διαχωρίσιμες και δεν μοιράζονται τίποτα](./processes) σημαίνει ότι η αύξηση παραλληλίας είναι μια απλή και αξιόπιστη διαδικασία. Η συστοιχία των τύπων διεργασιών και του αριθμού διεργασιών κάθε τύπου είναι γνωστή ως *σχηματισμός διεργασιών* (*process formation*). + +Οι διεργασίες της εφαρμογής δώδεκα παραγόντων [δεν πρέπει ποτέ να συμπεριφέρονται σαν δαίμονες (daemonize)](http://dustin.github.com/2010/02/28/running-processes.html) ή να γράφουν αρχεία PID (PID files). Αντίθετα, βασίζονται στον διαχειριστή διεργασιών του λειτουργικού συστήματος (operating system's process manager) (όπως το [systemd](https://www.freedesktop.org/wiki/Software/systemd/), σε ένα κατανεμημένο διαχειριστή διεργασιών σε μια πλατφόρμα υπολογιστικού νέφους, ή σε ένα εργαλείο όπως το [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) κατά την υλοποίηση) για να διαχειριστούν [ροές εξόδου (output streams)](./logs), να διαχειριστούν διεργασίες που κατέρρευσαν, και να διαχειριστούν επανεκκινήσεις και τερματισμούς από το χρήστη. diff --git a/content/el/config.md b/content/el/config.md new file mode 100644 index 000000000..fbcbdf769 --- /dev/null +++ b/content/el/config.md @@ -0,0 +1,22 @@ +## III. Παραμετροποίηση +### Αποθήκευση παραμέτρων στο περιβάλλον + +Οι *παράμετροι* (*config*) μιας εφαρμογής είναι όλα εκείνα που είναι πιθανό να αλλάζουν ανά [ανάπτυξη της εφαρμογής](./codebase) (έλεγχος, παραγωγή, περιβάλλον προγραμματιστή, κλπ). Αυτό περιλαμβάνει: + +* Αναγνωριστικά πόρων (resource handles) στη βάση δεδομένων, στο Memcached, και άλλες [υπηρεσίες υποστήριξης](./backing-services) +* Διαπιστευτήρια (credentials) για εξωτερικές υπηρεσίες όπως το Amazon S3 ή το Twitter +* Τιμές σχετικές με μια συγκεκριμένη ανάπτυξη όπως το κανονικό όνομα φιλοξενητή (canonical hostname) της ανάπτυξης + +Οι εφαρμογές μερικές φορές αποθηκέυουν τις παραμέτρους ως σταθερές στον κώδικα. Αυτό αποτελεί παραβίαση των δώδεκα παραγόντων, το οποίο απαιτεί **αυστηρό διαχωρισμό παραμέτρων από τον κώδικα**. Οι παράμετροι διαφοροποιούνται σημαντικά μεταξύ αναπτύξεων, ο κώδικας όχι. + +Ένα τέστ litmus για το αν μία εφαρμογή έχει αφήσει έξω την παραμετροποίηση με σωστό τρόπο είναι εάν η βάση κώδικα μπορει να γίνει ανοιχτού κώδικα ανά πάσα στιγμή, χωρίς να γίνει γνωστό κανένα διαπιστευτήριο. + +Σημειώστε ότι αυτός ο ορισμός της παραμετροποίησης **δεν** συμπεριλαμβάνει την εσωτερική παραμετροποίηση της εφαρμογής, όπως το `config/routes.rb` στο Rails, ή πως [συνδέονται τα μέρη του κώδικα](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) στο [Spring](http://spring.io/). Αυτός ο τύπος παραμετροποίησης δεν μεταβάλλεται μεταξύ αναπτύξεων, οπότε είναι καλύτερα να γίνεται στον κώδικα. + +Μια άλλη προσέγγιση στην παραμετροποίηση είναι η χρήση αρχείων παραμέτρων (config files) τα οποία δεν περιλαμβάνονται στο αποθετήριο της εφαρμογής, όπως το `config/database.yml` στο Rails. Αυτό αποτελεί μια μεγάλη βελτίωση από το να χρησιμοποιούνται σταθερές στον κώδικα, αλλά ακόμα έχει αδυναμίες: είναι έυκολο κατά λάθος να συμπεριληφθεί το αρχείο στο αποθετήριο, υπάρχει μία τάση τα αρχεία παραμέτρων να είναι διασκορπισμένα σε διάφορα μέρη και σε διαφορετικές μορφές, καθιστώντας έτσι δύσκολο να δει και να διαχειριστεί κάποιος όλες τις παραμέτρους σε ένα μέρος. Επιπλέον, αυτές οι μορφές τείνουν να είναι συγκεκριμένες ως προς τη γλώσσα προγραμματισμού ή το πλάισιο ανάπτυξης της εφαρμογής. + +**Η εφαρμογή δώδεκα παραγόντων αποθηκέυει την παραμετροποίηση σε *μεταβλητές περιβάλλοντος* (*environment variables*, *env vars*, *env*)**. Οι μεταβλητές περιβάλλοντος αλλάζουν έυκολα μεταξύ αναπτύξεων της εφαρμογής χωρίς να αλλάξει ο κώδικας, σε σχέση με τα αρχεία παραμέτρων, υπάρχει μικρή πιθανότητα κατά λάθος να εισαχθούν στο αποθετήριο του κώδικα, και επίσης πάλι σε σχέση με τα αρχεία παραμέτρων, ή άλλους μηχανισμούς παραμετροποίησης όπως τα Java System Properties, αποτελούν ένα πρότυπο ανεξάρτητο από τη γλώσσα προγραμματισμού και το λειτουργικό σύτημα. + +Μια άλλη πλευρά της διαχείρισης παραμέτρων είναι η ομαδοποίηση. Μερικές φορές οι εφαρμογές στοιβάζουν παραμέτρους σε ονομαστικές ομάδες (συχνά καλούνται "περιβάλλοντα") που παίρνουν το όνομά τους απο συγκεκριμένες αναπτύξεις, όπως τα περιβάλλοντα `development` (`υλοποίηση`), `test` (`τέστ`), και `production` (`παραγωγή`) στο Rails. Αυτή η μέθοδος δεν κλιμακώνεται καθαρά: καθώς περισσότερες αναπτύξεις της εφαρμογής δημιουργούνται, νέα ονόματα περιβαλλόντων γίνονται απαραίτητα, όπως `staging` (`έλεγχος`) ή `qa`. Καθώς το έργο επεκτείνεται περαιτέρω, οι προγραμματιστές μπορει να προσθέσουν τα δικά τους ειδικά περιβάλλοντα όπως `joes-staging`, συνεπαγόμενα μια συνδυαστική έκρηξη από παραμετροποιήσεις που κάνουν την διαχείριση αναπτύξεων της εφαρμογής πολύ εύθραυστη. + +Σε μια εφαρμογή δώδεκα παραγόντων, οι μεταβλητές περιβάλλοντος αποτελούν στοιχεία λεπτοφυούς ελέγχου, το καθένα πλήρως ορθογώνιο σε άλλες μεταβλητές περιβάλλοντος. Ποτέ δεν ομαδοποιούνται μαζί ως "περιβάλλοντα", αντιθέτως διαχειρίζονται ανεξάρτητα για κάθε ανάπτυξη της εφαρμογής. Αυτό είναι ένα μοντέλο που κλιμακώνεται ομαλά προς τα πάνω καθώς η εφαρμογή φυσικά διευρύνεται σε περισσότερες αναπτύξεις κατά της διάρκεια της ζωής της. diff --git a/content/el/dependencies.md b/content/el/dependencies.md new file mode 100644 index 000000000..0a922190e --- /dev/null +++ b/content/el/dependencies.md @@ -0,0 +1,12 @@ +## II. Εξαρτήσεις +### Εξαρτήσεις εκπεφρασμένα δηλωμένες και απομονωμένες + +Οι περισσότερες γλώσσες προγραμματισμού προσφέρουν ένα σύστημα πακεταρίσματος για διανομή των βιβλιοθηκών υποστήριξης, όπως το [CPAN](http://www.cpan.org/) για την Perl ή το [Rubygems](http://rubygems.org/) για τη Ruby. Οι βιβλιοθήκες που εγκαθιστούνται μέσω του συστήματος πακεταρίσματος μπορουν να εγκατασταθούν είτε για όλο το σύστημα (γνωστές ως "καθολικά πακέτα", "site packages") είτε τοπικά μέσα στο φάκελο που περιέχει την εφαρμογή (γνωστές ως "προμηθευμένες", "vendoring" ή ως "δέσμες", "bundling"). + +**Μία εφαρμογή δώδεκα παραγόντων ποτέ δεν εξαρτάται απο την υπόρρητη ύπαρξη καθολικών πακέτων.** Δηλώνει όλες τις εξαρτήσεις, ολοκληρωτικά και ακριβώς, μέσω ενός δηλωτικού αρχείου *δήλωσης εξαρτήσεων* (*dependency declaration* manifest). Επιπλέον, χρησιμοποιεί ένα εργαλείο *απομόνωσης εξαρτήσεων* (*dependency isolation*) κατά την διάρκεια της εκτέλεσης ώστε να εξασφαλίσει ότι καμία υπόρρητη εξάρτηση δεν θα "διαρρέυσει" απο το περιβάλλον σύστημα. Η πλήρης και εκπεφρασμένη δήλωση εξαρτήσεων εφαρμόζεται το ίδιο και στο περιβάλλον παραγωγής και στο περιβάλλον υλοποίησης (του προγραμματιστή). + +Για παράδειγμα, το [Bundler](https://bundler.io/) για τη Ruby προσφέρει τη δομή δηλωτικού `Gemfile` για δήλωση εξαρτήσεων και το `bundle exec` για απομόνωση εξαρτήσεων. Στην Python υπάρχουν δύο διαφορετικά εργαλεία για αυτά τα βήματα -- το [Pip](http://www.pip-installer.org/en/latest/) χρησιμοποιείται για δήλωση και το [Virtualenv](http://www.virtualenv.org/en/latest/) για απομόνωση. Ακόμα και η C έχει το [Autoconf](http://www.gnu.org/s/autoconf/) για δήλωση εξαρτήσεων, και η στατική διασύνδεση μπορεί να προσφέρει απομόνωση εξαρτήσεων. Όποια και αν είναι η αλυσίδα εργαλείων, η δήλωση εξαρτήσεων και η απομόνωση πρέπει πάντα να χρησιμοποιούνται μαζί -- μόνο η μία ή η άλλη δεν είναι ικανό για τους δώδεκα παράγοντες. + +Ένα πλεονέκτημα της εκπεφρασμένης δήλωσης εξαρτήσεων είναι ότι απλοποιεί το στήσιμο της εφαρμογής για προγραμματιστές οι οποίοι είναι καινούργιοι στην εφαρμογή. Ο νέος προγραμματιστής μπορεί να κατεβάσει τη βάση κώδικα της εφαρμογής στο δικό του υπολογιστή, απαιτώντας να εγκατασταθούν μόνο το εκτελέσιμο της γλώσσας προγραμματισμού (language runtime) και ο διαχειριστής εξαρτήσεων (dependency manager) ως προαπαιτούμενα. Αυτά θα είναι ικανά να στήσουν οτιδήποτε χρειάζεται ώστε να τρέξει η εφαρμογή μέσω μιάς ντετερμινιστικής *εντολής κατασκευής* (*build command*). Για παράδειγμα, η εντολή κατασκευής για το Ruby/Bundler είναι `bundle install`, ενώ για την Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) είναι `lein deps`. + +Οι εφαρμογές δώδεκα παραγόντων επίσης δεν εξαρτώνται από την υπόρρητη ύπαρξη οποιουδήποτε εργαλείου συστήματος. Μερικά παραδείγματα είναι το ImageMagick ή το `curl`. Μπορεί αυτά τα εργαλεία να υπάρχουν σε πολλά ή στα περισσότερα συστήματα, αλλά κανείς δεν εγγυάται ότι θα υπάρχουν σε όλα τα συστήματα που θα τρέξουν την εφαρμογή στο μέλλον, ή ότι η έκδοση που θα υπάρχει θα είναι συμβατή με την εφαρμογή. Εάν η εφαρμογή χρειάζεται κάποιο τέτοιο εργαλείο συστήματος, αυτό το εργαλείο πρέπει να γίνει προμηθέυσιμο (vendored) μέσα στην εφαρμογή. diff --git a/content/el/dev-prod-parity.md b/content/el/dev-prod-parity.md new file mode 100644 index 000000000..338303b01 --- /dev/null +++ b/content/el/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Ισοτιμία dev/prod +### Κράτησε τα περιβάλλοντα υλοποίησης, ελέγχου και παραγωγής όσο πιο όμοια γίνεται + +Ιστορικά, έχουν υπάρξει μεγάλα χάσματα μεταξύ υλοποίησης (development) (ο προγραμματιστής να κάνει αλλαγές σε πραγματικό χρόνο σε μία τοπική [ανάπτυξη](./codebase) της εφαρμογής) και της παραγωγής (production) (μία εκτελούμενη ανάπτυξη της εφαρμογής προσβάσιμη μόνο από τελικούς χρήστες). Αυτά τα χάσματα εκδηλώνονται σε τρία σημεία: + +* **Το χρονικό χάσμα**: Ένας προγραμματιστής μπορεί να δουλέυει σε ένα κώδικα που παίρνει μέρες, εβδομάδες, ή ακόμα και μήνες να φτάσει στην παραγωγή. +* **Το χάσμα προσωπικού**: Οι προγραμματιστές (developers) γράφουν κώδικα, οι επιχειρησιακοί μηχανικοί (ops engineers) τον αναπτύσσουν. +* **Το εργαλειακό χάσμα**: Οι προγραμματιστές μπορεί να χρησιμοποιούν εργαλεία όπως το Nginx, την SQLite, και το OS X, αλλά η αναπτύξη της παραγωγής χρησιμοποιεί το Apache, τη MySQL, και το Linux. + +**Η εφαρμογή δώδεκα παραγόντων είναι σχεδιασμένη για [συνεχή αναπτύξη (continuous deployment)](http://avc.com/2011/02/continuous-deployment/) με το να κρατάει το χάσμα μεταξύ υλοποίησης (development) και παραγωγής (production) μικρό.** Κοιτώντας τα τρία χάσματα που περιγράψαμε παραπάνω: + +* Μείωσε το χρονικό χάσμα: ένας προγραμματιστής μπορεί να γράψει κώδικα και να τον αναπτύξει μερικές ώρες ή ακόμα και μερικά λεπτά αργότερα. +* Μείωσε το χάσμα προσωπικού: οι προγραμματιστές που έγραψαν τον κώδικα ασχολούνται στενά με την ανάπτυξή του και παρακολουθούν την συμπεριφορά του στην παραγωγή. +* Μείωσε το εργαλειακό χάσμα: κράτησε τα περιβάλλοντα υλοποίησης (development) και παραγωγής (production) όσο πιο όμοια γίνεται. + +Συνοψίζοντας τα παραπάνω σε ένα πίνακα: + + + + + + + + + + + + + + + + + + + + + + +
Παραδοσιακή εφαρμογήΕφαρμογή δώδεκα παραγόντων
Χρόνος μεταξύ αναπτύξεωνΕβδομάδεςΏρες
Συγγραφείς κώδικα ή αναπτυκτές του κώδικαΔιαφορετικοί άνθρωποιΊδιοι άνθρωποι
Περιβάλλοντα υλοποίησης (dev) ή παραγωγής (production)ΑποκλίνονταΌσο πιο όμοια γίνεται
+ +Οι [υπηρεσίες υποστήριξης](./backing-services), όπως η βάση δεδομένων (database) της εφαρμογής, το σύστημα ουρών (queueing system), ή η προσωρινή μνήμη (cache), είναι ένας τόπος όπου η ισοτιμία dev/prod είναι σημαντική. Πολλές γλώσσες προγραμματισμού προσφέρουν βιβλιοθήκες οι οποίες απλοποιούν την πρόσβαση στην υπηρεσία υποστήριξης, συμπεριλαμβανομένων *προσαρμογέων* (*adapters*) για διάφορους τύπους υπηρεσιών. Μερικά παραδείγματα περιέχονται στον παρακάτω πίνακα. + + + + + + + + + + + + + + + + + + + + + + + + + + +
ΤύποςΓλώσσα ΠρογραμματισμούΒιβλιοθήκηΠροσαρμογείς
Βάση δεδομένωνRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
Ουρά εργασιώνPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
Προσωρινή μνήμηRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Οι προγραμματιστές μερικές φορές βρίσκουν πολύ ελκυστικό να χρησιμοποιήσουν μια ελαφρά υπηρεσία υποστήριξης στο τοπικό περιβάλλον ανάπτυξής τους, ενώ μια πιο στιβαρή και εύρωστη υπηρεσία υποστήριξης θα χρησιμοποιηθεί στην παραγωγή. Για παράδειγμα, χρησιμοποιώντας την SQLite τοπικά και την PostgreSQL στην παραγωγή, ή την τοπική μνήμη διεργασίας για προσωρινή μνήμη κατά την υλοποίηση και το Memcached στην παραγωγή. + +**Ο προγραμματιστής δώδεκα παραγόντων αντιστέκεται στην ορμή να χρησιμοποιήσει διαφορετικές υπηρεσίες υποστήριξης μεταξύ υλοποίησης και παραγωγής**, ακόμα και όταν οι προσαρμογείς θεωρητικά μπορούν να αφαιρέσουν τις επιμέρους διαφορές στις υπηρεσίες υποστήριξης. Οι διαφορές μεταξύ υπηρεσιών υποστήριξης σημαίνουν ότι μικρές ασυμβατότητες ανακύπτουν, που προκαλούν τον κώδικα που λειτουργούσε και πέρναγε τα τεστ στην υλοποίηση ή στον έλεγχο να αποτυγχάνει στην παραγωγή. Αυτού του είδους τα σφάλματα δημιουργούν τριβή η οποία είναι αντικίνητρο στην συνεχή ανάπτυξη (continuous deployment). Το κόστος αυτής της τριβής και της επακόλουθης μείωσης της συνεχούς ανάπτυξης είναι εξαιρετικά υψηλό όταν ληφθεί υπόψη η συσσώρευσή του κατά την διάρκεια του χρόνου ζωής της εφαρμογής. + +Οι ελαφρές τοπικές υπηρεσίες είναι λιγότερο ελκυστικές από ότι ήταν κάποτε. Οι μοντέρνες υπηρεσίες υποστήριξης όπως το Memcached, η PostgreSQL, και το RabbitMQ δεν είναι δύσκολο να εγκατασταθούν και να τρέξουν χάριν στα μοντέρνα συστήματα πακεταρίσματος (modern packaging systems), όπως το [Homebrew](http://mxcl.github.com/homebrew/) και το [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Εναλλακτικά, τα εργαλεία δηλωμένων παροχών (declarative provisioning tools) όπως το [Chef](http://www.opscode.com/chef/) και το [Puppet](http://docs.puppetlabs.com/) συνδυασμένα με ελαφρά εικονικά περιβάλλοντα (light-weight virtual environments) όπως το [Docker](https://www.docker.com/) και το [Vagrant](http://vagrantup.com/) επιτρέπουν στους προγραμματιστές να τρέξουν τοπικά περιβάλλοντα τα οποία προσομοιάζουν κατά πολύ τα περιβάλλοντα παραγωγής. Το κόστος εγκατάστασης και χρήσης αυτών των συστημάτων είναι χαμηλό συγκρινόμενο με το πλεονέκτημα της ισοτιμίας dev/prod και της συνεχούς αναπτύξεως. + +Οι προσαρμογείς στις διαφορετικές υπηρεσίες υποστήριξης είναι ακόμα χρήσιμοι, επειδή η μετάβαση σε νέες υπηρεσίες υποστήριξης γίνεται σχετικά αβασάνιστα. Αλλά όλες οι αναπτύξεις (deploys) της εφαρμογής (περιβάλλοντα υλοποίησης, ελέγχου, παραγωγής) θα πρέπει να χρησιμοποιούν τον ίδιο τύπο και έκδοση για κάθε μια από τις υπηρεσίες υποστήριξης. diff --git a/content/el/disposability.md b/content/el/disposability.md new file mode 100644 index 000000000..efa75e25c --- /dev/null +++ b/content/el/disposability.md @@ -0,0 +1,14 @@ +## IX. Απορριψιμότητα +### Μεγιστοποίηση ευρωστίας της εφαρμογής μέσω γρήγορης εκκίνησης και κομψού τερματισμού + +**Οι [διεργασίες](./processes) της εφαρμογής δώδεκα παραγόντων είναι *απορρίψιμες* (*disposable*), δηλαδή μπορούν να εκκινηθούν και να τερματιστούν μέσα σε μια στιγμή.** Αυτο διευκολύνει τη γρήγορη ελαστική κλιμάκωση, τη γοργή ανάπτυξη του [κώδικα της εφαρμογής](./codebase) ή τις αλλαγές στις [παραμέτρους](./config), και την ευρωστία των αναπτύξεων της εφαρμογής στην παραγωγή. + +Οι διεργασίες θα πρέπει να προσπαθούν να **ελαχιστοποιούν τον χρόνο εκκίνησης**. Ιδανικά, μια διεργασία παίρνει μερικά δευτερόλεπτα απο τη στιγμή της εντολής εκκίνησης μέχρι τη στιγμή που είναι σηκωμένη και έτοιμη να λάβει αιτήσεις ή εργασίες. Ο σύντομος χρόνος εκκίνησης παρέχει περισσότερη ευκινησία στην διαδικασία [έκδοσης](./build-release-run) και κλιμάκωσης προς τα πάνω, και βοηθά την ευρωστία, επειδή ο διαχειριστής διεργασιών μπορεί πιο εύκολα να μετακινήσει διεργασίες σε νέα φυσικά μηχανήματα όταν χρειαστεί. + +Οι διεργασίες **τερματίζουν κομψά όταν λάβουν το σήμα [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** από τον διαχειριστή διεργασιών. Για μια διεργασία ιστού (web process), ο κομψός τερματισμός επιτυγχάνεται με το να πάυει να ακούει τη θύρα εξυπηρέτησης (αρνούμενη έτσι νέες αιτήσεις), επιτρέποντας σε τρέχουσες αιτήσεις να ολοκληρωθούν, και έπειτα να κάνει έξοδο. Σε αυτό το μοντέλο εννοείται πως οι αιτήσεις HTTP είναι σύντομες (όχι παραπάνω από μερικά δευτερόλεπτα), ή στην περίπτωση μακράς δειγματοληψίας (long polling), ο πελάτης (client) θα πρέπει να προσπαθήσει απρόσκοπτα να επανασυνδεθεί όταν η σύνδεση χαθεί. + +Για μια διεργασία εργάτη (worker process), ο κομψός τερματισμός επιτυγχάνεται με το να επιστρέφει την τρέχουσα εργασία πίσω στην ουρά εργασιών. Για παράδειγμα, στο [RabbitMQ](http://www.rabbitmq.com/) ο εργάτης μπορεί να στείλει ένα [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack), στο [Beanstalkd](https://beanstalkd.github.io), η εργασία επιστρέφεται στην ουρά αυτόματα όποτε ένας εργάτης αποσυνδέεται. Συστήματα βασισμένα σε κλείδωμα (lock-based systems) όπως το [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) πρέπει να σιγουρευτούν ότι απελευθέρωσαν το κλείδωμα από την εγγραφή της εργασίας. Σε αυτό το μοντέλο εννοείται πως όλες οι εργασίες είναι [επανεισδόχιμες (reentrant)](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), το οποίο τυπικά επιτυγχάνεται με το να περιέχονται τα αποτελέσματα της εργασίας σε μια συναλλαγή (transaction), ή να είναι η λειτουργία [ταυτοδύναμη (idempotent)](http://en.wikipedia.org/wiki/Idempotence). + +Οι διεργασίες θα πρέπει επίσης να είναι **εύρωστες απέναντι στον ξαφνικό θάνατο**, στην περίπτωση αστοχίας του υποκείμενου υλικού. Καθόσον αυτό είναι ένα πολύ πιο σπάνιο φαινόμενο από ένα κομψό τερματισμό μέσω `SIGTERM`, μπορεί παρολαυτά να συμβεί. Η συνιστώμενη προσέγγιση είναι η χρήση ενός εύρωστου διαχειριστή ουρών, όπως το Beanstalkd, ο οποίος επιστρέφει τις εργασίες πίσω στην ουρά όταν οι πελάτες αποσυνδεθούν ή λήξει ο χρόνος τους. Σε κάθε περίπτωση, μια εφαρμογή δώδεκα παραγόντων είναι δομημένη έτσι ώστε να διαχειρίζεται απρόβλεπτους, μη κομψούς τερματισμούς. Η [σχεδίαση Crash-only](http://lwn.net/Articles/191059/) πάει αυτή την έννοια στην [λογική της κατάληξη](http://docs.couchdb.org/en/latest/intro/overview.html). + + diff --git a/content/el/intro.md b/content/el/intro.md new file mode 100644 index 000000000..ffe0c79f4 --- /dev/null +++ b/content/el/intro.md @@ -0,0 +1,12 @@ +Εισαγωγή +======== + +Στη μοντέρνα εποχή, το λογισμικό συνήθως παρέχεται ως υπηρεσία: καλούμενο *εφαρμογές ιστού* (*web apps*), ή *λογισμικό-ως-υπηρεσία* (*software-as-a-service*). Η εφαρμογή δώδεκα παραγόντων είναι μια μεθοδολογία κατασκευής εφαρμογών λογισμικού-ως-υπηρεσίας όπου: + +* Χρησιμοποιεί **δηλωτικές** μορφές (**declarative** formats) για να στήσει τον αυτοματισμό, να ελαχιστοποιήσει το χρόνο και το κόστος για νέους προγραμματιστές να συμμετέχουν στο έργο, +* Έχει ένα **καθαρό συμβόλαιο** (**clean contract**) με το υποκείμενο λειτουργικό σύστημα, προσφέροντας **μέγιστη φορητότητα** (**maximum portability**) μεταξύ περιβαλλόντων εκτέλεσης, +* Είναι κατάλληλη για **ανάπτυξη** (**deployment**) σε μοντέρνες πλατφόρμες υπολογιστικού νέφους (**cloud platforms**), καθιστώντας περιττή την ανάγκη για εξυπηρετητές και διαχείριση συστημάτων, +* **Ελαχιστοποιεί την απόκλιση** μεταξύ υλοποίησης (development) και παραγωγής (production), διευκολύνοντας την **συνεχή ανάπτυξη** (**continuous deployment**) για μέγιστη ευκινησία (maximum agility), +* Και μπορεί να **κλιμακωθεί προς τα πάνω** (**scale up**) χωρίς σημαντικές αλλαγές στα εργαλεία, στην αρχιτεκτονική, ή στις πρακτικές υλοποίησης. + +Η μεθοδολογία δώδεκα παραγόντων μπορεί να εφαρμοστεί σε εφαρμογές οι οποίες είναι γραμμένες σε οποιαδήποτε γλώσσα προγραμματισμού, και οι οποίες χρησιμοποιούν οποιοδήποτε συνδυασμό από υπηρεσίες υποστήριξης (βάση δεδομένων, ουρά εργασιών, προσωρινή μνήμη, κλπ). diff --git a/content/el/logs.md b/content/el/logs.md new file mode 100644 index 000000000..8e3c3d012 --- /dev/null +++ b/content/el/logs.md @@ -0,0 +1,16 @@ +## XI. Αρχεία συμβάντων +### Τα αρχεία συμβάντων ως ροές συμβάντων + +Τα *αρχεία συμβάντων* (*logs*) παρέχουν ορατότητα στη συμπεριφορά της εκτελούμενης εφαρμογής. Σε περιβάλλοντα εξυπηρετητή (server-based environments) συνήθως γράφονται σε ένα αρχείο στο δίσκο (ένα "logfile"), αλλά αυτό είναι μόνο μια μορφή εξόδου (output format). + +Τα αρχεία συμβάντων είναι η [ροή (stream)](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) των συσσωρευμένων, χρονικά διατεταγμένων συμβάντων που συλλέγονται από τις ροές εξόδου (output streams) όλων των εκτελούμενων διεργασιών και υπηρεσιών υποστήριξης. Τα αρχεία συμβάντων στην ακατέργαστη μορφή τους είναι τυπικά μια μορφή κειμένου με ένα συμβάν ανά γραμμή (ωστόσο τα ίχνη εκτέλεσης ή backtraces από σφάλματα μπορεί να επεκτείνονται σε πολλαπλές γραμμές). Τα αρχεία συμβάντων δεν έχουν δεδομένη αρχή ή τέλος, αλλά ρέουν συνεχόμενα όσο η εφαρμογή λειτουργεί. + +**Μια εφαρμογή δώδεκα παραγόντων ποτέ δεν ασχολείται με τη δρομολόγηση ή την αποθήκευση της ροής εξόδου (output stream) της.** Δεν πρέπει να επιχειρεί να γράψει ή να διαχειριστεί logfiles. Αντίθετα, κάθε εκτέλούμενη διεργασία γράφει τη ροή συμβάντων της , χωρίς προσωρινή αποθήκευση και συσσώρευση (unbuffered), στο `stdout` (τυπική έξοδο). Κατά την υλοποίηση τοπικά, ο προγραμματιστής θα δεί αυτή τη ροή στο προσκήνιο του τερματικού του για να παρατηρήσει την συμπεριφορά της εφαρμογής. + +Στις αναπτύξεις ελέγχου ή παραγωγής (staging or production deploys), η ροή κάθε διεργασίας θα συλλεγεί από το περιβάλλον εκτέλεσης, θα συνδεθεί μαζί με όλες τις άλλες ροές από την εφαρμογή, και θα δρομολογηθεί σε ένα ή περισσότερους τελικούς προορισμούς για εξέταση και αποθήκευση μακράς διάρκειας. Αυτοί οι προορισμοί δεν είναι ούτε ορατοί ούτε παραμετροποιήσιμοι από την εφαρμογή, και αντιθέτως είναι τελείως διαχειριζόμενοι από το περιβάλλον εκτέλεσης. Δρομολογητές συμβάντων ανοικτού κώδικα (όπως το [Logplex](https://github.com/heroku/logplex) και το [Fluentd](https://github.com/fluent/fluentd)) είναι διαθέσιμοι για αυτό το σκοπό. + +Η ροή συμβάντων μιας εφαρμογής μπορεί να δρομολογηθεί σε ένα αρχείο, ή να παρακολουθηθεί σε πραγματικό χρόνο μέσω tail σε ένα τερματικό. Το σημαντικότερο, η ροή μπορεί να σταλθεί σε ένα σύστημα ανάλυσης και αρχειοθέτησης συμβάντων (log indexing and analysis system) όπως το [Splunk](http://www.splunk.com/), ή σε ένα γενικού σκοπού σύστημα ανάλυσης δεδομένων (data warehousing system) όπως το [Hadoop/Hive](http://hive.apache.org/). Αυτά τα συστήματα επιτρέπουν μεγαλή ισχύ και ευελιξία στην ενδοσκόπηση της συμπεριφοράς της εφαρμογής σε σχέση με το χρόνο, συμπεριλαμβανομένων: + +* Εύρεση συγκεκριμένων συμβάντων στο παρελθόν. +* Γραφήματα τάσεων μεγάλης κλίμακας (όπως αιτήσεις ανά λεπτό). +* Ενεργή ειδοποίηση (active alerting) σύμφωνα με ευρετικά κριτήρια δοσμένα από το χρήστη (user-defined heuristics) (όπως μια ειδοποίηση όταν η ποσότητα σφαλμάτων ανά λεπτό υπερβαίνει ένα συγκεκριμένο όριο). diff --git a/content/el/port-binding.md b/content/el/port-binding.md new file mode 100644 index 000000000..edf9e0bb6 --- /dev/null +++ b/content/el/port-binding.md @@ -0,0 +1,14 @@ +## VII. Πρόσδεση θυρών +### Εξαγωγή υπηρεσιών μέσω πρόσδεσης θυρών + +Οι εφαρμογές (παγκόσμιου) ιστού (web apps) μερικές φορές εκτελούνται μέσα σε ένα εξυπηρετητή ιστού (webserver container). Για παράδειγμα, εφαρμογές PHP μπορεί να τρέχουν ως ένα κομμάτι μέσα στο [Apache HTTPD](http://httpd.apache.org/), ή εφαρμογές Java μπορεί να τρέχουν μέσα στο [Tomcat](http://tomcat.apache.org/). + +**Η εφαρμογή δώδεκα παραγόντων είναι εντελώς αυτοτελής (self-contained)** και δεν βασίζεται στην εισδοχή ενός εξυπηρετηή ιστού (webserver) κατά την εκτέλεση από το περιβάλλον εκτέλεσης για να δημιουργήσει μια υπηρεσία ιστού (web-facing service). Η εφαρμογή ιστου (web app) **εξάγει το HTTP ως υπηρεσία μέσω πρόσδεσης σε μια θύρα (binding to a port)**, και αναμένοντας αιτήσεις εξυπηρέτησης που έρχονται από αυτή τη θύρα. + +Σε ένα τοπικό περιβάλλον υλοποίησης, ο προγραμματιστής επισκέπτεται ένα URL υπηρεσίας όπως το `http://localhost:5000/` για να έχει πρόσβαση στην υπηρεσία που εξάγεται απο την εφαρμογή του. Στην παραγωγή, ένα επίπεδο δρομολόγησης χειρίζεται τις αιτήσεις δρομολόγησης από ένα δημόσιο φιλοξενητή πρός τις διεργασίες ιστού προσδεδεμένες σε θύρα (port-bound web processes). + +Αυτό τυπικά υλοποιείται χρησιμοποιώντας [δήλωση εξαρτήσεων](./dependencies) για να προστεθεί μια βιβλιοθήκη εξυπηρετητή ιστου (webserver library) στην εφαρμογή, όπως το [Tornado](http://www.tornadoweb.org/) για τη Python, το [Thin](http://code.macournoyer.com/thin/) για τη Ruby, ή το [Jetty](http://www.eclipse.org/jetty/) για τη Java και άλλες γλώσσες που βασίζονται στη JVM. Αυτό συμβαίνει εξ' ολοκλήρου στο *χώρο χρήστη* (*user space*), δηλαδή, μέσα στον κώδικα της εφαρμογής. Το συμβόλαιο (contract) με το περιβάλλον εκτέλεσης είναι η πρόσδεση σε μια θύρα για να εξυπηρετηθούν αιτήσεις. + +Το HTTP δεν είναι η μόνη υπηρεσία που μπορεί να εξαχθεί μέσω πρόσδεσης θυρών (port binding). Σχεδόν κάθε είδος λογισμικού εξυπηρετητή (server software) μπορέι να τρέξει μέσω μιας διεργασίας που προσδένεται σε θύρα και αναμένει εισερχόμενα αιτήματα εξυπηρέτησης. Παραδείγματα περιλαμβάνουν το [ejabberd](http://www.ejabberd.im/) (που μιλάει [XMPP](http://xmpp.org/)), και το [Redis](http://redis.io/) (που μιλάει το [πρωτόκολλο Redis](http://redis.io/topics/protocol)). + +Σημειώστε επίσης ότι η προσέγγιση της πρόσδεσης θυρών σημαίνει ότι μία εφαρμογή μπορεί να γίνει [υπηρεσία υποστήριξης](./backing-services) για μια άλλη εφαρμογή, παρέχοντας το URL της εφαρμογής υποστήριξης ως ένα αναγνωριστικό πόρου (resource handle) στις [παραμέτρους (config)](./config) της εφαρμογής που θα την καταναλώσει. diff --git a/content/el/processes.md b/content/el/processes.md new file mode 100644 index 000000000..3f0669129 --- /dev/null +++ b/content/el/processes.md @@ -0,0 +1,14 @@ +## VI. Διεργασίες +### Εκτέλεση εφαρμογής ως μία ή περισσότερες διεργασίες χωρίς κατάσταση + +Η εφαρμογή εκτελείται στο περιβάλλον εκτέλεσης ως μία ή περισσότερες *διεργασίες* (*processes*). + +Στην απλούστερη των περιπτώσεων, ο κώδικας είναι ένα αυτόνομο σενάριο εντολών (script), το περιβάλλον εκτέλεσης είναι ο φορητός υπολογιστής του προγραμματιστή με εγκατεστημένο ένα εκτελέσιμο της γλώσσας προγραμματισμού, και η διεργασία κινείται μέσω της γραμμής εντολών (command line) (για παράδειγμα, `python my_script.py`). Στην άλλη πλευρά του φάσματος, μια ανάπτυξη εφαρμογής για παραγωγή μιας σύνθετης εφαρμογής μπορεί να χρησιμοποιήσει πολλούς [τύπους διεργασιών, ενσαρκωμένων σε μερικές διεργασίες](./concurrency). + +**Οι διεργασίες δώδεκα παραγόντων είναι χωρίς κατάσταση (stateless) και [δεν μοιράζονται τίποτα](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Οποιαδήποτε δεδομένα πρέπει να παραμείνουν πρέπει να aποθηκευθούν σε μία [υπηρεσία υποστήριξης](./backing-services) με κατάσταση (stateful), τυπικά μια βάση δεδομένων. + +Ο χώρος μνήμης ή το σύστημα αρχείων μιας διεργασίας μπορούν να χρησιμοποιηθούν ως μία σύντομη, μια και έξω προσωρινή μνήμη. Για παράδειγμα, να κατεβάσει ένα μεγάλο αρχείο, να δράσει πάνω σε αυτό, και να αποθηκέυσει τα αποτελέσματα στη βάση δεδομένων. Η εφαρμογή δώδεκα παραγόντων ποτέ δεν θεωρεί ως δεδομένο πως οτιδήποτε αποθηκέυτηκε προσωρινά στη μνήμη της ή στο δίσκο θα είναι διαθέσιμο και σε μια μελλοντική αίτηση για εξυπηρέτηση ή εργασία -- με πολλές διεργασίες κάθε τύπου να τρέχουν, οι πιθανότητες είναι υψηλές πως μια μελλοντική αίτηση για εξυπηρέτηση θα εξυπηρετηθεί από μια άλλη διεργασία. Ακόμα και εάν τρέχει μόνο μία διεργασία, μια επανεκκίνηση (πυροδοτημένη απο μια ανάπτυξη κώδικα, αλλαγή παραμέτρων, ή από το περιβάλλον εκτέλεσης που αλλάζει τη φυσική τοποθεσία της διεργασίας) συνήθως θα σβήσει όλη την τοπική (π.χ, μνήμη και σύστημα αρχείων) κατάσταση (state). + +Οι συσκευαστές περιουσιακών στοιχείων της εφαρμογής (asset packagers) όπως το [django-assetpackager](http://code.google.com/p/django-assetpackager/) χρησιμοποιούν το σύστημα αρχείων σαν προσωρινή μνήμη για μεταγλωττισμένα στοιχεία (compiled assets). Μια εφαρμογή δώδεκα παραγόντων προτιμά να κάνει αυτή τη μεταγλώττιση κατά το [στάδιο κατασκευής (build stage)](./build-release-run). Μερικοί συσκευαστές όπως το [Jammit](http://documentcloud.github.com/jammit/) και το [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) μπορούν να ρυθμιστούν ώστε να συσκευάσουν τα assets κατά το στάδιο κατασκευής. + +Μερικά συστήματα ιστού (web systems) βασίζονται σε ["επίμονες συνεδρίες" ("sticky sessions")](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- δηλαδή, αποθηκέυουν προσωρινά τη συνεδρία χρήστη στη μνήμη της διεργασίας της εφαρμογής και θεωρούν πως οι μελλοντικές αιτήσεις για εξυπηρέτηση απο τον ίδιο χρήστη θα δρομολογηθούν στην ίδια διεργασία. Οι επίμονες συνεδρίες συνιστούν παράβαση των δώδεκα παραγόντων και δεν θα πρέπει ποτέ να χρησιμοποιούνται ή η εφαρμογή να βασίζεται σε αυτές. Τα δεδομένα κατάστασης συνεδρίας είναι καλύτερα να αποθηκευτούν σε μια αποθήκη δεδομένων (datastore) που διαθέτει χρόνο λήξης, όπως το [Memcached](http://memcached.org/) ή το [Redis](http://redis.io/). diff --git a/content/el/toc.md b/content/el/toc.md new file mode 100644 index 000000000..fa7580110 --- /dev/null +++ b/content/el/toc.md @@ -0,0 +1,38 @@ +Οι Δώδεκα Παράγοντες +==================== + +## [I. Βάση Κώδικα](./codebase) +### Μία βάση κώδικα με έλεγχο εκδόσεων, πολλές αναπτύξεις + +## [II. Εξαρτήσεις](./dependencies) +### Εξαρτήσεις εκπεφρασμένα δηλωμένες και απομονωμένες + +## [III. Παραμετροποίηση](./config) +### Αποθήκευση παραμέτρων στο περιβάλλον + +## [IV. Υπηρεσίες υποστήριξης](./backing-services) +### Υπηρεσίες υποστήριξης ως επισυναπτόμενοι πόροι + +## [V. Κατασκευή, έκδοση, εκτέλεση](./build-release-run) +### Αυστηρός διαχωρισμός μεταξύ των σταδίων μεταγλώττισης/κατασκευής και εκτέλεσης + +## [VI. Διεργασίες](./processes) +### Εκτέλεση εφαρμογής ως μία ή περισσότερες διεργασίες χωρίς κατάσταση + +## [VII. Πρόσδεση θυρών](./port-binding) +### Εξαγωγή υπηρεσιών μέσω πρόσδεσης θυρών + +## [VIII. Παραλληλία](./concurrency) +### Κλιμάκωση προς τα έξω μέσω του μοντέλου διεργασιών + +## [IX. Απορριψιμότητα](./disposability) +### Μεγιστοποίηση ευρωστίας της εφαρμογής μέσω γρήγορης εκκίνησης και κομψού τερματισμού + +## [X. Ισοτιμία dev/prod](./dev-prod-parity) +### Κράτησε τα περιβάλλοντα υλοποίησης, ελέγχου και παραγωγής όσο πιο όμοια γίνεται + +## [XI. Αρχεία συμβάντων](./logs) +### Τα αρχεία συμβάντων ως ροές συμβάντων + +## [XII. Διεργασίες διαχείρισης](./admin-processes) +### Εκτέλεση εργασιών διαχείρισης ως διεργασίες μια και έξω diff --git a/content/el/who.md b/content/el/who.md new file mode 100644 index 000000000..2e5c93854 --- /dev/null +++ b/content/el/who.md @@ -0,0 +1,4 @@ +Ποιός πρέπει να διαβάσει αυτό το κείμενο; +========================================= + +Κάθε προγραμματιστής που αναπτύσσει εφαρμογές που τρέχουν σαν υπηρεσίες. Μηχανικοί διαχείρισης συστημάτων οι οποίοι εγκαθιστούν ή διαχειρίζονται τέτοιες εφαρμογές. diff --git a/locales/el.yml b/locales/el.yml new file mode 100644 index 000000000..7a292ab43 --- /dev/null +++ b/locales/el.yml @@ -0,0 +1,7 @@ +el: + # Name of language listed in locales menu + language: "Ελληνικά (el)" + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Μετάφραση από το πρωτότυπο" From 30fad5a8cec67fbf6f9efa9861ea281e2f303d50 Mon Sep 17 00:00:00 2001 From: David Routen Date: Tue, 10 Dec 2019 15:40:47 -0500 Subject: [PATCH 439/472] Upgrade to Ruby 2.6.5, and to Puma 4.2.1 --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index ec1cf33c3..57cf282eb 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.3 +2.6.5 diff --git a/Gemfile b/Gemfile index ffe4ab7a0..1c3836091 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.6.3' +ruby '2.6.5' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index f5b7a45fa..925634ca1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.6.3p62 + ruby 2.6.5p114 BUNDLED WITH 1.17.2 From bbabc1e22fe0af48f185ceda9a3a54f15ae78161 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Wed, 11 Dec 2019 09:56:45 +0100 Subject: [PATCH 440/472] Update travis.yml to Ruby 2.6.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 18a88fd77..3339c363a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.6.3 + - 2.6.5 script: exit 0 sudo: false From faa7e799c59ed37164ffea74d52640f6a4f15f96 Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Fri, 20 Dec 2019 16:14:42 +0100 Subject: [PATCH 441/472] Upgrade rack --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 925634ca1..a3d8d918f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,7 +5,7 @@ GEM eventmachine (1.2.0.1) i18n (0.7.0) maruku (0.7.2) - rack (1.6.11) + rack (1.6.12) rack-protection (1.5.3) rack rack-ssl-enforcer (0.2.9) From 908ccdf0a4f3ac973ea9bc0a933668f320a4be78 Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 28 Oct 2019 15:23:44 +0100 Subject: [PATCH 442/472] [fr] translate "Build, release, run" --- content/fr/toc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/toc.md b/content/fr/toc.md index 6acb2daf5..c67e46eb9 100644 --- a/content/fr/toc.md +++ b/content/fr/toc.md @@ -13,7 +13,7 @@ Les 12 facteurs ## [IV. Services externes](./backing-services) ### Traitez les services externes comme des ressources attachées -## [V. Build, release, run](./build-release-run) +## [V. Assemblez, publiez, exécutez](./build-release-run) ### Séparez strictement les étapes d'assemblage et d'exécution ## [VI. Processus](./processes) From 8f692456307ae47b14ed289e421db4767c47cd50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trung=20L=C3=AA?= Date: Fri, 12 Jun 2015 23:03:21 +0700 Subject: [PATCH 443/472] Translate intro.md [vi] --- content/vi/admin-processes.md | 14 ++++++ content/vi/background.md | 9 ++++ content/vi/backing-services.md | 15 +++++++ content/vi/build-release-run.md | 19 +++++++++ content/vi/codebase.md | 18 ++++++++ content/vi/concurrency.md | 14 ++++++ content/vi/config.md | 22 ++++++++++ content/vi/dependencies.md | 12 ++++++ content/vi/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/vi/disposability.md | 14 ++++++ content/vi/intro.md | 20 +++++++++ content/vi/logs.md | 16 +++++++ content/vi/port-binding.md | 14 ++++++ content/vi/processes.md | 15 +++++++ content/vi/toc.md | 38 +++++++++++++++++ content/vi/who.md | 4 ++ 16 files changed, 320 insertions(+) create mode 100644 content/vi/admin-processes.md create mode 100644 content/vi/background.md create mode 100644 content/vi/backing-services.md create mode 100644 content/vi/build-release-run.md create mode 100644 content/vi/codebase.md create mode 100644 content/vi/concurrency.md create mode 100644 content/vi/config.md create mode 100644 content/vi/dependencies.md create mode 100644 content/vi/dev-prod-parity.md create mode 100644 content/vi/disposability.md create mode 100644 content/vi/intro.md create mode 100644 content/vi/logs.md create mode 100644 content/vi/port-binding.md create mode 100644 content/vi/processes.md create mode 100644 content/vi/toc.md create mode 100644 content/vi/who.md diff --git a/content/vi/admin-processes.md b/content/vi/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/vi/admin-processes.md @@ -0,0 +1,14 @@ +## 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. diff --git a/content/vi/background.md b/content/vi/background.md new file mode 100644 index 000000000..b9ecf6fbd --- /dev/null +++ b/content/vi/background.md @@ -0,0 +1,9 @@ +Background +========== + +The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. + +This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). + +Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. + diff --git a/content/vi/backing-services.md b/content/vi/backing-services.md new file mode 100644 index 000000000..60e43fced --- /dev/null +++ b/content/vi/backing-services.md @@ -0,0 +1,15 @@ +## IV. Backing Services +### Treat backing services as attached resources + +A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). + +Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). + +**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. + +Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. + +A production deploy attached to four backing services. + +Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. + diff --git a/content/vi/build-release-run.md b/content/vi/build-release-run.md new file mode 100644 index 000000000..a7215b0a1 --- /dev/null +++ b/content/vi/build-release-run.md @@ -0,0 +1,19 @@ +## V. Build, release, run +### Strictly separate build and run stages + +A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: + +* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. +* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. +* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) + +**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. + +Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. + +Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. + +Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. + diff --git a/content/vi/codebase.md b/content/vi/codebase.md new file mode 100644 index 000000000..94a62f41e --- /dev/null +++ b/content/vi/codebase.md @@ -0,0 +1,18 @@ +## I. Codebase +### One codebase tracked in revision control, many deploys + +A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. + +A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). + +![One codebase maps to many deploys](/images/codebase-deploys.png) + +There is always a one-to-one correlation between the codebase and the app: + +* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. +* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). + +There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. + +The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. + diff --git a/content/vi/concurrency.md b/content/vi/concurrency.md new file mode 100644 index 000000000..5ae4706b9 --- /dev/null +++ b/content/vi/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Concurrency +### Scale out via the process model + +Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. + +![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) + +**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. + +This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. + +The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. + +Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. diff --git a/content/vi/config.md b/content/vi/config.md new file mode 100644 index 000000000..0bc603b82 --- /dev/null +++ b/content/vi/config.md @@ -0,0 +1,22 @@ +## III. Config +### Store config in the environment + +An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: + +* Resource handles to the database, Memcached, and other [backing services](./backing-services) +* Credentials to external services such as Amazon S3 or Twitter +* Per-deploy values such as the canonical hostname for the deploy + +Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. + +A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. + +Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. + +Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. + +**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. + +Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. + +In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. diff --git a/content/vi/dependencies.md b/content/vi/dependencies.md new file mode 100644 index 000000000..bf5a2dd91 --- /dev/null +++ b/content/vi/dependencies.md @@ -0,0 +1,12 @@ +## 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, [Gem Bundler](http://gembundler.com/) 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. diff --git a/content/vi/dev-prod-parity.md b/content/vi/dev-prod-parity.md new file mode 100644 index 000000000..f6e573342 --- /dev/null +++ b/content/vi/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Dev/prod parity +### Keep development, staging, and production as similar as possible + +Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: + +* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. +* **The personnel gap**: Developers write code, ops engineers deploy it. +* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. + +**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: + +* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. +* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. +* Make the tools gap small: keep development and production as similar as possible. + +Summarizing the above into a table: + + + + + + + + + + + + + + + + + + + + + + +
Traditional appTwelve-factor app
Time between deploysWeeksHours
Code authors vs code deployersDifferent peopleSame people
Dev vs production environmentsDivergentAs similar as possible
+ +[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeLanguageLibraryAdapters
DatabaseRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
QueuePython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CacheMemory, filesystem, Memcached
+ +Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. + +**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. + +Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. + +Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. diff --git a/content/vi/disposability.md b/content/vi/disposability.md new file mode 100644 index 000000000..085f2d721 --- /dev/null +++ b/content/vi/disposability.md @@ -0,0 +1,14 @@ +## 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](http://kr.github.com/beanstalkd/), 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). + + diff --git a/content/vi/intro.md b/content/vi/intro.md new file mode 100644 index 000000000..60f4174b7 --- /dev/null +++ b/content/vi/intro.md @@ -0,0 +1,20 @@ +Giới thiệu +========== + +Trong thời buổi hiện nay, phần mềm thường được chuyển giao như là một dịch vụ: còn được +gọi là *các ứng dụng web*, hay *phần mềm-như-một-dịch vụ (software-as-a-service)*. +Ứng dụng 12-nhân tố là một phương pháp để xẩy dựng các ứng dụng phần mềm-như-một-dịch vụ với +các tiêu chí sau: + +* Sử dụng các định dạng theo kiểu **tường thuật** cho việc thiết lập tự động hoá, để +cắt giảm chi phí và thời gian cho lập trình viên mới tham gia dự án; +* Có một **hợp đồng sạch** với hệ điều hành bên dưới, cung cấp **tối đa khả năng dịch chuyển** giữa các môi trường thực thi; +* Phù hợp để **triển khai** trên các **nền tảng đám mây** mới, cắt giảm yêu cầu quản trị +cho server và hệ thống; +* **Giảm thiểu sự khác nhau** giữa môi trường phát triển và môi trường sản xuất, cho phép +**triển khai liên tục** cho phép tối đa linh hoạt hoá; +* Và có thể **mở rộng** mà không cần thay đổi lớn cho các công cụ, kiến trúc, hoặc cách thức +phát triển. + +Phương pháp 12-nhân tố có thể được áp dụng cho các ứng dụng viết bằng bất kì ngôn ngữ lập +trình nào, và sử dụng bất kì kết hợp giữa các dịch vụ backend (cơ sở dữ liệu, queue, memory cache, vv.). diff --git a/content/vi/logs.md b/content/vi/logs.md new file mode 100644 index 000000000..ab2f4f829 --- /dev/null +++ b/content/vi/logs.md @@ -0,0 +1,16 @@ +## XI. Logs +### Treat logs as event streams + +*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. + +Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. + +**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. + +In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. + +The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: + +* Finding specific events in the past. +* Large-scale graphing of trends (such as requests per minute). +* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). diff --git a/content/vi/port-binding.md b/content/vi/port-binding.md new file mode 100644 index 000000000..8b3a0407e --- /dev/null +++ b/content/vi/port-binding.md @@ -0,0 +1,14 @@ +## VII. Port binding +### Export services via port binding + +Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). + +**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. + +In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. + +This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. + +HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). + +Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. diff --git a/content/vi/processes.md b/content/vi/processes.md new file mode 100644 index 000000000..dbd86a7c8 --- /dev/null +++ b/content/vi/processes.md @@ -0,0 +1,15 @@ +## VI. Processes +### Execute the app as one or more stateless processes + +The app is executed in the execution environment as one or more *processes*. + +In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). + +**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. + +The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. + +Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. + +Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). + diff --git a/content/vi/toc.md b/content/vi/toc.md new file mode 100644 index 000000000..742cb8a5a --- /dev/null +++ b/content/vi/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Codebase](./codebase) +### One codebase tracked in revision control, many deploys + +## [II. Dependencies](./dependencies) +### Explicitly declare and isolate dependencies + +## [III. Config](./config) +### Store config in the environment + +## [IV. Backing Services](./backing-services) +### Treat backing services as attached resources + +## [V. Build, release, run](./build-release-run) +### Strictly separate build and run stages + +## [VI. Processes](./processes) +### Execute the app as one or more stateless processes + +## [VII. Port binding](./port-binding) +### Export services via port binding + +## [VIII. Concurrency](./concurrency) +### Scale out via the process model + +## [IX. Disposability](./disposability) +### Maximize robustness with fast startup and graceful shutdown + +## [X. Dev/prod parity](./dev-prod-parity) +### Keep development, staging, and production as similar as possible + +## [XI. Logs](./logs) +### Treat logs as event streams + +## [XII. Admin processes](./admin-processes) +### Run admin/management tasks as one-off processes diff --git a/content/vi/who.md b/content/vi/who.md new file mode 100644 index 000000000..49eb40fd5 --- /dev/null +++ b/content/vi/who.md @@ -0,0 +1,4 @@ +Who should read this document? +============================== + +Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. From 9cf1006115901ca76028e25f85dfa202fd206275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trung=20L=C3=AA?= Date: Fri, 12 Jun 2015 23:07:49 +0700 Subject: [PATCH 444/472] Add vi locale --- locales/vi.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/vi.yml diff --git a/locales/vi.yml b/locales/vi.yml new file mode 100644 index 000000000..b66801279 --- /dev/null +++ b/locales/vi.yml @@ -0,0 +1,7 @@ +vi: + # Name of language listed in locales menu + language: Tiếng Việt (vi) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "(Tiếng Việt)" From f921e3d8d491e26924b1a820b8fdcfa1d50e45b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trung=20L=C3=AA?= Date: Fri, 12 Jun 2015 23:08:03 +0700 Subject: [PATCH 445/472] Translate who [vi] --- content/vi/who.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/content/vi/who.md b/content/vi/who.md index 49eb40fd5..c16693394 100644 --- a/content/vi/who.md +++ b/content/vi/who.md @@ -1,4 +1,5 @@ -Who should read this document? -============================== +Ai nên đọc tài liệu này? +======================== -Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. +Bất kì lập trình viên đang xây dựng các ứng dụng chạy như là một dịch vụ. Các kỹ sữ hệ +thống đảm nhiệm viện triển khai hoặc quản lý các ứng dụng. From 98994f02f29fa66b959daef5e02ecfa39004a8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trung=20L=C3=AA?= Date: Sat, 13 Jun 2015 00:54:13 +0700 Subject: [PATCH 446/472] Translate more pages [vi] --- content/vi/background.md | 20 ++++++++++++++------ content/vi/codebase.md | 28 +++++++++++++++++----------- content/vi/dependencies.md | 25 ++++++++++++++++++------- content/vi/intro.md | 4 ++-- content/vi/toc.md | 8 ++++---- content/vi/who.md | 2 +- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/content/vi/background.md b/content/vi/background.md index b9ecf6fbd..927c3e61e 100644 --- a/content/vi/background.md +++ b/content/vi/background.md @@ -1,9 +1,17 @@ -Background -========== +Gốc gác +======= -The contributors to this document have been directly involved in the development and deployment of hundreds of apps, and indirectly witnessed the development, operation, and scaling of hundreds of thousands of apps via our work on the [Heroku](http://www.heroku.com/) platform. +Tất cả tác giả của tài liệu này đã trực tiếp tham gia vào quá trình phát triển và triển +khai của hàng trăm ứng dụng, và gián tiếp theo dõi các quá trình phát triển, vận hành, +và mở rộng của hàng nghìn ứng dụng thông qua công việc của chúng tôi trên hệ thống [Heroku](http://www.heroku.com/). -This document synthesizes all of our experience and observations on a wide variety of software-as-a-service apps in the wild. It is a triangulation on ideal practices for app development, paying particular attention to the dynamics of the organic growth of an app over time, the dynamics of collaboration between developers working on the app's codebase, and [avoiding the cost of software erosion](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). - -Our motivation is to raise awareness of some systemic problems we've seen in modern application development, to provide a shared vocabulary for discussing those problems, and to offer a set of broad conceptual solutions to those problems with accompanying terminology. The format is inspired by Martin Fowler's books *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* and *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)*. +Tài liệu này là cô đọng của tất cả kinh nghiệm và quan sát của chúng tôi trên một số lượng +lớn các ứng dụng-như-một-dịch vụ ở ngoài. Đây là kết hợp của kiến thức thực hành chuẩn mực +trong việc phát triển ứng dụng, với trọng tâm vào cơ cấu phát triển cơ bản của ứng dụng trong +một khoảng thời gian, cơ cấu động của sự hợp tác giữa các lập trình viên đang làm việc trên +cùng một mã gốc, và [tránh rò rỉ chi phí phát triển phần mềm](http://blog.heroku.com/archives/2011/6/28/the_new_heroku_4_erosion_resistance_explicit_contracts/). +Động lực của chúng tôi là tăng cường nhận thức về các vấn đề hệ thống mà chúng tôi biết +với các qui trình phát triển ứng dụng hiện tại, để chia sẻ một kho kiến thức thảo luận +về các vấn đề này, và để cung cấp một chuỗi các giải pháp mở chác vấn đề trên và cũng đi kèm +với các thuật ngữ chuyên môn. Định dạng này lấy ý tưởng từ cuốn sách *[Patterns of Enterprise Application Architecture](http://books.google.com/books/about/Patterns_of_enterprise_application_archi.html?id=FyWZt5DdvFkC)* và *[Refactoring](http://books.google.com/books/about/Refactoring.html?id=1MsETFPD3I0C)* của ông Martin Fowler. diff --git a/content/vi/codebase.md b/content/vi/codebase.md index 94a62f41e..9be6bc17d 100644 --- a/content/vi/codebase.md +++ b/content/vi/codebase.md @@ -1,18 +1,24 @@ -## I. Codebase -### One codebase tracked in revision control, many deploys +## I. Mã gốc (codebase) +### Một mã gốc (codebase) được theo dõi với hệ thống quản lý phiên bản, và nhiều lần triển khai (deploy) -A twelve-factor app is always tracked in a version control system, such as [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), or [Subversion](http://subversion.apache.org/). A copy of the revision tracking database is known as a *code repository*, often shortened to *code repo* or just *repo*. +Một ứng dụng 12-hệ số luôn luôn được theo dõi bới hê thống quản lý phiên bản, như là [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/), hay [Subversion](http://subversion.apache.org/). Một bản lưu của cơ sở dữ liệu các phiên bản được gọi là **kho mã (code repository)**, và hay được viết vắn tắt thành *code repo* hay *repo*. -A *codebase* is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). +Một *mã gốc* là bất kì một repo riêng lẻ (trong một hệ thống quản lý phiên bản thống nhất như Subversion), hoặc bất kì một nhóm các repo chia sẻ cùng một commit nguồn (root commit) (trong một hệ thống quản lý phiên bản kiểu phân quyển như Git). -![One codebase maps to many deploys](/images/codebase-deploys.png) +![Một mã gốc được gắn với nhiều triển khai](/images/codebase-deploys.png) -There is always a one-to-one correlation between the codebase and the app: +Sẽ luôn luôn là sự tương quan một-với-một giữa mã gốc và ứng dụng: -* If there are multiple codebases, it's not an app -- it's a distributed system. Each component in a distributed system is an app, and each can individually comply with twelve-factor. -* Multiple apps sharing the same code is a violation of twelve-factor. The solution here is to factor shared code into libraries which can be included through the [dependency manager](./dependencies). +* Nếu có nhiều mã gốc, đấy không phải là một ứng dụng -- mà là một hệ thống phân tán. Với các +phần tử trong một hệ thống phân tán là một ứng dụng, với mỗi cá thể tuân theo luật 12-hệ số. +* Nhiều ứng dụng chia sẻ cùng một mã là vi phạm luật của 12-hệ số. Giải pháp ở đây là xem xét +để nhóm các mã chia sẻ thành các thư viện mà có thể được nhúng vào thông qua [trình quản lý các gói phụ thuộc (dependency manager)](./dependencies). -There is only one codebase per app, but there will be many deploys of the app. A *deploy* is a running instance of the app. This is typically a production site, and one or more staging sites. Additionally, every developer has a copy of the app running in their local development environment, each of which also qualifies as a deploy. - -The codebase is the same across all deploys, although different versions may be active in each deploy. For example, a developer has some commits not yet deployed to staging; staging has some commits not yet deployed to production. But they all share the same codebase, thus making them identifiable as different deploys of the same app. +Chỉ có một mã gốc từng ứng dụng, nhưng sẽ có nhiều triển khai của một ứng dụng. Một *triển khai* là một đối tượng thực thi của ứng dụng đó. Đây là trường hợp rất phổ biến của các trang +đã đi vào hoạt động, và của một vài trang thử nghiệm. Thêm vào đó mỗi lập trình viên sẽ có một +bản lưu của ứng dụng đang chạy trên môi trường phát triển cá nhân, mỗi bản đều được coi như là +một triển khai. +Mã gốc sẽ giống nhau trên các triển khai, tuy là phiên bản khác nhau có thể hoạt dộng trong mỗi triển khai. Lấy một ví dụ, một lập trình viên có nhiều commit nhưng chưa triển khai vào +hệ thống thử (staging); hệ thống thử có nhiều commit mà chưa được triển khai trên hệ thống sản xuất (production). Nhưng cả hai đều chia sẻ cùng một mã gốc; thế nên phải định dạng chúng +như những cá thể triển khai của cùng một ứng dụng. diff --git a/content/vi/dependencies.md b/content/vi/dependencies.md index bf5a2dd91..14390f6d7 100644 --- a/content/vi/dependencies.md +++ b/content/vi/dependencies.md @@ -1,12 +1,23 @@ -## II. Dependencies -### Explicitly declare and isolate dependencies +## II. Các phụ thuộc +### Khai báo và phân cách các phụ thuộc -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"). +Hầu hết các ngôn ngữ lập trình đều cung cấp hệ thống gói để phân phối các gói thư viện hỗ trợ, ví dụ như [CPAN](http://www.cpan.org/) cho Perl hay [Rubygems](http://rubygems.org/) cho Ruby. Các thư viện cài đặt thông qua một hệ thống gói có thể được cài đặt ở mức phủ hệ thống (được biết đến với thuật ngữ "site packages") hay được nhóm và trong một thư mục có kèm ứng +dụng (được biết đến với thuật ngữ "vendoring" hay "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. +**Một ứng dụng 12-hệ số không bao giờ phụ thuộc vào sự hiện diện tuyệt đối của các gói hệ +thống.** Nó khai báo toàn bộ các phụ thuộc hoàn toàn thông qua bản kê khai *khai báo phụ thuộc*. Hơn thế nữa nó còn sử dụng công cụ *phân cách phụ thuộc* trong quá trình thực thi để +đảm bảo rằng không có các phụ thuộc tuyệt đối nào bị "lọt" vào trong các hệ thống xung quanh. +Khai báo đầy đủ và rõ ràng các phụ thuộc được áp dụng đồng đều cho cả hệ thống sản xuất và +phát triển. -For example, [Gem Bundler](http://gembundler.com/) 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. +Lấy ví dụ [Gem Bundler](http://gembundler.com/) của Ruby cung cấp định dạng kê khai `Gemfile` để khai báo phụ thuộc và `bundle exec` để phân cách phụ thuộc. Với Python thì có công cụ riêng biệt cho các bước trên -- [Pip](http://www.pip-installer.org/en/latest/) được dùng để khai báo [Virtualenv](http://www.virtualenv.org/en/latest/) để phân cách. Ngay cả C có [Autoconf](http://www.gnu.org/s/autoconf/) để khai báo phụ thuộc, và liên kết tĩnh (static linking) có thể cung cấp phân cách phụ thuộc. Bất kể công cụ gì, kê khai phụ thuộc và phân cách luôn phải đi đôi với nhau -- chỉ cần thiếu một trong hai là không đạt yêu câu của của 12-hệ số. -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`. +Một ích lợi khác của khai báo phụ thuộc rõ ràng là nó đơn giản hoá quá trình cài đặt cho +lập trình viên mới tiếp nhận dự án. Các lập trình viên mới có thể lấy về mã trên hệ thống +phát triển của họ, chỉ với một yêu cầu là cài đặt trước ngôn ngữ lập trình và trình quản lý +phụ thuộc. Chúng có thể được dùng để thiết lập mọi thứ cần để vận hành một ứng dụng với một +*lệnh biên dịch/xây dựng* định sẵn. Lấy một ví dụ cụ thể là lệnh thiết lập cho Ruby/Bundler là `bundle install`, còn với Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) là `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. +Các ứng dụng 12-hệ số đông thời có thể không phụ thuộc vào bất cứ sự hiện diện của các công cụ hệ thống tuyệt đối nào. Các ví dụ bao gồm các công cụ cài đặt sẵn như ImageMagick hay `curl`. Trong khi các công cụ trên có thể hiện diện trên đa số các hệ thống, nhưng không có gì bảo +đảm là chúng sẽ hiện diện trên toàn bộ các hệ thống mà ứng dụng có thể chạy trong tương la, hoặc có chăng phiên bản tìm thấy trên các hệ thống tương lai sẽ tương thích với ứng dụng. Nếu ứng dụng cần được cài sẵn như một công cụ hệ thống, các công cụ đó nên được đi kèm cùng +với ứng dụng. diff --git a/content/vi/intro.md b/content/vi/intro.md index 60f4174b7..d24ad3d55 100644 --- a/content/vi/intro.md +++ b/content/vi/intro.md @@ -3,7 +3,7 @@ Giới thiệu Trong thời buổi hiện nay, phần mềm thường được chuyển giao như là một dịch vụ: còn được gọi là *các ứng dụng web*, hay *phần mềm-như-một-dịch vụ (software-as-a-service)*. -Ứng dụng 12-nhân tố là một phương pháp để xẩy dựng các ứng dụng phần mềm-như-một-dịch vụ với +Ứng dụng 12-hệ số là một phương pháp để xẩy dựng các ứng dụng phần mềm-như-một-dịch vụ với các tiêu chí sau: * Sử dụng các định dạng theo kiểu **tường thuật** cho việc thiết lập tự động hoá, để @@ -16,5 +16,5 @@ cho server và hệ thống; * Và có thể **mở rộng** mà không cần thay đổi lớn cho các công cụ, kiến trúc, hoặc cách thức phát triển. -Phương pháp 12-nhân tố có thể được áp dụng cho các ứng dụng viết bằng bất kì ngôn ngữ lập +Phương pháp 12-hệ số có thể được áp dụng cho các ứng dụng viết bằng bất kì ngôn ngữ lập trình nào, và sử dụng bất kì kết hợp giữa các dịch vụ backend (cơ sở dữ liệu, queue, memory cache, vv.). diff --git a/content/vi/toc.md b/content/vi/toc.md index 742cb8a5a..adc493d6f 100644 --- a/content/vi/toc.md +++ b/content/vi/toc.md @@ -1,8 +1,8 @@ -The Twelve Factors -================== +12 hệ số +======== -## [I. Codebase](./codebase) -### One codebase tracked in revision control, many deploys +## [I. Mã gốc](./codebase) +### Một mã gốc được theo dõi với hệ thống quản lý phiên bản, và nhiều lần triển khai ## [II. Dependencies](./dependencies) ### Explicitly declare and isolate dependencies diff --git a/content/vi/who.md b/content/vi/who.md index c16693394..4dedf8cc2 100644 --- a/content/vi/who.md +++ b/content/vi/who.md @@ -2,4 +2,4 @@ Ai nên đọc tài liệu này? ======================== Bất kì lập trình viên đang xây dựng các ứng dụng chạy như là một dịch vụ. Các kỹ sữ hệ -thống đảm nhiệm viện triển khai hoặc quản lý các ứng dụng. +thống đảm nhiệm triển khai hoặc quản lý các ứng dụng. From 01e759b54f53580d69cf1c9afab16f69a3dc0fbb Mon Sep 17 00:00:00 2001 From: Hoai-Thu Vuong Date: Sat, 30 Jun 2018 00:48:21 +0700 Subject: [PATCH 447/472] vietnamese translation - update toc, config, dependencies - translate config - fix term - update keyword in locale for vietnamese - update toc, chapter 2 - translate config - typo in intro - fix toc of config and edit intro - translate backing services - fix toc for backing service - improve intro - translate stages - translate processes - translate port-binding, concurrency, processess - translate last four factors --- content/vi/admin-processes.md | 18 ++++----- content/vi/backing-services.md | 15 ++++--- content/vi/build-release-run.md | 23 ++++++----- content/vi/concurrency.md | 17 ++++---- content/vi/config.md | 33 +++++++++------- content/vi/dependencies.md | 2 +- content/vi/dev-prod-parity.md | 69 ++++++++++++++++----------------- content/vi/disposability.md | 16 ++++---- content/vi/intro.md | 8 ++-- content/vi/logs.md | 20 +++++----- content/vi/port-binding.md | 16 ++++---- content/vi/processes.md | 17 ++++---- content/vi/toc.md | 44 ++++++++++----------- content/vi/who.md | 2 +- locales/vi.yml | 2 +- 15 files changed, 151 insertions(+), 151 deletions(-) diff --git a/content/vi/admin-processes.md b/content/vi/admin-processes.md index 870a56096..60bf77426 100644 --- a/content/vi/admin-processes.md +++ b/content/vi/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Admin processes -### Run admin/management tasks as one-off processes +## XII. Tiến trình quản trị +### Thực thi nhiệm vụ quản trị như là một tiến trình -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: +[Công thức cho các tiến trình](./concurrency) là danh sách các tiến trình được sử dụng để thực thi các nghiệp vụ của ứng dụng (như là điều khiển web) khi chúng vận hành. Ngoài ra, lập trình viên thường mong muốn thực hiện các nhiệm vụ quản trị ứng dụng như là: -* 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`). +* Áp dụng các thay đổi cho cơ sở dữ liệu (như là `manage.py migrate` với Django, `rake db:migrate` với Rails). +* Giao diện điều khiển trực tiếp ứng dụng (được biết đến như là vỏ [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop)) để vận hành các đoạn mã nguồn tuỳ ý hoặc kiểm tra các mô hình của ứng dụng đối với cơ sở dữ liệu hiện tại. Hầu hết các ngôn ngữ cung cấp REPL bằng cách thực thi một bộ biên dịch không có tham số như là (e.g. `python` or `perl`) hoặc trong vài trường hợp có các câu lệnh đặc biệt (như là `irb` với Ruby, `rails console` với Rails). +* Thực thi một lần đoạn kịch bản được quản lý trên kho mã nguồn của ứng dụng (như là `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. +Tiến trình quản trị thực thi một lần nên đươcj vận hành trong một môi trường giống như [tiến trình vận hành lâu dài](./processes) của ứng dụng. Với một bản [phát hành](./build-release-run), các tiến trình quản trị sử dụng cùng [mã gốc](./codebase) và [cấu hình](./config) như bất kỳ các tiến trình vận hành trong bản phát hành đó. Đoạn mã quản trị cần được triển khai cùng với mã của ứng dụng để đảm bảo không có các vấn đề về mặt động bộ hoá. -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. +Kỹ thuật [cô lập phụ thuộc](./dependencies) tương tự được sử dụng cho cùng một kiểu tiến trình. Ví dụ tiến trình web sử dụng Ruby sử dụng câu lệnh `bundle exec thin start`, sau đó việc đồng bộ hoá cơ sở dữ liệu sử dụng câu lệnh `bundle exec rake db:migrate`. Tương tự, một chương trình Python sử dụng môi trường ảo cung cấp câu lệnh `bin/python` cho việc vận hành máy chủ web Tornado và bất cứ tiến trình quản trị thông qua `manage.py`. -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. +Mười hai hệ số ưu tiên sử dụng các ngôn ngữ cung cấp vỏ REPL linh hoạt, và làm nó trở nên dễ dàng cho việc thực thi một lần các kịch bản. Trong môi trường triển khai cục bộ, lập trình viên thực thi các tiến trình quản trị bằng cách thực thi trực tiếp các câu lệnh trong thư mục lưu trữ mã nguồn của ứng dụng. Trong môi trường vận hành thực tế, lập trình viên có thể sử dụng ssh hoặc các câu lệnh điều khiển thực thi cơ chế được cung cấp bởi môi trường vận hành của quá trình triển khai để thực thi các tiến trình. diff --git a/content/vi/backing-services.md b/content/vi/backing-services.md index 60e43fced..19b2301e9 100644 --- a/content/vi/backing-services.md +++ b/content/vi/backing-services.md @@ -1,15 +1,14 @@ -## IV. Backing Services -### Treat backing services as attached resources +## IV. Dịch vụ hỗ trợ +### Dịch vụ hỗ trợ như là tài nguyên bổ xung -A *backing service* is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as [MySQL](http://dev.mysql.com/) or [CouchDB](http://couchdb.apache.org/)), messaging/queueing systems (such as [RabbitMQ](http://www.rabbitmq.com/) or [Beanstalkd](http://kr.github.com/beanstalkd/)), SMTP services for outbound email (such as [Postfix](http://www.postfix.org/)), and caching systems (such as [Memcached](http://memcached.org/)). +*Dịch vụ hỗ trợ* là các dịch vụ mà ứng dụng sử dụng thông qua mạng như là một thành phần trong vận hành. Ví dụ bao gồm nơi lưu trữ dữ liệu (như là [MySQL](http://dev.mysql.com/) hoặc [CouchDB](http://couchdb.apache.org/)), hệ thống tin nhắn/hàng đợi (như là [RabbitMQ](http://www.rabbitmq.com/) hoặc [Beanstalkd](http://kr.github.com/beanstalkd/)), dịch vụ SMTP để gửi thư điện tử ra ngoài (như là [Postfix](http://www.postfix.org/)), và hệ thống đệm (như là [Memcached](http://memcached.org/)). -Backing services like the database are traditionally managed by the same systems administrators as the app's runtime deploy. In addition to these locally-managed services, the app may also have services provided and managed by third parties. Examples include SMTP services (such as [Postmark](http://postmarkapp.com/)), metrics-gathering services (such as [New Relic](http://newrelic.com/) or [Loggly](http://www.loggly.com/)), binary asset services (such as [Amazon S3](http://aws.amazon.com/s3/)), and even API-accessible consumer services (such as [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), or [Last.fm](http://www.last.fm/api)). +Dịch vụ hỗ trợ như cơ sở dữ liệu thường được quản lý bởi chính hệ thống quản trị của dịch vụ đó trong quá trình triển khai ứng dụng. Thêm vào đó, việc quản trị dịch vụ cục bộ, các ứng dụng có thể sử dụng các dịch vụ được cung cấp và quản lý bởi bên thứ ba. Ví dụ như các dịch vụ SMTP (như [Postmark](http://postmarkapp.com/)), các dịch vụ thu thập thông tin đo lường (metrics-gathering services) (như [New Relic](http://newrelic.com/) hay [Loggly](http://www.loggly.com/)), dịch vụ tài sản nhị phân (binary assets services) (như [Amazon S3](http://aws.amazon.com/s3/)), và các dịch vụ sử dụng API (như [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), hoặc [Last.fm](http://www.last.fm/api)). -**The code for a twelve-factor app makes no distinction between local and third party services.** To the app, both are attached resources, accessed via a URL or other locator/credentials stored in the [config](./config). A [deploy](./codebase) of the twelve-factor app should be able to swap out a local MySQL database with one managed by a third party (such as [Amazon RDS](http://aws.amazon.com/rds/)) without any changes to the app's code. Likewise, a local SMTP server could be swapped with a third-party SMTP service (such as Postmark) without code changes. In both cases, only the resource handle in the config needs to change. +**Mã nguồn của ứng dụng áp dụng mười hai-hệ số cho phép không có sự khác biệt giữa dịch vụ cục bộ và bên thứ ba.** Đối với ứng dụng, cả tài nguyên bổ xung và có thể truy cập thông qua URL hoặc thông tin tài khoản được lưu trữ trong [cấu hình](./config). Một [triển khai](./codebase) của ứng dụng áp dụng mười hai-hệ số có thể chuyển đổi giữa cơ sở dữ liệu MySQL cục bộ với một cơ sở dữ liệu được quản lý bởi bên thứ ba (như [Amazon RDS](http://aws.amazon.com/rds/)) mà không phải thay đổi bất kỳ một đoạn mã nguồn nào của ứng dụng. Giống như, máy chủ SMTP cục bộ có thể được thay thế bởi dịch SMTP của bên thứ ba (như Postmark) mà không thay đổi mã nguồn. Trong cả hai trường hợp, chúng ta chỉ cần thay đổi các tài nguyên được quản lý trong cấu hình. -Each distinct backing service is a *resource*. For example, a MySQL database is a resource; two MySQL databases (used for sharding at the application layer) qualify as two distinct resources. The twelve-factor app treats these databases as *attached resources*, which indicates their loose coupling to the deploy they are attached to. +Mỗi dịch vụ hỗ trợ riêng biệt là một *tài nguyên*. Ví dụ, cơ sở dữ liệu MySQL là một tài nguyên, hai cơ sở dữ liệu MySQL (sử dụng cho việc phân tách ở tầng ứng dụng) được xác định là hai tài nguyên riêng biệt. Ứng dụng áp dụng mười hai-hệ số đối xử các cơ sở dữ liệu như là *tài nguyên bổ sung*, nhằm đảm bảo kết nối lỏng lẻo với triên khai mà chúng được bổ xung. A production deploy attached to four backing services. -Resources can be attached and detached to deploys at will. For example, if the app's database is misbehaving due to a hardware issue, the app's administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached -- all without any code changes. - +Tài nguyển có thể được thêm vào triển khai khi cần thiết. Ví dụ, nếu cơ sở dữ liệu của ứng dụng bị mất do lỗi phần cứng, quản trị viên của ứng dụng có thể thêm vào một máy chủ cơ sở dữ liệu được khôi phục từ các sao lưu trước đó. Các thay đổi bao gồm cơ sở dữ liệu chính đang sử dụng có thể được loại bỏ, và bổ xung cơ sở dữ liệu mới có thể xảy ra mà không cần thay đổi bất kỳ một đoạn mã nguồn nào. diff --git a/content/vi/build-release-run.md b/content/vi/build-release-run.md index a7215b0a1..d3ccc9cf5 100644 --- a/content/vi/build-release-run.md +++ b/content/vi/build-release-run.md @@ -1,19 +1,18 @@ -## V. Build, release, run -### Strictly separate build and run stages +## V. Xây dựng, phát hành, vận hành +### Tách biệt hoàn toàn giữa bước xây dựng và vận hành -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: +[Mã gốc](./codebase) được chuyển sang (tạm dừng phát triển) triển khai thông qua ba bước: -* The *build stage* is a transform which converts a code repo into an executable bundle known as a *build*. Using a version of the code at a commit specified by the deployment process, the build stage fetches and vendors [dependencies](./dependencies) and compiles binaries and assets. -* The *release stage* takes the build produced by the build stage and combines it with the deploy's current [config](./config). The resulting *release* contains both the build and the config and is ready for immediate execution in the execution environment. -* The *run stage* (also known as "runtime") runs the app in the execution environment, by launching some set of the app's [processes](./processes) against a selected release. +* Bước xây dựng* là bước chuyển các đoạn mã thành các gói có khả năng thực thi được gọi là một *bản xảy dựng*. Sử dụng phiên bản của mã nguồn ở một bản cam kết (commit) quy định bở quy trình triển khai, bước xây dựng lấy về và cung cấp các [phụ thuộc](./dependencies) và biên dịch các thành phần và tài nguyên. +* Bước phát hành* sử dụng các kết quả của bước xây dựng và kết hợp với các [cấu hình](./config) triển khai hiện tại. Kết quả của *phát hành* bao gồm cả bản xây dựng và các câu hình cho phép ứng dụng có thể được vận hành trong môi trường vận hành. +* Bước vận hành* (được biết như là "thời gian vận hành" (runtime)) vận hành ứng dụng trong môi trường thực thi, bằng việc thực thi một tập các [tiến trình](./process) của của ứng dụng với một phiên bản phát hành cụ thể. -![Code becomes a build, which is combined with config to create a release.](/images/release.png) +![Mã nguồn được xây dựng, kết hợp với các cấu hình để cung cập một phát hành.](/images/release.png) -**The twelve-factor app uses strict separation between the build, release, and run stages.** For example, it is impossible to make changes to the code at runtime, since there is no way to propagate those changes back to the build stage. +**Ứng dụng sử dụng mười hai-hệ số tách biệt hoàn toàn giữa các bước xây dựng, phát hành và vận hành.** Ví dụ, chúng ta không thể tạo ra các thay đổi của mã nguồn khi đang vận hành, do đó không có khả năng quay ngược lại bước xây dựng. -Deployment tools typically offer release management tools, most notably the ability to roll back to a previous release. For example, the [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool stores releases in a subdirectory named `releases`, where the current release is a symlink to the current release directory. Its `rollback` command makes it easy to quickly roll back to a previous release. +Công cụ triển khai thường cung cấp công cụ quản lý phát hành, cùng với các ký pháp cho phép quay ngược lại bản phat hành trước đó. Ví dụ, công cụ triển khai [Capistrano](https://github.com/capistrano/capistrano/wiki) lưu trữ các phát hành trong thư mục con tên là `releases`, nơi mà phiên bản hiện tại được liên kết giả đến thư mục phát hành hiện tại. Lệnh `rollback` làm cho việc quay trở lại phiên bản trước trở nên dễ dàng. -Every release should always have a unique release ID, such as a timestamp of the release (such as `2011-04-06-20:32:17`) or an incrementing number (such as `v100`). Releases are an append-only ledger and a release cannot be mutated once it is created. Any change must create a new release. - -Builds are initiated by the app's developers whenever new code is deployed. Runtime execution, by contrast, can happen automatically in cases such as a server reboot, or a crashed process being restarted by the process manager. Therefore, the run stage should be kept to as few moving parts as possible, since problems that prevent an app from running can cause it to break in the middle of the night when no developers are on hand. The build stage can be more complex, since errors are always in the foreground for a developer who is driving the deploy. +Mỗi phát hành đều có một định danh duy nhất ID, như là dựa vào thời gian phát hành (như `2011-04-06-20:32:17`) hoặc một số tự tăng (như `v100`). Các phiên bản được tạo ra thành một chuỗi liên tục và một phiên bản không thể thay đổi sau khi nó được tạo ra. Bất cứ thay đổi nào đểu tạo ra một bản phát hành mới. +Các bước xây dựng được khởi tạo với nhà phát triển ứng dụng khi mà mã nguồn được triển khai. Thời gian thực thi, ngược lại, có thể tự động xảy ra trong trường hợp các máy chủ được khởi động lại, hoặc tiến trình tạm dừng được khởi động lại bởi bộ quản lý các tiến trình. Do đó, bước vận hành nên được giữ các thành phần thay đổi càng ít càng tốt, vì các sự cố xảy ra làm ứng dụng không vận hành được có thể gây ra các thiệt hại lúc nửa đêm khi mà không có bất kỳ lập trình viên nào có thể khắc phục sự cố. Bước xây dựng có thể phức tạp hơn, vì các lỗi có thể xuất hiện trước mắt cho lập trình viên, người đang thực hiện triển khai biết được. diff --git a/content/vi/concurrency.md b/content/vi/concurrency.md index 5ae4706b9..8b3518328 100644 --- a/content/vi/concurrency.md +++ b/content/vi/concurrency.md @@ -1,14 +1,15 @@ -## VIII. Concurrency -### Scale out via the process model +## VIII. Đồng bộ hoá +### Mở rộng theo chiều ngang thông qua mô hình tiến trình -Any computer program, once run, is represented by one or more processes. Web apps have taken a variety of process-execution forms. For example, PHP processes run as child processes of Apache, started on demand as needed by request volume. Java processes take the opposite approach, with the JVM providing one massive uberprocess that reserves a large block of system resources (CPU and memory) on startup, with concurrency managed internally via threads. In both cases, the running process(es) are only minimally visible to the developers of the app. +Bất kỳ chương trình máy tính nào, khi vận hành, đều được đại diện bởi một hoặc nhiều tiến trình. Ứng dụng web có thể sử dụng bất kỳ dạng nào của tiến trình vận hành. Ví dụ, tiến trình PHP vận hành như là tiến trình con của Apache, chạy như một tiến trình nền dựa vào số lượng yêu cầu được gửi đến. Ứng dụng Java, tiếp cận theo cách ngược lại, với JVM cung cấp một tiến trình nền tảng lớn (a massive uberprocess) với lượng lớn các tài nguyên (CPU và bộ nhớ) được cấp phát ngay từ đầu, việc đồng bộ hoá được quản lý bên trong thông qua các luồng. Trong cả hai trường hợp, các tiến trình vận hành chỉ hiện hữu rất ít đối với các nhà phát triển của ứng dụng. +developers of the app. -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) +![Mở rộng được biểu diễn thông qua các tiến trình vận hành, Scale is expressed as running processes, hình thái của tải được biểu diễn như là kiểu tiến trình.](/images/process-types.png) -**In the twelve-factor app, processes are a first class citizen.** Processes in the twelve-factor app take strong cues from [the unix process model for running service daemons](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a *process type*. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. +**Trong ứng dụng áp dụng mười hai hệ số, các tiến trình là thành phần nền tảng đầu tiên.** Các tiến trình trong ứng dụng áp dụng mười hai hệ số sử dụng các tín hiệu rõ rệt từ [các mô hình tiến trình của unix cho các dịch vụ chạy nền](http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Sử dụng mô hinh này, các lập trình viên có thể thiết kế ứng dụng của họ để điều khiển các công việc khác nhau bằng cách gán mỗi loại tương ứng với một *kiểu tiến trình*. Ví dụ, yêu cầu HTTP có thể điều khiển bởi tiến trình web, và các ứng dụng chạy gầm tốn nhiều thời gian có thể được quản lý bởi các tiến trình làm việc. -This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), or [Node.js](http://nodejs.org/). But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. +Điều này không loại bỏ các tiến trình các nhân khỏi việc quản lý chính các kênh nội bộ của tiến trình đó, thông qua các luồng bên trong máy áo đang thực thi, hoặc mô hình bất đồng bộ/xự kiện trong các công cụ như là [EventMachine](http://rubyeventmachine.com/), [Twisted](http://twistedmatrix.com/trac/), hoặc [Node.js](http://nodejs.org/). Nhưng một máy ảo (VM) riêng biệt chỉ có thể mở rộng (mở rộng theo chiều dọc), do đó ứng dụng cần có thể mở rộng thành các tiến trình chạy trên nhiều máy chủ vật lý. -The process model truly shines when it comes time to scale out. The [share-nothing, horizontally partitionable nature of twelve-factor app processes](./processes) means that adding more concurrency is a simple and reliable operation. The array of process types and number of processes of each type is known as the *process formation*. +Mô hình tiến trình thực sự nổi trội khi mà việc mở rộng tài nguyên trở nên phổ biển. [Việc không chia sẻ, phân hoạch tự nhiên của các tiến trình của ứng dụng áp dụng mười hai hệ số](./processes) có nghĩa việc thêm các tiến trình đồng bộ hơn là đơn giản và tin cậy. Danh sách các kiểu tiến tình và số lượng tiến trình mỗi loại được biết đến như là *công thức tiến trình*. -Twelve-factor app processes [should never daemonize](http://dustin.github.com/2010/02/28/running-processes.html) or write PID files. Instead, rely on the operating system's process manager (such as [Upstart](http://upstart.ubuntu.com/), a distributed process manager on a cloud platform, or a tool like [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in development) to manage [output streams](./logs), respond to crashed processes, and handle user-initiated restarts and shutdowns. +Tiến trình của ứng dụng mười hai hệ số [không bao giờ chạy như là dịch vụ nền](http://dustin.github.com/2010/02/28/running-processes.html) hoặc ghi ra tệp tin PID. Thay vào đó, tin tưởng vào hệ thống quản lý tiến trình của hệ điều hành (như là [Upstart](http://upstart.ubuntu.com/), hoặc hệ thống quản lý tiến trình phân tán trên nền tảng đám mấy, hoặc công cụ như là [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) trong quá trình phát triển) để quản lý [luồng xuất ra](./logs), phản hồi các tiến trình bị lỗi, và quản lý yêu cầu khởi động lại hoặc ngưng hoạt động của người dùng. diff --git a/content/vi/config.md b/content/vi/config.md index 0bc603b82..f4273dc08 100644 --- a/content/vi/config.md +++ b/content/vi/config.md @@ -1,22 +1,27 @@ -## III. Config -### Store config in the environment +## III. Cấu hình +### Lưu trữ cấu hình trong môi trường -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: +Cấu hình của ứng dụng là những thứ có thể thay đổi qua các [triển khai](./codebase) (hệ thống thử, hệ thống sản xuất, môi trường phát triển, etc). Nó bao gồm: +* Tài nguyên xử lý cơ sở dữ liệu, Memcached, và [dịch vụ lớp dưới](./backing-services) khác +* Thông tin đăng nhập đến các dịch vụ như là Amazon S3 hay Twitter +* Các giá trị ứng với từng triển khai như như là tên của máy chủ để triển khai -* Resource handles to the database, Memcached, and other [backing services](./backing-services) -* Credentials to external services such as Amazon S3 or Twitter -* Per-deploy values such as the canonical hostname for the deploy +Các ứng dụng thường lưu trữ các cấu hình như là hằng số trong mã nguồn. Điều này không phù hợp với nguyên tắc của 12-thừa số, yêu cầu **giới hạn tách biệt các cấu hình khỏi mã nguồn**. Các cấu hình thay đổi qua các triển khai, mã nguồn thì không. -Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires **strict separation of config from code**. Config varies substantially across deploys, code does not. +Một litmus test cho ứng dụng có các cấu hình được thừa số hoá chính xác là mã gốc có khả năng nguồn mở hoá bất kỳ lúc nào mà không lo sợ bị mất các thông tin đăng nhập. -A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. +Chú ý rằng, định nghĩa của "cấu hình" không bao gồm các cấu hình nội tại của ứng dụng, như là `config/routes.rb` trong Rails, hoặc [các thành phần được kết nối](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) trong [Spring](http://spring.io/). Những cấu hình kiểu này thường không thay đổi giữa các triển khai, và do đó đã thực hiện tốt trong mã nguồn. -Note that this definition of "config" does **not** include internal application config, such as `config/routes.rb` in Rails, or how [code modules are connected](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). This type of config does not vary between deploys, and so is best done in the code. +Một cách tiếp cận khác với các cấu hình là việc sử dụng tệp tin cấu hình mà tệp tin đó không được quản lý phiên bản, như là `config/database.yml` trong Rails. Đây là một cải tiến lớn so với việc +sử dụng hằng số trong mã nguồn đã được quản lý phiên bản, nhưng vẫn có điểm yếu: dễ bị thêm nhầm vào quản lý phiên bản, các tệp tin cấu hình dễ bị phân tán ở những nơi khác nhau và các định dạng khác +nhau, làm cho nó trở nên khó đọc và quản lý tất các cấu hỉnh một cách tập trung. Ngoài ra, định dạng của các tệp tin chứa cấu hình thường do đặc tả của ngôn ngữ- hoặc framework-. -Another approach to config is the use of config files which are not checked into revision control, such as `config/database.yml` in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific. +**Ứng dụng áp dụng mười hai thừa số chứa các cấu hình trong *environment variables (biến môi trường)*** (thường viết tắt là *env vars* hoặc *env*). Các biến môi trường rất dễ để thay đổi giữa các triển khai +mà không phải thay đổi mã nguồn; không giống như tệp tin cấu hình, vẫn có khả năng để bị thêm vào kho mã (code repository); và không giống như các tệp tin cấu hình tuỳ chỉnh, hoặc cơ chế quảnl lý cấu +hình như là *Java System Properties*, các biến môi trường là *agnostic standard* theo ngôn ngữ và hệ điều hành. -**The twelve-factor app stores config in *environment variables*** (often shortened to *env vars* or *env*). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard. +Một khía cạnh khác của quản lý cấu hình là nhóm các cấu hình. Đôi khi, các ứng dụng tổ chức các cấu hình theo nhóm (thường được gọi là "các môi trường") được đặt tên theo các triển khai, như là các môi trường`development`, `test`, and `production` trong Rails. Phương pháp này không mở rộng rõ ràng: nếu như có nhiều triển khải của ứng dụng được tạo ra, tên của các môi trường rất quan trọng, như là `staging` hoặc `qa`. Nếu một dự án phát triển sau này, lập trình viên có thể thêm các môi trường của riêng họ như là `joes-staging`, kết quả là một sự bùng nổ về các cấu hình, làm cho việc quản lý +các triển khai trở nên không ổn định. -Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the `development`, `test`, and `production` environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as `staging` or `qa`. As the project grows further, developers may add their own special environments like `joes-staging`, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle. - -In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as "environments", but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime. +Trong một ứng dụng áp dụng mười hai thừa số, các biến môi trường được quản lý chi tiết, hoàn toàn độc lập với các biến môi trường khác. Chúng không được nhóm với nhau như là các "môi trường", nhưng +thay vào đó được quản lý độc lập theo các triển khai. Mô hình này giúp cho việc mở rộng trở nên trơn tru như là việc thêm vào các triển khai theo vòng đời của phần mềm được mở rộng một cách tự nhiên. diff --git a/content/vi/dependencies.md b/content/vi/dependencies.md index 14390f6d7..0c73a06f2 100644 --- a/content/vi/dependencies.md +++ b/content/vi/dependencies.md @@ -1,5 +1,5 @@ ## II. Các phụ thuộc -### Khai báo và phân cách các phụ thuộc +### Khai báo rõ ràng và phân tách các phụ thuộc Hầu hết các ngôn ngữ lập trình đều cung cấp hệ thống gói để phân phối các gói thư viện hỗ trợ, ví dụ như [CPAN](http://www.cpan.org/) cho Perl hay [Rubygems](http://rubygems.org/) cho Ruby. Các thư viện cài đặt thông qua một hệ thống gói có thể được cài đặt ở mức phủ hệ thống (được biết đến với thuật ngữ "site packages") hay được nhóm và trong một thư mục có kèm ứng dụng (được biết đến với thuật ngữ "vendoring" hay "bundling"). diff --git a/content/vi/dev-prod-parity.md b/content/vi/dev-prod-parity.md index f6e573342..bf83fb9c9 100644 --- a/content/vi/dev-prod-parity.md +++ b/content/vi/dev-prod-parity.md @@ -1,76 +1,75 @@ -## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +## X. Sự tương đồng giữa quá trình phát triển và vận hành thực tế +### Đảm bảo sự tương đồng giữa môi trường phát triển, kiểm thử và thực tế -Historically, there have been substantial gaps between development (a developer making live edits to a local [deploy](./codebase) of the app) and production (a running deploy of the app accessed by end users). These gaps manifest in three areas: +Trước đây, có sự khác biệt nhất định giữa quá trình phát triển (lập trình viên có thể tạo ra các bản chỉnh sửa [triển khai](./codebase) cục bộ của ứng dụng) và vận hành thực tế (phiên bản được triển khai thực tế và truy cập bởi khách hàng). Khác biệt này được thể hiện ở ba lĩnh vực: -* **The time gap:** A developer may work on code that takes days, weeks, or even months to go into production. -* **The personnel gap**: Developers write code, ops engineers deploy it. -* **The tools gap**: Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux. +* **Về thời gian**: Lập trình viên có thể làm việc với mã nguồn hàng ngày, tuận, thậm chỉ là hàng tháng để có một phiên bản vận hành thực tế. +* **Về tính cá nhân**: Lập trình viên viết mã nguồn, người vận hành triển khai mã nguồn đó. +* **Về công cụ**: Lập trình viên có thể sử dụng tập các công cụ như là Nginx, SQLite, và OS X, trong khi triển khai thực tế sử dụng Apache, MySQL, và Linux. -**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) by keeping the gap between development and production small.** Looking at the three gaps described above: +**Ứng dụng áp dụng mười hai hệ số được thiết kế để [triển khai liên tục](http://www.avc.com/a_vc/2011/02/continuous-deployment.html) bằng việc giảm thiểu khác biệt giữa quá trình triển khai và vận hành thực tế.** Chúng ta cùng xem lại các sự khác biệt ở trên: -* Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. -* Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. -* Make the tools gap small: keep development and production as similar as possible. - -Summarizing the above into a table: +* Giảm thiểu thời gian: lập trình viên có thể viết mã nguồn và nó được triển khai vài giờ, thậm chí vài phút sau đó. +* Giảm thiểu tính cá nhân: lập trình viên người viết ra các dòng lệnh, có thể tham gia trực tiếp vào quá trình triển khai và quan sát các hình vi của ứng dụng trong môi trường vận hành thực tế. +* Giảm thiểu các công cụ: đảm bảo sự tương đồng giữa môi trường phát triển và vận hành. +Tổng kết vấn đề trên thông qua bảng sau: - - + + - - - + + + - - - + + + - - - + + +
Traditional appTwelve-factor appỨng dụng truyền thốngỨng dụng sử dụng mười hai hệ số
Time between deploysWeeksHoursThời gian giữa các lần triển khaiHàng tuầnHàng giờ
Code authors vs code deployersDifferent peopleSame peopleTác giả và người triển khai mã nguồnKhác nhauCùng một người
Dev vs production environmentsDivergentAs similar as possibleMôi trường phát triển và thực tếKhông đồng nhấtTương đồng
-[Backing services](./backing-services), such as the app's database, queueing system, or cache, is one area where dev/prod parity is important. Many languages offer libraries which simplify access to the backing service, including *adapters* to different types of services. Some examples are in the table below. +[Dịch vụ hỗ trợ](./backing-services), như là cơ sở dữ liệu của ứng dụng, hệ thống hàng đợi hoặc bộ đệm, là nơi mà thường có sự khác biệt giữa môi trường phát triển và vận hành. Rất nhiều ngôn ngữ cung cấp các thư viện, bao gồm nhiều *mô phỏng* của các loại dịch vụ khác nhau được cung cấp để làm đơn giản hoá việc truy cập các dịch vụ hỗ trợ. Một vài ví dụ ở bảng sau: - - - - + + + + - + - + - +
TypeLanguageLibraryAdaptersLoạiNgôn ngữThư việnMô phỏng
DatabaseCơ sở dữ liệu Ruby/Rails ActiveRecord MySQL, PostgreSQL, SQLite
QueueHàng đợi Python/Django Celery RabbitMQ, Beanstalkd, Redis
CacheBộ đệm Ruby/Rails ActiveSupport::Cache Memory, filesystem, Memcached
-Developers sometimes find great appeal in using a lightweight backing service in their local environments, while a more serious and robust backing service will be used in production. For example, using SQLite locally and PostgreSQL in production; or local process memory for caching in development and Memcached in production. +Lập trình viên thường thích sử dụng các dịch vụ hỗ trợ đơn giản trên môi trường cục bộ của họ, trong khi nhiều dịch vụ hỗ trợ mạnh mẽ và an toàn hơn được sử dụng trong môi trường vận hành thực tế. Ví dụ, sử dụng SQLite ở cục bộ và Postgresql trong vận hành, hoặc sử dụng trực tiếp bộ nhớ cho bộ đệm trong phát triển và Memcached trong vận hành. -**The twelve-factor developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Differences between backing services mean that tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors create friction that disincentivizes continuous deployment. The cost of this friction and the subsequent dampening of continuous deployment is extremely high when considered in aggregate over the lifetime of an application. +**Ứng dụng sử dụng mười hai hệ số không cho phép sử dụng dịch vụ hỗ trợ khác nhau giữa môi trường phát triển và vận hành**, mặc dù các bộ mô phỏng có thể trừu tượng hoá bất kỳ sự khác biệt của dịch vụ hỗ trợ. Sự khác biệt giữa dịch vụ hỗ trợ có nghĩa là dù bất kỳ sự không đồng bộ nhỏ nào cũng có thể mở rộng, là nguyên nhân cho việc mã nguồn có thể hoạt động tốt ở môi trường phát triển hoặc kiểm thử nhưng không hoạt động trong môi trường thực tế. Các kiểu lỗi này làm cản trở quá trình triển khai liên tục. Chi phí cho các cản trở và làm giảm ảnh hưởng cho chúng thường rất tốn kém trong suốt quá trình phát triển của một ứng dụng. -Lightweight local services are less compelling than they once were. Modern backing services such as Memcached, PostgreSQL, and RabbitMQ are not difficult to install and run thanks to modern packaging systems, such as [Homebrew](http://mxcl.github.com/homebrew/) and [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Alternatively, declarative provisioning tools such as [Chef](http://www.opscode.com/chef/) and [Puppet](http://docs.puppetlabs.com/) combined with light-weight virtual environments such as [Vagrant](http://vagrantup.com/) allow developers to run local environments which closely approximate production environments. The cost of installing and using these systems is low compared to the benefit of dev/prod parity and continuous deployment. +Các dịch vụ đơn giản ở cục bộ không được ưu tiên như các dịch vụ tương tự. Các dịch vụ hỗ trợ hiện đại như Memcached, PostgreSQL, và RabbitMQ không quá khó để cài đặt thông qua các dịch vụ đóng gói như là [Homebrew](http://mxcl.github.com/homebrew/) và [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Ngoài ra, các công cụ cung cấp khai báo [Chef](http://www.opscode.com/chef/) và [Puppet](http://docs.puppetlabs.com/) kết hợp với các môi trường ảo hoá đơn giản [Vagrant](http://vagrantup.com/) cho phép lập trình viên có thể vận hành ở cục bộ một môi trường khá giống với môi trường vận hành thực tế. Chi phí cho việc cài đặt và sử dụng nhỏ hơn rất nhiều so với chi phí của triển khai liên tục và sự khác biệt giữa môi trường phát triển và vận hành. -Adapters to different backing services are still useful, because they make porting to new backing services relatively painless. But all deploys of the app (developer environments, staging, production) should be using the same type and version of each of the backing services. +Bộ mô phỏng đối với các dịch vụ hỗ trợ vẫn có ích, vì chúng làm giảm ảnh hưởng của việc chuyển đổi sang dịch vụ hỗ trợ mới. Nhưng tất cả các bước triển khai của ứng dụng (môi trường của lập trình viên, kiểm thử, vân hành thực tế) nên sử dụng cùng một loại và phiên bản của các kiểu dịch vụ hỗ trợ. diff --git a/content/vi/disposability.md b/content/vi/disposability.md index 085f2d721..698c1902d 100644 --- a/content/vi/disposability.md +++ b/content/vi/disposability.md @@ -1,14 +1,12 @@ -## IX. Disposability -### Maximize robustness with fast startup and graceful shutdown +## IX. Tính khả dụng +### Tối ưu hoá với khởi động nhanh và dừng phần mềm ổn định -**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. +**[Tiến trình](./processes) của ứng dụng áp dụng mười hai thừa số luôn *sẵn sàng* (disposable), có nghĩa là bạn có thể chạy hoặc dừng phần mềm tại một thời điểm báo trước.** Điều này tạo điều kiện cho việc mở rộng trở nên dễ dàng hơn, việc triển khai nhanh các thay đổi của [mã nguồn](./codebase) hoặc [cấu hình](./config), và sự linh hoạt quá trình triển khai sản phẩm. -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. +Các tiến trình nên cố gắng **giảm thiểu thời gian khởi động**. Lý tưởng nhất, một tiến trình chỉ cần một vài giây kể từ khi có lệnh khởi động cho đến khi tiến trình bắt đầu và sẵn sàng để nhận yêu cầu hay bắt đầu công việc. Thời gian khởi động ngắn cho phép quá trình triển khai và mở rộng nhanh hơn; và hỗ trợ mạnh mẽ hơn, vì hệ thống quản lý các tiến trình có thể dễ dàng mang các tiến trình tới các máy chủ vật lý khi có các cảnh báo. -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](http://kr.github.com/beanstalkd/), 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). +Tiến trình **ngưng hoạt động linh hoạt khi chúng nhận được một tín hiệu [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** từ hệ thống quản lý các tiến trình. Đối với ứng dụng web, việc ngưng hoạt động linh hoạt rất dễ thực hiện bằng cách ngừng lắng nghe trên công dịch vụ (do đó từ chối bất kỳ một yêu cầu mới nào), cho phép các yêu cầu hiện tại được kết thúc, và thoát ra. Ý tưởng của mô hình này là các yêu cầu HTTP cần thực hiện trong thời gian ngắn (thông thường không quá một vài giây), hoặc trong trường hợp kết nối lâu hơn, ứng dụng cần thực hiện kết nối lại khi các kết nối đã bị mất. +Đối với các tiến trình thực thi, việc ngưng hoạt động linh hoạt có thể đạt được bằng cách trả các công việc trở lại hàng đợi. Ví dụ, trên [RabbitMQ](http://www.rabbitmq.com/) các tiến trình thực thi chỉ cần gửi lại một [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); trên [Beanstalkd](http://kr.github.com/beanstalkd/), các công việc được trả lại hàng đợi tự động khi mà các tiến trình thực thi bị mất kết nối. Hệ thống sử dụng khoá như là [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) cần đảm bảo sẽ giải phóng các bản ghi công việc. Ý tưởng của mô hình này là tất các các công việc cần [có khả năng quay lại][reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), thường đạt đường bằng cách đóng gói các kết quả thành các giao dịch, hoặc tạo ra các toán tử [không thay đổi kết quả nếu đầu vào không thay đổi dù gọi một hay nhiều lần (idempotent)](http://en.wikipedia.org/wiki/Idempotence). +Các tiến trình cũng **có khả năng chống lại các lỗi bất thường**, như các thiết bị phần cứng đột nhiên ngừng hoạt động. Điều này thường ít khi xảy ra hơn là việc ngừng hoạt động linh hoạt với tín hiệu `SIGTERM`, nhưng vẫn có khả năng xảy ra. Cách tiếp cận thường được khuyến nghị là sử dụng cơ chế hàng đợi đằng sau, như là Beanstalkd, các công việc quay trở lại hàng đợi khi mà các kết nối bị ngừng hoặc quá hạn thời gian. Ngoài ra, ứng dụng sử dụng mười hai hệ số được thiết kế để có thể điều khiển các trường hợp ngừng hoạt động đột ngột, ép buộc. [Thiết kế chỉ có đổ vỡ] đem khái niệm này vào [các kết luận logic]](http://docs.couchdb.org/en/latest/intro/overview.html) của nó. diff --git a/content/vi/intro.md b/content/vi/intro.md index d24ad3d55..4e4eaa8dc 100644 --- a/content/vi/intro.md +++ b/content/vi/intro.md @@ -1,9 +1,9 @@ Giới thiệu ========== -Trong thời buổi hiện nay, phần mềm thường được chuyển giao như là một dịch vụ: còn được +Ngày nay, phần mềm thường được chuyển giao như là một dịch vụ: còn được gọi là *các ứng dụng web*, hay *phần mềm-như-một-dịch vụ (software-as-a-service)*. -Ứng dụng 12-hệ số là một phương pháp để xẩy dựng các ứng dụng phần mềm-như-một-dịch vụ với +Ứng dụng 12-hệ số là một phương pháp để xây dựng các ứng dụng phần mềm-như-một-dịch vụ với các tiêu chí sau: * Sử dụng các định dạng theo kiểu **tường thuật** cho việc thiết lập tự động hoá, để @@ -11,8 +11,8 @@ cắt giảm chi phí và thời gian cho lập trình viên mới tham gia dự * Có một **hợp đồng sạch** với hệ điều hành bên dưới, cung cấp **tối đa khả năng dịch chuyển** giữa các môi trường thực thi; * Phù hợp để **triển khai** trên các **nền tảng đám mây** mới, cắt giảm yêu cầu quản trị cho server và hệ thống; -* **Giảm thiểu sự khác nhau** giữa môi trường phát triển và môi trường sản xuất, cho phép -**triển khai liên tục** cho phép tối đa linh hoạt hoá; +* **Giảm thiểu sự khác nhau** giữa môi trường phát triển và môi trường sản xuất, cho phép đạt được sự linh hoạt tối đa +trong **triển khai liên tục**; * Và có thể **mở rộng** mà không cần thay đổi lớn cho các công cụ, kiến trúc, hoặc cách thức phát triển. diff --git a/content/vi/logs.md b/content/vi/logs.md index ab2f4f829..cd82d4a4a 100644 --- a/content/vi/logs.md +++ b/content/vi/logs.md @@ -1,16 +1,16 @@ -## XI. Logs -### Treat logs as event streams +## [XI. Nhật ký](./logs) +### Nhật ký là các luồng sự kiện -*Logs* provide visibility into the behavior of a running app. In server-based environments they are commonly written to a file on disk (a "logfile"); but this is only an output format. +*Nhật ký* cung cấp khả năng thể hiện các hình vi của ứng dụng đang vận hành, trong môi trường máy chủ chúng thường được ghi lại thành các tệp tin trên ổ đĩa cứng (a "logfile"); nhưng chỉ có một định dạng biểu diễn duy nhất. -Logs are the [stream](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating. +Nhật ký như là [luồng](http://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files/) của sự kết hợp, theo trình tự thời gian của các sự kiện, được thu thập từ các luồng ra của các tiến trình đang vận hành và dịch vụ hỗ trợ của ứng dụng. Nhật ký ở dạng nguyên gốc thường là các chuỗi ký tự được định dạng với mỗi sự kiện trên một dòng (mặc dù các truy vết của ngoại lệ thường chia thành nhiều dòng). Nhật ký không có định điểm bắt đầu hay kết thúc, nhưng là luồng liên tục miễn là ứng dụng vẫn đang vận hành. -**A twelve-factor app never concerns itself with routing or storage of its output stream.** It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to `stdout`. During local development, the developer will view this stream in the foreground of their terminal to observe the app's behavior. +**Ứng dụng sử dụng mười hai hệ số không bao giờ quan tâm đến việc điều hướng hay lưu trữ luồng đầu ra.** Ứng dụng không nên ghi hoặc quản lý các logfiles. Thay vào đó, mỗi tiến trình đang vận hành ghi các luồng sự kiện, không có bộ đệm, ra `stdout`. Trong môi trường phát triển cục bộ, lập trình viên sẽ xem các luồng này ở trên thiết bị đầu cuối để nắm bắt được hành vi của ứng dụng. -In staging or production deploys, each process' stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as [Logplex](https://github.com/heroku/logplex) and [Fluent](https://github.com/fluent/fluentd)) are available for this purpose. +Trong quá trình triển khai kiểm thử hoặc kiểm thử, mỗi luồng của tiến trình sẽ được lưu trữ bởi môi trường thực thi, thu tập cùng với tất các các luồng của ứng dụng, và định hướng đến một hoặc nhiều điểm đến cuối cùng để đọc và lưu trữ lâu dài. Các bộ định hướng nhật ký nguồn mở (như là [Logplex](https://github.com/heroku/logplex) và [Fluent](https://github.com/fluent/fluentd)) luôn sẵn sàng cho mục đích này. -The event stream for an app can be routed to a file, or watched via realtime tail in a terminal. Most significantly, the stream can be sent to a log indexing and analysis system such as [Splunk](http://www.splunk.com/), or a general-purpose data warehousing system such as [Hadoop/Hive](http://hive.apache.org/). These systems allow for great power and flexibility for introspecting an app's behavior over time, including: +Luồng sự kiện của ứng dụng có thể định hướng ra các tệp tin, hoặc xem xét thời gian thực ở thiết bị đầu cuối. Hơn nữa, luồng còn có thể được đánh chỉ mục và phân tích bởi hệ thống như là [Splunk](http://www.splunk.com/), hoặc hệ thống phân tích dữ liệu tổng quát như là [Hadoop/Hive](http://hive.apache.org/). Các hệ thống này cung cấp các công cụ mạnh mẽ và linh hoạt cho việc phân tích hành vi của ứng dụng theo thời gian như là: -* Finding specific events in the past. -* Large-scale graphing of trends (such as requests per minute). -* Active alerting according to user-defined heuristics (such as an alert when the quantity of errors per minute exceeds a certain threshold). +* Tìm kiếm các sự kiện đặc biệt trong quá khứ +* Đồ thị hoá xu hướng tổng quát (đồ thị số lượng yêu cầu theo phút) +* Kích hoạt các cảnh báo theo kinh nghiệm của người dùng (như là cảnh báo khi số lượng lỗi theo phút vượt quá ngưỡng nào đó). diff --git a/content/vi/port-binding.md b/content/vi/port-binding.md index 8b3a0407e..ed02cbd9b 100644 --- a/content/vi/port-binding.md +++ b/content/vi/port-binding.md @@ -1,14 +1,14 @@ -## VII. Port binding -### Export services via port binding +## VII. Mở cổng mạng +### Cung cấp các dịch vụ thông qua mở cổng mạng -Web apps are sometimes executed inside a webserver container. For example, PHP apps might run as a module inside [Apache HTTPD](http://httpd.apache.org/), or Java apps might run inside [Tomcat](http://tomcat.apache.org/). +Các ứng dụng web thường được thực thi bên trong một máy chủ web. Ví dụ, ứng dụng PHP có thể thực thi như là một thành phần của [Apache HTTPD](http://httpd.apache.org/), hoặc ứng dụng Java có thể thực thi thông qua [Tomcat](http://tomcat.apache.org/). -**The twelve-factor app is completely self-contained** and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app **exports HTTP as a service by binding to a port**, and listening to requests coming in on that port. +**Ứng dụng áp dụng mười hai-hệ số có khả năng tự đóng gói hoàn toàn chính nó** và không phụ thuộc vào việc tích hợp thêm máy chủ web trong thời gian thực thi vào môi trường thực thi để tạo ra dịch vụ web. Ứng dụng web **cung cấp cơ chế HTTP như là dịch vụ bởi việc mở một cổng nhất định**, và lắng nghe các yêu cầu được gửi tới cổng này. -In a local development environment, the developer visits a service URL like `http://localhost:5000/` to access the service exported by their app. In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes. +Trong môi trường phát triển cục bộ, lập trình viên có thể truy cập dịch vụ thông qua URL như là `http://localhost:5000/` để truy cập đến các dịch vụ được cung cấp bởi ứng dụng của họ. Trong triển khai, lớp điều khiển luồng sẽ điều khiểu các yêu cầu từ đường dẫn công khai thông qua tên máy chủ đến tiến trình cung cấp cổng của ứng dụng. -This is typically implemented by using [dependency declaration](./dependencies) to add a webserver library to the app, such as [Tornado](http://www.tornadoweb.org/) for Python, [Thin](http://code.macournoyer.com/thin/) for Ruby, or [Jetty](http://jetty.codehaus.org/jetty/) for Java and other JVM-based languages. This happens entirely in *user space*, that is, within the app's code. The contract with the execution environment is binding to a port to serve requests. +Việc này thường được triển khai bằng [các định nghĩa ràng buộc](./dependencies) để thêm các thư viện máy chủ cho ứng dụng như là [Tornado](http://www.tornadoweb.org/) cho Python, [Thin](http://code.macournoyer.com/thin/) cho Ruby, hoặc [Jetty](http://jetty.codehaus.org/jetty/) cho Java và các ngôn ngữ dựa trên máy ảo JVM. Điều này được xử lý ở *không gian của người dùng*, hay bên trong mã nguồn của ứng dụng. Ràng buộc đối với môi trường thực thi là việc mở cổng dịch vụ để lắng nghe các yêu cầu. -HTTP is not the only service that can be exported by port binding. Nearly any kind of server software can be run via a process binding to a port and awaiting incoming requests. Examples include [ejabberd](http://www.ejabberd.im/) (speaking [XMPP](http://xmpp.org/)), and [Redis](http://redis.io/) (speaking the [Redis protocol](http://redis.io/topics/protocol)). +HTTP không phải là dịch vụ duy nhất mà có thể cung cấp bởi việc mở cộng mạng. Gần như bất kỳ máy chủ phần mềm nào cũng có thể vận hành như là tiến trình được mở cổng mạng và chờ đợi các yêu cầu được gửi tới. Ví dụ bao gôm [ejabberd](http://www.ejabberd.im/) (sử dụng [XMPP](http://xmpp.org/)), và [Redis](http://redis.io/) (sử dụng [giao thức Redis](http://redis.io/topics/protocol)). -Note also that the port-binding approach means that one app can become the [backing service](./backing-services) for another app, by providing the URL to the backing app as a resource handle in the [config](./config) for the consuming app. +Chú ý là cách tiếp cận bằng mở cổng mạng có nghĩa là ứng dụng có thể trở thành [dịch vụ hỗ trợ(./backing-services) cho bất kỳ ứng dụng nào khác, bằng việc cung cấp URL đến dịch vụ hỡ trợ như là tài nguyên được điều khiển tronng [cấu hình](./config) cho ứng dụng cần sử dụng dịch vụ. diff --git a/content/vi/processes.md b/content/vi/processes.md index dbd86a7c8..b020e5740 100644 --- a/content/vi/processes.md +++ b/content/vi/processes.md @@ -1,15 +1,14 @@ -## VI. Processes -### Execute the app as one or more stateless processes +## VI. Tiến trình +### Vận hành ứng dụng như là một hoặc nhiều tiến trình phi trạng thái -The app is executed in the execution environment as one or more *processes*. +Ứng dụng được vận hành trong môi trường vận hành như là một hoặc nhiều *tiến trình*. -In the simplest case, the code is a stand-alone script, the execution environment is a developer's local laptop with an installed language runtime, and the process is launched via the command line (for example, `python my_script.py`). On the other end of the spectrum, a production deploy of a sophisticated app may use many [process types, instantiated into zero or more running processes](./concurrency). +Trong trường hợp đơn giản, mã nguồn là các kịch bản độc lập, môi trường vận hành chính là máy tính của nhà phát triển với ngôn ngữ thực thi được cài đặt, và tiến trình được khởi chạy thông qua dòng lệnh (ví dụ, `python my_script.py`). Ở một khía cạnh khác, triển khai thực tế của ứng dụng phức tạp có thể sử dụng nhiều [xử lý từ không đến nhiều kiểu tiến trình ngay lập tức](./concurrency). -**Twelve-factor processes are stateless and [share-nothing](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Any data that needs to persist must be stored in a stateful [backing service](./backing-services), typically a database. +**Tiến trình áp dụng mười hai hệ số là phi trạng thái và không chia sẻ bất cứ tài nguyên nào](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Bất kỳ dữ liệu nào cần lưu trữ lâu dài cần được lưu trữ trong [dịch vụ hỗ trợ](./backing-services) đầy đủ trạng thái, thông thường là cơ sở dữ liệu. -The memory space or filesystem of the process can be used as a brief, single-transaction cache. For example, downloading a large file, operating on it, and storing the results of the operation in the database. The twelve-factor app never assumes that anything cached in memory or on disk will be available on a future request or job -- with many processes of each type running, chances are high that a future request will be served by a different process. Even when running only one process, a restart (triggered by code deploy, config change, or the execution environment relocating the process to a different physical location) will usually wipe out all local (e.g., memory and filesystem) state. +Không gian bộ nhớ hoặc hệ thống tệp tin của tiến trình có thể được sử dụng như là bộ đệm tạm thời, thông qua luồng xử lý duy nhất. Ví dụ, việc tải một tệp tin lớn, tiến trình tải xuống và lưu trữ kết quả của tiến trình được lưu trữ trong cơ sở dữ liệu. Ứng dụng theo mười hai hệ số không bao giờ giả sử rằng có bất cứ cơ chế đệm nào của bộ nhớ hay ổ đĩa cứng sẵn sàng cho các yêu cầu hoặc công việc trong tương lai -- với nhiều tiến trình mà mỗi kiểu vận hành, mà tỷ cao các yêu cầu trong tương lai được xử lý bởi tiến trình khác. Mặc dù chỉ chạy một tiến trình, việc khởi động lại (được kích hoạt bởi mã nguồn triển khai, thay đổi cấu hình hoặc môi trường thực thi được thay đổi lại đến một tài nguyên vật lý khác), thường sẽ loại bỏ toàn bộ trạng thái cục bộ (như là bộ nhớ và hệ thống tệp tin). -Asset packagers (such as [Jammit](http://documentcloud.github.com/jammit/) or [django-compressor](http://django-compressor.readthedocs.org/)) use the filesystem as a cache for compiled assets. A twelve-factor app prefers to do this compiling during the [build stage](./build-release-run), such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), rather than at runtime. - -Some web systems rely on ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- that is, caching user session data in memory of the app's process and expecting future requests from the same visitor to be routed to the same process. Sticky sessions are a violation of twelve-factor and should never be used or relied upon. Session state data is a good candidate for a datastore that offers time-expiration, such as [Memcached](http://memcached.org/) or [Redis](http://redis.io/). +Bộ đóng gói tài nguyên (như [Jammit](http://documentcloud.github.com/jammit/) hoặc [django-compressor](http://django-compressor.readthedocs.org/)) sử dụng hệ thống tệp tin như là bộ đệm cho việc biên dịch các tài nguyên. Ứng dụng sử dụng mười hai hệ số thường thực thi việc biên dịch này trong [bước xây dựng](./build-release-run), như [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), hơn là ở bước vận hành. +Một vài hệ thống web dựa vào ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- đó là cơ chế lưu trữ tạm thời các dữ liệu của người dùng theo phiên làm việc trong bộ nhớ của các tiến trình vận hành ứng dụng và trông đợi các yêu cầu từ cùng một người dùng được định hướng tới cùng tiến trình. *Sticky sessions* đã vi phạm nguyên tắc của mười hai hệ số và không nên được sử dụng hoặc áp dụng theo. Dữ liệu trạng thái của các phiên làm việc là nên được lưu trữ trong các nơi lưu trữ cung cấp khả năng hết hạn theo thời gian như là [Memcached](http://memcached.org/) hoặc [Redis](http://redis.io/). diff --git a/content/vi/toc.md b/content/vi/toc.md index adc493d6f..9cdaf0ac7 100644 --- a/content/vi/toc.md +++ b/content/vi/toc.md @@ -4,35 +4,35 @@ ## [I. Mã gốc](./codebase) ### Một mã gốc được theo dõi với hệ thống quản lý phiên bản, và nhiều lần triển khai -## [II. Dependencies](./dependencies) -### Explicitly declare and isolate dependencies +## [II. Các phụ thuộc](./dependencies) +### Khai báo rõ ràng và phân tách các phụ thuộc -## [III. Config](./config) -### Store config in the environment +## [III. Cấu hình](./config) +### Lưu trữ cấu hình trong môi trường -## [IV. Backing Services](./backing-services) -### Treat backing services as attached resources +## [IV. Dịch vụ hỗ trợ](./backing-services) +### Dịch vụ hỗ trợ như là tài nguyên bổ xung -## [V. Build, release, run](./build-release-run) -### Strictly separate build and run stages +## [V. Xây dựng, phát hành, vận hành](./build-release-run) +### Tách biệt hoàn toàn giữa bước xây dựng và vận hành -## [VI. Processes](./processes) -### Execute the app as one or more stateless processes +## [VI. Tiến trình](./processes) +### Vận hành ứng dụng như là một hoặc nhiều tiến trình phi trạng thái -## [VII. Port binding](./port-binding) -### Export services via port binding +## [VII. Mở cổng mạng](./port-binding) +### Cung cấp các dịch vụ thông qua công mạng -## [VIII. Concurrency](./concurrency) -### Scale out via the process model +## [VIII. Đồng bộ](./concurrency) +### Mở rộng theo chiều ngang thông qua mô hình tiến trình -## [IX. Disposability](./disposability) -### Maximize robustness with fast startup and graceful shutdown +## [IX. Tính khả dụng](./disposability) +### Tối ưu hoá với khởi động nhanh và dừng phần mềm ổn định -## [X. Dev/prod parity](./dev-prod-parity) -### Keep development, staging, and production as similar as possible +## [X. Sự tương đồng giữa quá trình phát triển và vận hành thực tế](./dev-prod-parity) +### Đảm bảo sự tương đồng giữa môi trường phát triển, kiểm thử và thực tế -## [XI. Logs](./logs) -### Treat logs as event streams +## [XI. Nhật ký](./logs) +### Nhật ký là các luồng sự kiện -## [XII. Admin processes](./admin-processes) -### Run admin/management tasks as one-off processes +## [XII. Tiến trình quản trị](./admin-processes) +### Thực thi nhiệm vụ quản trị như là một tiến trình diff --git a/content/vi/who.md b/content/vi/who.md index 4dedf8cc2..8e2dc2753 100644 --- a/content/vi/who.md +++ b/content/vi/who.md @@ -1,5 +1,5 @@ Ai nên đọc tài liệu này? ======================== -Bất kì lập trình viên đang xây dựng các ứng dụng chạy như là một dịch vụ. Các kỹ sữ hệ +Bất kì lập trình viên đang xây dựng các ứng dụng-như-một-dịch vụ. Các kỹ sư hệ thống đảm nhiệm triển khai hoặc quản lý các ứng dụng. diff --git a/locales/vi.yml b/locales/vi.yml index b66801279..d07b54091 100644 --- a/locales/vi.yml +++ b/locales/vi.yml @@ -4,4 +4,4 @@ vi: # A text to make known that the article is a translation not an original. # Empty for English, original. - translation: "(Tiếng Việt)" + translation: "Đây là bản dịch." From 95b1cfa741dbf4f2d4dc96cf8f7858933a6b5c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Schr=C3=B6der?= Date: Tue, 3 Dec 2019 15:54:32 +0100 Subject: [PATCH 448/472] Fix small typo --- content/de/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/de/processes.md b/content/de/processes.md index 2c339b42e..93a484656 100644 --- a/content/de/processes.md +++ b/content/de/processes.md @@ -7,7 +7,7 @@ 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 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. +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, dass 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 diese Art von Kompilation eher in der [Build-Phase](./build-release-run) erledigen anstatt zur Laufzeit. From ef83576df7a9c8e0df2cb943d21d605148c68ef6 Mon Sep 17 00:00:00 2001 From: Thiago Bittencourt Date: Mon, 11 Nov 2019 15:14:22 -0300 Subject: [PATCH 449/472] Fixing pt-br translations Translated the title of topic V and a word in topic X content --- content/pt_br/dev-prod-parity.md | 2 +- content/pt_br/toc.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt_br/dev-prod-parity.md b/content/pt_br/dev-prod-parity.md index 8cb0b6868..e54f5a332 100644 --- a/content/pt_br/dev-prod-parity.md +++ b/content/pt_br/dev-prod-parity.md @@ -67,7 +67,7 @@ Resumindo o acima em uma tabela: -Desenvolvedores as vezes vem uma grande vantagem em usar um serviço de apoio leve em seus ambientes, enquanto um serviço de apoio mais sério e robusto seria usado em produção. Por exemplo, usando SQLite localmente e PostgreSQL em produção; ou memória de processo local para caching em desenvolvimento e Memcached em produção. +Desenvolvedores as vezes veem uma grande vantagem em usar um serviço de apoio leve em seus ambientes, enquanto um serviço de apoio mais sério e robusto seria usado em produção. Por exemplo, usando SQLite localmente e PostgreSQL em produção; ou memória de processo local para caching em desenvolvimento e Memcached em produção. **O desenvolvedor doze-fatores resiste a tentação de usar diferentes serviços de apoio entre desenvolvimento e produção**, mesmo quando adaptadores teoricamente abstraem as diferenças dos serviços de apoio. Diferenças entre serviços de apoio significam que pequenas incompatibilidades aparecerão, fazendo com que código que funcionava e passava em desenvolvimento ou homologação, falhe em produção. Tais tipos de erros criam fricção que desincentivam deploy contínuo. O custo dessa fricção e do subsequente decaimento de deploy contínuo é extremamente alto quando considerado que vai acumular no tempo de vida da aplicação. diff --git a/content/pt_br/toc.md b/content/pt_br/toc.md index caf3e9be2..d57d599c0 100644 --- a/content/pt_br/toc.md +++ b/content/pt_br/toc.md @@ -13,7 +13,7 @@ Os Doze Fatores ## [IV. Serviços de Apoio](./backing-services) ### Trate os serviços de apoio, como recursos ligados -## [V. Build, release, run](./build-release-run) +## [V. Construa, lance, execute](./build-release-run) ### Separe estritamente os builds e execute em estágios ## [VI. Processos](./processes) From 66e7a0fc1abde0c6b7154e5d722e2014af25a1f0 Mon Sep 17 00:00:00 2001 From: Arthur Aukhatov Date: Tue, 17 Dec 2019 10:22:35 +0300 Subject: [PATCH 450/472] Paraphrase 10th principle in Russian language --- content/ru/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ru/dev-prod-parity.md b/content/ru/dev-prod-parity.md index 3983385fa..8dde29b41 100644 --- a/content/ru/dev-prod-parity.md +++ b/content/ru/dev-prod-parity.md @@ -1,4 +1,4 @@ -## X. Паритет разработки/работы приложения +## X. Паритет окружений разработки и продуктива (Dev/prod parity) ### Держите окружения разработки, промежуточного развёртывания (staging) и рабочего развёртывания (production) максимально похожими Исторически существуют значительные различия между разработкой (разработчик делает живые изменения на локальном [развёртывании](./codebase) приложения) и работой приложения (развёртывание приложения с доступом к нему конечных пользователей). Эти различия проявляются в трёх областях: From 457bc054380d687cf7e6748f6e434dc85064cd1e Mon Sep 17 00:00:00 2001 From: johnakos Date: Tue, 17 Mar 2020 19:34:05 +0200 Subject: [PATCH 451/472] Update codebase.md --- content/el/codebase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/el/codebase.md b/content/el/codebase.md index 714c3ae85..05a738785 100644 --- a/content/el/codebase.md +++ b/content/el/codebase.md @@ -14,5 +14,5 @@ Υπάρχει μόνο μία βάση κώδικα ανά εφαρμογή, αλλά θα υπάρξουν πολλές αναπτύξεις της εφαρμογής. Μια *ανάπτυξη* (*deploy*) της εφαρμογής, είναι μία εκτελούμενη ενσάρκωση της εφαρμογής. Αυτό τυπικά είναι μία τοποθεσία παραγωγής (production site), και μία ή περισσότερες τοποθεσίες ελέγχου (staging sites). Επιπλέον, κάθε προγραμματιστής έχει ένα αντίγραφο της εφαρμογής εκτελούμενο τοπικά στο περιβάλλον του, το οποίο επίσης συνιστά μια ανάπτυξη. -Η βάση κώδικα είναι η ίδια για όλες τις αναπτύξεις, παρόλαυτά διαφορετικές εκδόσεις κώδικα μπορεί να είναι ενεργές ανά ανάπτυξη. Για παράδειγμα, ο προγραμματιστής έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην τοποθεσία ελέγχου, η τοποθεσία ελέγχου έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην παραγωγή. Αλλά όλα μοιράζονται την ίδια βάση κώδικα, έτσι μπορούν να ταυτοποιηθούν ως διαφορετικές αναπτύξεις της ίδιας εφαρμογήε. +Η βάση κώδικα είναι η ίδια για όλες τις αναπτύξεις, παρόλαυτά διαφορετικές εκδόσεις κώδικα μπορεί να είναι ενεργές ανά ανάπτυξη. Για παράδειγμα, ο προγραμματιστής έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην τοποθεσία ελέγχου, η τοποθεσία ελέγχου έχει κάποιες αλλαγές που δεν έχουν ακόμα κατατεθεί στην παραγωγή. Αλλά όλα μοιράζονται την ίδια βάση κώδικα, έτσι μπορούν να ταυτοποιηθούν ως διαφορετικές αναπτύξεις της ίδιας εφαρμογής. From 9ddbe57571b5972df1f4d852a79df40c57c13e5e Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 28 Oct 2019 14:53:11 +0100 Subject: [PATCH 452/472] emphase **declarative** & **continuous deployment** As in the original (-: --- content/fr/intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/fr/intro.md b/content/fr/intro.md index 4aeeaa6f8..d7d220cf4 100644 --- a/content/fr/intro.md +++ b/content/fr/intro.md @@ -3,10 +3,10 @@ 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; +* 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; +* **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.) From 56caff950cdfca9ea41bc3a71208f6e62ca9ec38 Mon Sep 17 00:00:00 2001 From: Jan Gabriel Date: Mon, 17 Feb 2020 22:42:20 +0100 Subject: [PATCH 453/472] czech version --- content/cs/admin-processes.md | 14 ++++++ content/cs/background.md | 8 ++++ content/cs/backing-services.md | 14 ++++++ content/cs/build-release-run.md | 19 +++++++++ content/cs/codebase.md | 18 ++++++++ content/cs/concurrency.md | 14 ++++++ content/cs/config.md | 22 ++++++++++ content/cs/dependencies.md | 12 ++++++ content/cs/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/cs/disposability.md | 15 +++++++ content/cs/intro.md | 12 ++++++ content/cs/logs.md | 16 +++++++ content/cs/port-binding.md | 14 ++++++ content/cs/processes.md | 14 ++++++ content/cs/toc.md | 38 +++++++++++++++++ content/cs/who.md | 4 ++ locales/cs.yml | 7 +++ 17 files changed, 317 insertions(+) create mode 100644 content/cs/admin-processes.md create mode 100644 content/cs/background.md create mode 100644 content/cs/backing-services.md create mode 100644 content/cs/build-release-run.md create mode 100644 content/cs/codebase.md create mode 100644 content/cs/concurrency.md create mode 100644 content/cs/config.md create mode 100644 content/cs/dependencies.md create mode 100644 content/cs/dev-prod-parity.md create mode 100644 content/cs/disposability.md create mode 100644 content/cs/intro.md create mode 100644 content/cs/logs.md create mode 100644 content/cs/port-binding.md create mode 100644 content/cs/processes.md create mode 100644 content/cs/toc.md create mode 100644 content/cs/who.md create mode 100644 locales/cs.yml diff --git a/content/cs/admin-processes.md b/content/cs/admin-processes.md new file mode 100644 index 000000000..f1020acbb --- /dev/null +++ b/content/cs/admin-processes.md @@ -0,0 +1,14 @@ +## XII. Admin procesy +### Spouštějte administrativní úlohy jako jednorázové procesy. + +[Formace procesů](./concurrency) je sada procesů, které aplikace používá pro svůj běh (jako je například obsluha příchozích požadavků). Kromě toho potřebují vývojáři často spouštět i jednorázové administrativní nebo úlohy údržby, jako například: + +* Spuštění databázové migrace (jako `manage.py migrate` v Django, `rake db:migrate` v Rails). +* Spuštění konzole (známé také jako [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) pro vykonání libovolného kódu nebo k prohlížení aplikačních modelů v živé databázi. Většina jazyků poskytuje REPL spuštěním interpreteru bez argumentů (kupříkladu `python` nebo `perl`) nebo v některých případech samostatným příkazem (jako `irb` u Ruby, `rails console` pro Rails). +* Spuštění jednorázových skriptů uložených v repozitáři aplikace (například `php scripts/fix_bad_records.php`). + +Jednorázové administrativní procesy by měly být spouštěny ve stejném prostředí jako běžné [dlouho běžící procesy](./processes) aplikace. Běží proti [vydání](./build-release-run) za použití stejného [kódu](./codebase) a [konfigurace ](./config) jako ostatní procesy daného vydání. Administrativní kód musí být dodáván spolu s aplikací, aby se zabránilo problémům se synchronizací. + +Stejné techniky [izolace závislostí](./dependencies) by měli být použity na všechny typy procesů. Například, pokud Ruby webový proces používá příkaz `bundle exec thin start`, tak databázová migrace by měla používat `bundle exec rake db:migrate`. Obdobně by pak měl program v Pythonu, využívající Virtualenv, používat přibalený `bin/python` pro spouštění jak Tornado webserveru, tak i pro spouštění `manage.py` administrativního procesu. + +Twelve-factor metodika silně preferuje jazyky, které poskytují REPL shell v základu a umožňují tak snadno spouštět jednorázové skripty. V lokálním nasazení spouštějí vývojáři jednorázový administrativní proces příkazem přímo v shellu unvnitř repozitáže. V produkčním nasazení mohou vývojáři použít SSH nebo jiný způsob vzdáleného spouštění příkazů, který je v daném nasazení pro spouštění procesů k dispozici. diff --git a/content/cs/background.md b/content/cs/background.md new file mode 100644 index 000000000..1886b2dca --- /dev/null +++ b/content/cs/background.md @@ -0,0 +1,8 @@ +Pozadí +========== + +Přispěvatelé tohoto dokumentu se přímo podíleli na vývoji a nasazení stovek aplikací a byli svědky vývoje, provozu a škálování stovek tisíc aplikací prostřednictvím své práce na platformě Heroku. + +Tento dokument shromažďuje všechny naše zkušenosti a postřehy týkající se široké škály aplikací typu software-as-a-service v divočině. Jedná se o sadu ideálních postupů pro vývoj aplikací se zvláštní pozorností věnovanou dynamice organického růstu aplikace v průběhu času, dynamice spolupráce mezi vývojáři pracujícími na kódu aplikace a vyhýbání se nákladům na erozi softwaru. + +Naší motivací je zvyšovat povědomí o některých systémových problémech, které jsme zaznamenali v moderním vývoji aplikací, poskytnout společnou slovní zásobu pro diskusi o těchto problémech a nabídnout rozsáhlou sadu koncepčních řešení těchto problémů s doprovodnou terminologií. Formát je inspirován knihami Martina Fowlera *Patterns of Enterprise Application Architecture* a *Refactoring*. diff --git a/content/cs/backing-services.md b/content/cs/backing-services.md new file mode 100644 index 000000000..b7168ea73 --- /dev/null +++ b/content/cs/backing-services.md @@ -0,0 +1,14 @@ +## IV. Backing services +### Nakládejte s podpůrnými službami jako s připojenými zdroji. + +*Podpůrná* služba je jakákoliv služba, kterou aplikace konzumuje přes síť jako součást svého normálního běhu. Příklady zahrnují databáze (jako například [MySQL](http://dev.mysql.com/) nebo [CouchDB](http://couchdb.apache.org/)), messaging/queueing systémy (jako jsou [RabbitMQ](http://www.rabbitmq.com/) nebo [Beanstalkd](https://beanstalkd.github.io)), SMTP služby pro odchozí emaily (jako [Postfix](http://www.postfix.org/)) a cachovací systémy (jako je [Memcached](http://memcached.org/)). + +Podpůrné služby, jako například databáze, jsou obvykle spravovány stejnými systémovými inženýri jako samotné nasazení aplikace. K těmto lokálně spravovaným službám může aplikace navíc využívat služby provozované a spravované třetí stranou. To mohou být například SMTP služby (jako je [Postmark](http://postmarkapp.com/)), služby na sbírání metrik (jako [New Relic](http://newrelic.com/) nebo [Loggly](http://www.loggly.com/)), datová uložistě (jako [Amazon S3](http://aws.amazon.com/s3/)) a dokonce i služby přístupné přes API (jako jsou například [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) nebo [Last.fm](http://www.last.fm/api)). + +**Kód twelve-factor aplikace nedělá rozdíly mezi lokální službou a službou třetí strany.** Z pohledu aplikace jsou to připojené zdroje přístupné přes URL nebo jiné přístupové/přihlašovací údaje uložené v [konfiguraci](./config). Nasazení twelve-factor aplikace by mělo být schopné vyměnit lokální MySQL databázi za databázi spravovanou třetí stranou (jako je například [Amazon RDS](http://aws.amazon.com/rds/)) bez jakýchkoliv změn v aplikačním kódu. Obdobně může být lokální SMTP server nahrazen SMTP službou třetí strany (jako Postmark) bez změn v kódu. V obou případech se změní pouze přístupové a přihlašovací údaje v konfiguraci. + +Každá podpůrná služba je *zdroj*. Například MySQL databáze je zdroj, dvě MySQL databáze (použité pro sharding na aplikační úrovni) kvalifikujeme jako dva různé zdroje. Twelve-factor aplikace nakládá s těmito databázemi jako *připojenými zdroji*, což naznačuje i jejich volné spojení se souvisejícím nasazením. + +Produkční nasazení připojené k podpůrným službám. + +Zdroje je možné připojovat a odpojovat z nasazení dle libosti. Například pokud je databáze z důvodu hardwarových problémů nestabilní, systémový inženýr může rozběhnout nový databázový server z aktuální zálohy. Aktuální produkční databáze pak může být odpojena a nová databáze připojena na její místo, vše beze změn v kódu. diff --git a/content/cs/build-release-run.md b/content/cs/build-release-run.md new file mode 100644 index 000000000..7a75ccf08 --- /dev/null +++ b/content/cs/build-release-run.md @@ -0,0 +1,19 @@ +## V. Sestavení, vydání, spuštění +### Striktně oddělte fáze sestavení, vydání a spuštění. + +[Zdrojový kód](./codebase) je transformován do (nevývojářského) nasazení ve třech fázích: + +* Fáze *sestavení (build)* je transformace, která převede zdrojový kód do spustitelného balíčku zvaného *sestavení*. Z verze kódu v čase příslušného commitu a dle postupu nasazení, dojde ve fázi sestavení ke stažení [závislostí](./dependencies), zkompilování binárek a připojení assetů. +* Fáze *vydání (release)* vezme sestavení vytvořené v předchozím kroku a zkombinuje ho [konfigurací](./config) pro dané nasazení. Výsledná kombinace je *vydáním*, které je připravené k okamžitému spuštění v běhovém prostředí. +* Fáze *spuštění (run)* (známá též jako "runtime") spustí aplikaci v běhovém prostředí nastartováním aplikačních [procesů](./processes) oproti danému vydání. + +![Kód se stane sestavením, které v kombinaci s příslušnou konfigurací tvoří vydání.](/images/release.png) + +**Twelve-factor aplikace striktně rozlišují mezi fází sestavení, vydání a spuštění.** Je například nemožné provedět změny ve spuštěném kódu, protože není cesty, jak tyto změny propagovat zpět do fáze sestavení. + +Nástroje pro nasazení obvykle poskytují i správu vydání a zejména pak schopnost vrátit se zpět k předchozímu vydání. Například nástroj [Capistrano](https://github.com/capistrano/capistrano/wiki) si ukládá nasazení v podadresáři zvaném `releases` a aktuální vydání je pak symlink na příslušný adresář s aktuální verzí. Příkaz `rollback` pak velmi snadno zajistí návrat k předchozímu vydání. + +Každé vydaní by mělo mít vždy unikátní ID, jako je například časová značka ( `2011-04-06-20:32:17`) nebo inkrementální číslo (například `v100`). Vydání již nelze po vytvoření jakkoliv upravovat, libovolná změna musí vždy vytvořit nové vydání. + +Sestavení iniciují vývojáři aplikace, kdykoliv se nasazuje nový kód. Naopak ke spuštění v běhovém prostředí může dojít automaticky v případě restartu serveru nebo restartem havarovaného procesu pomocí správce procesů. Proto by měla mít fáze spuštění co nejméně pohyblivých částí, jelikož problémy bránící aplikaci v běhu mohou nastat uprostřed noci, kdy nejsou žádní vývořáji k dispozici. Fáze sestavení pak může být složitější, protože chyby jsou více na očích pro vývojáře kontrolující nasazení aplikace. + diff --git a/content/cs/codebase.md b/content/cs/codebase.md new file mode 100644 index 000000000..fbe6f75a2 --- /dev/null +++ b/content/cs/codebase.md @@ -0,0 +1,18 @@ +## I. Zdrojový kód +### Mějte jeden zdrojový kód ve verzovacím systému a mnoho nasazení. + +Twelve-factor aplikace je vždy sledována ve verzovacím systému, jako je například [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/) nebo [Subversion](http://subversion.apache.org/). Kopie verzovací databáze se nazývá *kódový repozitář*, často zkracováno jako *repozitář* nebo jen *repo*. + +*Zdrojový kód* je jakýkoliv repozitář (v centralizovaném verzovacím systému jako je Subversion), nebo jakákoliv skupina repozitářů, které mají společný kořenový commit (v decentralizovaném verzovacím systému jako je Git). + +![Jeden zdrojový kód má mnoho nasazení](/images/codebase-deploys.png) + +Vždy existuje korelace jedna-ku-jedné mezi zdrojovým kódem a aplikací: + +* Pokud existuje více zdrojových kódů, nejedná se o aplikaci, ale o distribuovaný systém. Každá komponenta distibuovaného systému je dílčí aplikace, která může samostatně podléhat twelve-factor metodice. +* Více aplikací sdílejících stejný kód je porušení twelve-factor metodiky. Řešením je oddělení sdíleného kódu do knihovny, která se připojí pomocí [systému na správu závislostí](./dependencies). + +Každá aplikace má pouze jeden zdrojový kód, ale nasazení jedné aplikace bude vícero. *Nasazení* je běžící instance aplikace. Typicky je to produkční web a jeden nebo více testovacích webů. Každý vývojář má navíc lokální vývojovou kopii běžící aplikace, každou takovou kopii lze také považovat za nasazení. + +Zdrojový kód je stejný ve všech nasazeních, v každém nasazení však mohou být aktivní různé verze. Například vývojář má několik commitů, které ještě nejsou nasazeny v testovacím prostředí a na testovacím prostředí jsou commity, které zatím nejsou na produkci. Všechny verze však sdílejí jeden zdrojový kód a dá se tedy říct, že jsou různými nasazeními téže aplikace. + diff --git a/content/cs/concurrency.md b/content/cs/concurrency.md new file mode 100644 index 000000000..65baefe08 --- /dev/null +++ b/content/cs/concurrency.md @@ -0,0 +1,14 @@ +## VIII. Souběh +### Škálujte do šířky použitím proces modelu. + +Každý počítačový program se po spuštění prezentuje jako jeden nebo více procesů. Webové aplikace mají různé formy vykonávání procesů. Například PHP procesy běží jako potomci Apache procesu, spouštěné na požádání dle množství požadavků. Java procesy mají opačný přístup, kde JVM poskytuje jeden masivní super proces, který si po spuštění vyhradí velké množství systémovývh požadavků (CPU a paměti) a souběh si řídí interně pomocí vláken. V obou případech jsou běžící procesy jen málo viditelné pro vývojáře aplikace. + +![Škálování je vyjádřeno běžícími procesy, různorodost funkcionality pak typy procesů.](/images/process-types.png) + +**Ve twelve-factor aplikaci jsou procesy prominentními občany.** Procesy twelve-factor aplikace čerpají inspiraci z [unixového proces modelu pro démony služeb](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Použitím tohoto modelu může vývojář navrhnout aplikaci tak, aby různou práci vykonávaly různé typy procesů. Například HTTP požadavky může obsluhovat webový proces a dlouho běžící procesy na pozadí může obstarat worker proces. + +To nevylučuje, že si jednotlivé procesy nemohou spravovat interní multiplexování přes vlákna nebo pomocí async/event modelu, jako je tomu v [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) nebo [Node.js](http://nodejs.org/). Jednotlivé VM však mohou růst jen omezeně (vertikální škálování), aplikace tedy musí být schopná i běhu v několika procesech na více fyzických strojích. + +Proces model obvzlášť vyniká, když přijde čas na škálování. [Nesdílená a horizontálně dělitelná podstata procesů twelve-factor aplikace](./processes) znamená, že přidání větší souběžnosti je jednoduchá a spolehlivá operace. Sada typu procesů a množství procesů každého typu se nazývá *formace procesů*. + +Procesy twelve-factor aplikace by [nikdy neměly démonizovat](http://dustin.github.com/2010/02/28/running-processes.html) nebo zapisovat PID soubory. Namísto toho by se měly spoléhat na správce procesů operačního systému (jako je například [systemd](https://www.freedesktop.org/wiki/Software/systemd/), správce distribuovaných procesů na cloudové platformě nebo nástroje typu [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) během vývoje), který obstará [výstupní proudy](./logs), reakci na havarované procesy a obsluhu uživatelem vyvolaných restartů a zastavení. diff --git a/content/cs/config.md b/content/cs/config.md new file mode 100644 index 000000000..cdf66b99d --- /dev/null +++ b/content/cs/config.md @@ -0,0 +1,22 @@ +## III. Konfigurace +### Konfigurace ukládejte do prostředí. + +*Konfigurace* aplikace je všechno, co se liší mezi [nasazeními](./codebase) (testovací, produkční, vývojové prostředí, atd.). To zahrnuje: + +* Přihlašovací údaje k databázím, Memcached a dalším [podpůrným službám](./backing-services). +* Přístupové údaje k externím službám jako je Amazon S3 nebo Twitter. +* Specifické hodnoty pro dané nasazení jako například kanonické názvy hostitelů. + +Aplikace si někdy ukládají konfiguraci jako konstanty v kódu. To je porušení twelve-factor metodiky, která vyžaduje **přísné oddělení konfigurace od kódu**. Konfigurace se mezi nasazeními značně liší, kód však nikoliv. + +Test lakmusovým papírkem na správné oddělení konfigurace od kódu je fakt, že aplikace by mohla být kdykoliv uvolněna jako open source bez kompromitace přístupových údajů. + +Nutno podotknout, že do definice "konfigurace" *nepatří* interní nastavení aplikace jako je například `config/routes.rb` v Rails nebo nastavení [propojení základních modulů](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) ve [Springu](http://spring.io/). Tento typ konfigurace se neliší mezi nasazeními a je nejlepší ho ponechat v kódu. + +Další možností jak přistupovat ke konfiguracím je mít konfigurační soubory, které nejsou uložené ve verzovacím systému, jak je tomu například u `config/database.yml` v Rails. To je obrovské zlepšení oproti konstantám uloženým v repozitáři, tento přístup má však stále několik slabin: je velmi jednoduché omylem uložit tento soubor do repozitáře; chtě nechtě jsou tyto soubory obvykle rozmístěny na několika místech a v různých formátech, což komplikuje jejich centrální správu. Navíc jsou tyto konfigurační soubory často specifické pro daný jazyk či framework. + +**Twelve-factor aplikace ukládají konfiguraci do proměnných prostředí** (často zkracováno jak *env vars* nebo *env*). Proměnné prostředí se dají jednoduše měnit mezi nasazeními bez zásahu do kódu. Oproti konfiguračním souborům je zde velmi malá šance, že by byly omylem uloženy do repozitáře a narozdíl od vlastních konfiguračních souborů a jiných konfiguračních mechanismů, jako například Java System Properties, jsou nezávislé na jazyce a operačním systému. + +Dalším úskalím správy konfigurace je seskupování. Aplikace někdy seskupují konfigurace do pojmenovaných skupin (často nazývaných jako "prostředí"), rozlišených podle specifického nasazení, jako například `vývojové`, `testovací` nebo `produkční` prostředí. Tento přístup lze jen velmi težko čistě škálovat. Jak přibývají nasazení jsou zapotřebí nová prostředí, jako například `staging` nebo `qa`. Jakmile projekt začne narůstat, vývojáři přidávají svoje specifická prostředí jako třeba `joes-staging`, což má za následek kombinatorickou explozi konfigurací a správa nasazení se tak stáva velmi delikátní záležitostí. + +Ve twelve-factor aplikaci jsou proměnné prostředí jako vzájemně nezávislé ovládací prvky. Ty nejsou nikdy seskupovány do "prostředí", namísto toho jsou všechny spravovány nezávisle pro každé nasazení. Tento model plynule škáluje s přirozeně se rozrůstající aplikací a narůstajícím počtem nasazení během celého životního cyklu aplikace. diff --git a/content/cs/dependencies.md b/content/cs/dependencies.md new file mode 100644 index 000000000..5f989da32 --- /dev/null +++ b/content/cs/dependencies.md @@ -0,0 +1,12 @@ +## II. Závislosti +### Explicitně deklarujte a izololujte závislosti. + +Většina programovacých jazyků poskytuje balíčkovací systém pro distribuci podpůrných knihoven, například [CPAN](http://www.cpan.org/) pro Perl nebo [Rubygems](http://rubygems.org/) pro Ruby. Knihovny instalované skrze balíčkovací systém mohou být instalovány globálně pro celý systém (nazýváme "site packages") nebo pouze lokálně v rámci adresáře dané aplikace (nazýváme "vendoring" nebo "bundling"). + +**Twelve-factor aplikace se nikdy nespoléhá na implicitní existenci globálních systémových balíčků.** Svoje závislosti deklaruje úplně a přesně pomocí manifestu *deklarovaných závislostí*. Dále používá nástroje pro *izolaci závislostí*, aby bylo zajištěno, že při běhu aplikace žádné implicitní zavislosti neprosakují z okolního systému. Úplná explicitní deklarace závislostí je použita jednotně pro produkci i vývoj. + +Například [Bundler](https://bundler.io/) pro Ruby poskytuje `Gemfile` manifest formát pro deklaraci závislostí a `bundle exec` pro izolaci závislostí. Pro Python jsou to dva rozdílné nástroje, [Pip](http://www.pip-installer.org/en/latest/) je použit pro deklaraci závislostí a [Virtualenv](http://www.virtualenv.org/en/latest/) pro jejich izolaci. Dokonce i C má [Autoconf](http://www.gnu.org/s/autoconf/) pro deklaraci závislostí a statické linkování poskytuje izolaci závislostí. Nehledě na použitou sadu nástrojů, deklarace a izolace závislostí musí být vždy aplikovány společně, použití pouze jednoho nebo pouze druhého není dostatečné pro splnění podmínek twelve-factor metodiky. + +Jednou z výhod explicintní deklarace závislostí je to, že zjednodušuje počáteční rozběhnutí aplikace pro nové vývojáře. Nový vývojář si jen naklonuje repozitář aplikace do svého vývojového prostředí a jako prerekvizity mu postačí nainstalované běhové prostředí jazyka a příslušný správce závislostí. Vše potřebné pro rozběhnutí aplikace se zajistí deterministicky *build příkazem* . Například, build příkaz pro Ruby/Bundler je `bundle install`, pro Cloujure/[Leiningen](https://github.com/technomancy/leiningen#readme) je to `lein deps`. + +Twelve-factor aplikace se nespoléhají na implicitní existenci jakýchkoli systémových nástrojů. Příkladem může být spouštění ImageMagick nebo `curl` přes shell. I když tyto nástroje existují na mnoha a možná i většině aktuálně používaných systémů, neexistuje žadná záruka, že tyto nástroje budou existovat na systémech, kde aplikace poběží v budoucnu a nebo že budou na budoucích systémech dostupné v kompatibilní verzi. Pokud aplikace potřebuje spouštět nějaký nástroj přes shell, tak by měl být daný nástroj součástí aplikace. \ No newline at end of file diff --git a/content/cs/dev-prod-parity.md b/content/cs/dev-prod-parity.md new file mode 100644 index 000000000..ffd3b7549 --- /dev/null +++ b/content/cs/dev-prod-parity.md @@ -0,0 +1,76 @@ +## X. Podobnost Vývoj/Produkce +### Udržujte si co nejmenší rozdíly mezi vývojovým, testovacím a produkčním prostředím. + +Historicky byly vždy velké rozdíly mezi vývojovým (vývojář provádí změny v lokálním nasazení [zdrojového kódu](./codebase)) a produkčním prostředím (běžící nasazení aplikace přístupné koncovým uživatelům). To se projevuje jako mezery v těchto oblastech: + +* **Časová mezera**: Vývojář může pracovat na kódu, který se dostane na produkci až za několik dnů, týdnů nebo i měsíců. +* **Personální mezera**: Vývojáři píší kód, systémoví inženýři ho nasazují. +* **Nástrojová mezera**: Vývojáři mohou používat Nginx, SQLite a OS X, přitom na produkci běží Apache, MySQL a Linux. + +**Twelve-factor aplikace je navržena pro [průběžné nasazování](http://avc.com/2011/02/continuous-deployment/) tak, že si udržuje jen minimální rozdíly mezi vývojovým a produkčním prostředím.** Podíváme-li se na předchozí mezery touto optikou: + +* Zmenšování časové mezery: Vývojář napíše kód a nasadí ho v řádu hodin či dokonce minut. +* Zmenšování personální mezery: Vývojáři píšící kód jsou úzce zapojeni do nasazení a sledují jeho chování na produkci. +* Zmenšování nástrojové mezery: Udržujeme co nejmenší rozdíly mezi vývojovým a produkčním prostředím. + +Souhrn výše popsaného v tabulce: + + + + + + + + + + + + + + + + + + + + + + +
Tradiční aplikaceTwelve-factor aplikace
Čas mezi nasazenímiTýdnyHodiny
Autoři kódu vs ti kdo kód nasazujíRozdílní lidéStejní lidé
Vývojové vs Produkční prostředíRozdílnéMinimální rozdíly
+ +[Podpůrné služby](./backing-services), jako je například databáze, fronty nebo cache jsou oblastí, kde je podobnost vývojového a produkčního prostředí velmi důležitá. Mnoho jazyků nabízí knihovny zjednodušující přístup k podpůrným službám, včetně *adaptérů* pro různé druhy služeb. Některé příklady jsou uvedeny v tabulce níže: + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypJazykKnihovnaAdaptér
DatabázeRuby/RailsActiveRecordMySQL, PostgreSQL, SQLite
FrontaPython/DjangoCeleryRabbitMQ, Beanstalkd, Redis
CacheRuby/RailsActiveSupport::CachePamět, Souborový systém, Memcached
+ +Vývojáři někdy rádi používají odlehčené varianty podpůrných služeb pro lokální vývoj, přesto že na produkci budou použity jejich plnohodnotné varianty. Například použití SQLite lokálně a PostgreSQL na produkci nebo lokální pamět použitá jako cache pro vývoj oproti Memcached v produkci. + +**Twelve-factor vývojáři dokáží odolat nutkání používat rozdílné podpůrné služby ve vývojovém a produkčním prostředí**, i přesto že adaptéry teoreticky odstraňují jakékoliv rozdíly v podpůrných službách. Rozdíly mezi podpůrnými službami a drobné nekompatibility se vždy vynoří a způsobí, že kód který prošel testy ve vývojovém a testovacím prostředí pak nefunguje na produkci. Tento typ chyb způsobuje obtíže a odrazuje od průběžného nasazování. Náklady spojené s těmito obtížemi a následným útlumem v průběžném nasazování jsou velmi vysoké, zvažujeme-li je souhrně za celou dobu životnosti aplikace. + +Odlehčené varianty služeb jsou méně lákavé než bývaly dříve. Moderní podpůrné služby jako Memcached, PostgreSQL a RabbitMQ nejsou díky moderním balíčkovacím systémům jako [Homebrew](http://mxcl.github.com/homebrew/) a [apt-get](https://help.ubuntu.com/community/AptGet/Howto) složité na instalaci. Deklarativní nástroje pro provisioning, jako jsou například [Chef](http://www.opscode.com/chef/), či [Puppet](http://docs.puppetlabs.com/) v kombinaci s odlehčenými virtuálními prostředími typu [Docker](https://www.docker.com/) nebo [Vagrant](http://vagrantup.com/), umožňují vývojářům provozovat lokální vývojové prostředí, které velmi věrně odpovídá tomu produkčnímu. Cena za instalaci a provoz těchto systémů je poměrně nizká v porovnání s výhodami, které přináší podobnost vývoj/produkce a průběžné nasazování. + +Adaptéry pro různé podpůrné služby mají stále svůj význam, protože umožňují přechod na nové podpůrné služby poměrně bezbolestně. Všechna nasazení aplikace (vývojové, testovací a produkční) by však měla používat stejný typ a verzi každé podpůrné služby. diff --git a/content/cs/disposability.md b/content/cs/disposability.md new file mode 100644 index 000000000..ffba0b637 --- /dev/null +++ b/content/cs/disposability.md @@ -0,0 +1,15 @@ +## IX. Zahoditelnost +### Maximalizujte robustnost pomocí rychlého spouštění a korektního vypnutí. + + +**[Procesy](./processes) twelve-factor aplikace jsou *zahoditelné*, to znamená, že mohou být kdykoliv spuštěny nebo vypnuty.** Usnadňuje to elastické škálování, rychlé nasazování [kódu](./codebase), změny [konfigurace](./config) a zvyšuje se robustnost celého produkčního nasazení. + +Procesy by se měly snažit **minimalizovat čas spuštění**. Ideálně by procesu mělo zabrat jen pár sekund od spuštění příkazu, do doby, kdy je připraven přijímat požadavky nebo úlohy. Krátký čas spuštění přináší větší obratnost pro procesy zajišťující [nasazení](./build-release-run) a škálování. Napomáhá také celkové robustnosti, protože správce procesů může v případě potřeby snadno přesouvat procesy na nové fyzické stroje. + +Procesy **se korektně ukončí po přijetí signálu [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od správce procesů. Pro webový proces znamená korektní ukončení to, že přestane naslouchat na příslušném portu (tedy začne odmítat nové požadavky), aktuálně běžící požadavky zpracuje a pak se vypne. V tomto modelu předpokládáme, že HTTP požadavky jsou poměrně krátké (ne delší než pár sekund). V případě dlouho trvajícího spojení by se měl klient umět znovu sám připojit, dojde-li ke ztrátě spojení. + +Pro proces typu worker je korektní ukončení dosaženo vrácením aktuální úlohy zpět do pracovní fronty. Například v [RabbitMQ](http://www.rabbitmq.com/) může worker poslat [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack), u [Beanstalkd](https://beanstalkd.github.io) se úloha vrátí do fronty automaticky, pokud se worker odpojí. Systémy postavené na zamykání, jako například [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) musí uvolnit zámek pro záznam své úlohy. V tomto modelu předpokládáme, že všechny úlohy jsou [opakovatelné](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), čehož se typicky dosáhne obalením výsledku do transakce anebo tím, že operaci učiníme [idempotetní](http://en.wikipedia.org/wiki/Idempotence). + +Procesy by měli být dostatečné **robustní pro případ náhle smrti**, dojde-li například k selhání podkladového hardwaru. I když se to stává velmi zřídka narozdíl od koretního ukončení signálem `SIGTERM`, stále se to ale může stát. Doporučený postup je použít robustní systém, jako je Beanstalkd, který vrací úlohy zpět do fronty v případě odpojení klienta nebo vypršení časového limitu. V každém případě, twelve-factor aplikace je navržena tak, aby zvládna neočekávané a nekorektní ukončení. [Crash-only design](http://lwn.net/Articles/191059/) je tedy pro tento koncept [logickým východiskem](http://docs.couchdb.org/en/latest/intro/overview.html). + + diff --git a/content/cs/intro.md b/content/cs/intro.md new file mode 100644 index 000000000..bbac62fda --- /dev/null +++ b/content/cs/intro.md @@ -0,0 +1,12 @@ +Úvod +============ + +V moderní době je software často dodáván jako služba, což označujeme pojmem *webová aplikace* nebo *software-as-a-service (SaaS)*. Twelve-factor metodika slouží pro vytváření (SaaS) aplikací, které: + +* Používají **deklarativní** formáty pro nastavení automatizace, což vede k minimalizaci času a nákladů potřebných pro začlenění nových vývojářů do projektu; +* Mají **jasný kontrakt** s operačním systémem ve kterém běží, čímž je umožněna **maximální přenositelnost** mezi různými běhovými prostředími; +* Jsou vhodné pro **nasazení** na moderních **cloudových platformách**, což eliminuje potřebu správy serverů a podpůrných systémů; +* **Minimalizují rozdíly** mezi vývojovým a produkčním prostředím, čímž umožňují **průběžné nasazovaní** a maximální flexibilitu; +* Umožňují **vyškálování** bez výrazných změn v nástrojích, architektuře nebo vývojových postupech. + +Twelve-factor metodiku lze použít na aplikace napsané v jakémkoliv programovacím jazyce a používající libovolnou kombinaci podpůrných služeb (databáze, fronty, vyrovnávací paměť atd.). \ No newline at end of file diff --git a/content/cs/logs.md b/content/cs/logs.md new file mode 100644 index 000000000..647e1c552 --- /dev/null +++ b/content/cs/logs.md @@ -0,0 +1,16 @@ +## XI. Logy +### S logy zacházejte jako s proudy událostí. + +*Logy* poskytují náhled na chování běžící aplikace. V prostředí serveru se obvykle zapisují do souboru na disku ("logfile"), ale to je jen výstupní formát. + +Logy jsou [proudy](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) agregovaných a časově seřazených událostí, posbíraných z výstupních proudů všech běžících procesů a podpůrných služeb. Logy jsou ve své syrové formě typicky v textovém formátu s jednou událostí na řádek (avšak výpis vyjímky může zabírat i více řádků). Logy nemají žádný pevný začátek ani konec, ale plynule proudí po celou dobu běhu aplikace. + +**Twelve-factor aplikace se nikdy nestará o routování anebo ukládání svého výstupního proudu.** Neměla by se ani pokoušet zapisovat nebo si spravovat své log soubory. Místo toho zapisuje každy její běžící proces nebufferovaně na `stdout`. Během lokálního vývoje vidí vývojář proud událostí ve svém terminále a sleduje chování aplikace. + +V testovacím a produkčním prostředí je proud každého procesu zachycen běhovým prostředím, spojen s ostatnímy proudy aplikace a nasměrován do jedné nebo více cílových destinací, určených pro zobrazení nebo k dlouhodobé archivaci logů. Tyto cílové destinace nejsou pro aplikaci viditelné ani konfigurovatelné, jejich správa je plně pod kontrolou běhového prostředí. Open source směrovače logů (jako jsou [Logplex](https://github.com/heroku/logplex) a [Fluentd](https://github.com/fluent/fluentd) slouží přesně k těmto účelům. + +Proudy událostí aplikace mohou být směrovány do souboru, nebo sledovány v reálněm čase přes tail v terminále. Důležitější však je, že tyto proudy mohou být zaslány do systému na indexaci a analýzu logů, jako je například [Splunk](http://www.splunk.com/) anebo do univerzálnějších systémů pro datové sklady jako je [Hadoop/Hive](http://hive.apache.org/). Tyto systémy jsou flexibilní a velmi mocné, chceme-li zkoumát chování aplikace v průběhu času, například při: + +* Hledání konkrétních událostí v minulosti. +* Velkoplošném vykreslení trendů (požadavky za minutu) do grafu. +* Aktivním alertingu dle uživatelsky definovaných heuristik (například pokud množství chyb za minutu přesáhne stanovenou hranici). diff --git a/content/cs/port-binding.md b/content/cs/port-binding.md new file mode 100644 index 000000000..51e412c39 --- /dev/null +++ b/content/cs/port-binding.md @@ -0,0 +1,14 @@ +## VII. Vazba s portem +### Exportujte služby pomocí vazby na port. + +Webové aplikace jsou někdy vykonávány uvnitř webového serveru. Například PHP aplikace mohou běžet jako modul uvnitř [Apache HTTPD](http://httpd.apache.org/) nebo Java aplikace mohou běžet uvnitř [Tomcatu](http://tomcat.apache.org/). + +**Twelve-factor aplikace jsou úplně soběstačné** a nespoléhají se na vsunutí webserveru do běhového prostředí k vytvoření webové služby. Webová aplikace **exportuje HTTP jako službu vázanou na port** a naslouchá požadavkům přicházejícím na daný port. + +V lokálním vývojovém prostředí přistupuje vývojář na službu exportovanou jeho aplikací přes URL jako je `http://localhost:5000/`. U nasazení přesměrovává směrovací vrstva požadavky z veřejně dostupné domény na port webového procesu. + +To se typicky realizuje přidáním knihovny webserveru přímo do aplikace za pomoci [deklarace závislostí](./dependencies). Například [Tornado](http://www.tornadoweb.org/) pro Python, [Thin](http://code.macournoyer.com/thin/) pro Ruby, nebo [Jetty](http://www.eclipse.org/jetty/) pro Javu a jiné jazyky založené na JVM. Toto se děje výhradně v *uživatelském prostoru*, tedy v kódu aplikace. Dohoda s běhovým prostředím je pak pouze vazba na port pro obsluhu požadavků. + +HTTP není jediná služba, kterou je možné exportovat přes port. Téměř libovolný serverový software může běžet na otevřeném portu a naslouchat příchozím požadavkům. Například [ejabberd](http://www.ejabberd.im/) (komunikující pomocí [XMPP](http://xmpp.org/)) nebo [Redis](http://redis.io/) (komunikující [Redis protokolem](http://redis.io/topics/protocol)). + +Všimněte si také, že přístupem pomocí vazby na port se jedna aplikace může stát [podpůrnou službou](./backing-services) pro jinou aplikaci, poskytnutím URL podpůrné služby jako zdroje pro [konfiguraci](./config) konzumující aplikace. diff --git a/content/cs/processes.md b/content/cs/processes.md new file mode 100644 index 000000000..f740f698f --- /dev/null +++ b/content/cs/processes.md @@ -0,0 +1,14 @@ +## VI. Procesy +### Spouštějte aplikaci jako jeden nebo více bezestavových procesů. + +Aplikace je vykonávána v běhovém prostředí jako jeden nebo více *procesů*. + +V nejjednodušším případě je kód samostatný skript, běhové prostředí je laptop vývojáře s naistalovaným interpreterem daného jazyka a proces je spouštěn z příkazové řádky (například jako `python my_script.py`). Na druhé straně spektra je produkční nasazení sofistikované aplikace využívající vícero [typů procesu, instancovaných do nula nebo více běžících procesů](./concurrency). + +**Twelve-factor procesy jsou bezestavové a [nic nesdílejí](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Jakákoliv data, která potřebují být uchována, musí být uložena ve stavové [podpůrné službě](./backing-services), typicky v databázi. + +Paměť nebo souborový systém procesu mohou být využity jako krátkodobá cache pro jednu transakci. Například ke stažení velkého souboru, práce s ním a následné uložení výsledku do databáze. Twelve-factor aplikace nikdy nespoléhá, že cokoliv je nacachované v paměti nebo na disku, bude dostupné i v dalším požadavku. Při velkém počtu běžících procesů je vysoká pravděpodobnost, že další požadavek bude odbaven jiným procesem. I kdyby běžel pouze jeden proces, restart (způsobený nasazením nového kódu, změnou konfigurace nebo přemístěním procesu na jiné fyzické umístění) obvykle smaže všechny lokální (například pamět nebo souborový systém) stavy. + +Balíčkovače jako je [django-assetpackager](http://code.google.com/p/django-assetpackager/) používají souborový systém jako dočasné uložiště pro zkompilované soubory. Twelve-factor aplikace preferují kompilaci během [fáze sestavení](/build-release-run). Balíčkovače jako jsou [Jammit](http://documentcloud.github.com/jammit/) a [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) mohou být nastaveny tak, že soubory zabalí již během fáze sestavení. + +Některé webové aplikace spoléhají na ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence), tedy cachování uživatelských session v paměti procesu a směrování budoucích požadavků stejného návštěvníka na stejný proces. Sticky session jsou porušením twelve-factor metodiky a neměli by se používat a ani by se na ně nemělo jakkoliv spoléhat. Sticky session data jsou vhodným kandidátem pro uložiště, která podporují časovou expiraci dat, jako jsou například [Memcached](http://memcached.org/) nebo [Redis](http://redis.io/). \ No newline at end of file diff --git a/content/cs/toc.md b/content/cs/toc.md new file mode 100644 index 000000000..b12fd6f9f --- /dev/null +++ b/content/cs/toc.md @@ -0,0 +1,38 @@ +The Twelve Factors +================== + +## [I. Zdrojový kód](./codebase) +### Mějte jeden zdrojový kód ve verzovacím systému a mnoho nasazení. + +## [II. Závislosti](./dependencies) +### Explicitně deklarujte a izololujte závislosti. + +## [III. Konfigurace](./config) +### Konfigurace ukládejte do prostředí. + +## [IV. Podpůrné služby](./backing-services) +### Nakládejte s podpůrnými službami jako s připojenými zdroji. + +## [V. Sestavení, vydání, spuštění](./build-release-run) +### Striktně oddělte fáze sestavení, vydání a spuštění. + +## [VI. Procesy](./processes) +### Spouštějte aplikaci jako jeden nebo více bezestavových procesů. + +## [VII. Vazba s portem](./port-binding) +### Exportujte služby pomocí vazby na port. + +## [VIII. Souběh](./concurrency) +### Škálujte do šířky použitím proces modelu. + +## [IX. Zahoditelnost](./disposability) +### Maximalizujte robustnost pomocí rychlého spouštění a korektního vypnutí. + +## [X. Podobnost Vývoj/Produkce](./dev-prod-parity) +### Udržujte si co nejmenší rozdíly mezi vývojovým, testovacím a produkčním prostředím. + +## [XI. Logy](./logs) +### S logy zacházejte jako s proudy událostí. + +## [XII. Admin procesy](./admin-processes) +### Spouštějte administrativní úlohy jako jednorázové procesy. diff --git a/content/cs/who.md b/content/cs/who.md new file mode 100644 index 000000000..834f3fdbe --- /dev/null +++ b/content/cs/who.md @@ -0,0 +1,4 @@ +Kdo by měl číst tento dokument? +============================== + +Každý vývojář pracující na aplikaci, která běží jako služba. Systémoví inženýři, kteří takové aplikace nasazují nebo spravují. \ No newline at end of file diff --git a/locales/cs.yml b/locales/cs.yml new file mode 100644 index 000000000..4cd3d9bec --- /dev/null +++ b/locales/cs.yml @@ -0,0 +1,7 @@ +sk: + # Name of language listed in locales menu + language: Česky (cs) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: " - česká verze" From fb329133873d397f3fd434157f90e4ec007942aa Mon Sep 17 00:00:00 2001 From: Jan Gabriel Date: Tue, 18 Feb 2020 15:04:20 +0100 Subject: [PATCH 454/472] fix mistake made by copy and pasting --- locales/cs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/cs.yml b/locales/cs.yml index 4cd3d9bec..1879c4baa 100644 --- a/locales/cs.yml +++ b/locales/cs.yml @@ -1,4 +1,4 @@ -sk: +cs: # Name of language listed in locales menu language: Česky (cs) From fb2df27e098d62a8de7c2efbd70e306e069fd9b6 Mon Sep 17 00:00:00 2001 From: Jan Gabriel Date: Tue, 18 Feb 2020 15:05:33 +0100 Subject: [PATCH 455/472] translate heading left in EN --- content/cs/backing-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/cs/backing-services.md b/content/cs/backing-services.md index b7168ea73..0a28133d2 100644 --- a/content/cs/backing-services.md +++ b/content/cs/backing-services.md @@ -1,4 +1,4 @@ -## IV. Backing services +## IV. Podpůrné služby ### Nakládejte s podpůrnými službami jako s připojenými zdroji. *Podpůrná* služba je jakákoliv služba, kterou aplikace konzumuje přes síť jako součást svého normálního běhu. Příklady zahrnují databáze (jako například [MySQL](http://dev.mysql.com/) nebo [CouchDB](http://couchdb.apache.org/)), messaging/queueing systémy (jako jsou [RabbitMQ](http://www.rabbitmq.com/) nebo [Beanstalkd](https://beanstalkd.github.io)), SMTP služby pro odchozí emaily (jako [Postfix](http://www.postfix.org/)) a cachovací systémy (jako je [Memcached](http://memcached.org/)). From 6694fbba024ec7019018bedde5dbeb85e9c7da7e Mon Sep 17 00:00:00 2001 From: Jan Gabriel Date: Thu, 9 Apr 2020 08:18:49 +0200 Subject: [PATCH 456/472] fixed typos after review --- content/cs/admin-processes.md | 4 ++-- content/cs/backing-services.md | 2 +- content/cs/build-release-run.md | 2 +- content/cs/codebase.md | 2 +- content/cs/concurrency.md | 2 +- content/cs/dependencies.md | 2 +- content/cs/dev-prod-parity.md | 8 ++++---- content/cs/disposability.md | 4 ++-- content/cs/logs.md | 6 +++--- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/content/cs/admin-processes.md b/content/cs/admin-processes.md index f1020acbb..d940c09c7 100644 --- a/content/cs/admin-processes.md +++ b/content/cs/admin-processes.md @@ -9,6 +9,6 @@ Jednorázové administrativní procesy by měly být spouštěny ve stejném prostředí jako běžné [dlouho běžící procesy](./processes) aplikace. Běží proti [vydání](./build-release-run) za použití stejného [kódu](./codebase) a [konfigurace ](./config) jako ostatní procesy daného vydání. Administrativní kód musí být dodáván spolu s aplikací, aby se zabránilo problémům se synchronizací. -Stejné techniky [izolace závislostí](./dependencies) by měli být použity na všechny typy procesů. Například, pokud Ruby webový proces používá příkaz `bundle exec thin start`, tak databázová migrace by měla používat `bundle exec rake db:migrate`. Obdobně by pak měl program v Pythonu, využívající Virtualenv, používat přibalený `bin/python` pro spouštění jak Tornado webserveru, tak i pro spouštění `manage.py` administrativního procesu. +Stejné techniky [izolace závislostí](./dependencies) by měly být použity na všechny typy procesů. Například, pokud Ruby webový proces používá příkaz `bundle exec thin start`, tak databázová migrace by měla používat `bundle exec rake db:migrate`. Obdobně by pak měl program v Pythonu, využívající Virtualenv, používat přibalený `bin/python` pro spouštění jak Tornado webserveru, tak i pro spouštění `manage.py` administrativního procesu. -Twelve-factor metodika silně preferuje jazyky, které poskytují REPL shell v základu a umožňují tak snadno spouštět jednorázové skripty. V lokálním nasazení spouštějí vývojáři jednorázový administrativní proces příkazem přímo v shellu unvnitř repozitáže. V produkčním nasazení mohou vývojáři použít SSH nebo jiný způsob vzdáleného spouštění příkazů, který je v daném nasazení pro spouštění procesů k dispozici. +Twelve-factor metodika silně preferuje jazyky, které poskytují REPL shell v základu a umožňují tak snadno spouštět jednorázové skripty. V lokálním nasazení spouštějí vývojáři jednorázový administrativní proces příkazem přímo v shellu uvnitř repozitáře. V produkčním nasazení mohou vývojáři použít SSH nebo jiný způsob vzdáleného spouštění příkazů, který je v daném nasazení pro spouštění procesů k dispozici. diff --git a/content/cs/backing-services.md b/content/cs/backing-services.md index 0a28133d2..d904baf00 100644 --- a/content/cs/backing-services.md +++ b/content/cs/backing-services.md @@ -3,7 +3,7 @@ *Podpůrná* služba je jakákoliv služba, kterou aplikace konzumuje přes síť jako součást svého normálního běhu. Příklady zahrnují databáze (jako například [MySQL](http://dev.mysql.com/) nebo [CouchDB](http://couchdb.apache.org/)), messaging/queueing systémy (jako jsou [RabbitMQ](http://www.rabbitmq.com/) nebo [Beanstalkd](https://beanstalkd.github.io)), SMTP služby pro odchozí emaily (jako [Postfix](http://www.postfix.org/)) a cachovací systémy (jako je [Memcached](http://memcached.org/)). -Podpůrné služby, jako například databáze, jsou obvykle spravovány stejnými systémovými inženýri jako samotné nasazení aplikace. K těmto lokálně spravovaným službám může aplikace navíc využívat služby provozované a spravované třetí stranou. To mohou být například SMTP služby (jako je [Postmark](http://postmarkapp.com/)), služby na sbírání metrik (jako [New Relic](http://newrelic.com/) nebo [Loggly](http://www.loggly.com/)), datová uložistě (jako [Amazon S3](http://aws.amazon.com/s3/)) a dokonce i služby přístupné přes API (jako jsou například [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) nebo [Last.fm](http://www.last.fm/api)). +Podpůrné služby, jako například databáze, jsou obvykle spravovány stejnými systémovými inženýry jako samotné nasazení aplikace. K těmto lokálně spravovaným službám může aplikace navíc využívat služby provozované a spravované třetí stranou. To mohou být například SMTP služby (jako je [Postmark](http://postmarkapp.com/)), služby na sbírání metrik (jako [New Relic](http://newrelic.com/) nebo [Loggly](http://www.loggly.com/)), datová uložistě (jako [Amazon S3](http://aws.amazon.com/s3/)) a dokonce i služby přístupné přes API (jako jsou například [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/) nebo [Last.fm](http://www.last.fm/api)). **Kód twelve-factor aplikace nedělá rozdíly mezi lokální službou a službou třetí strany.** Z pohledu aplikace jsou to připojené zdroje přístupné přes URL nebo jiné přístupové/přihlašovací údaje uložené v [konfiguraci](./config). Nasazení twelve-factor aplikace by mělo být schopné vyměnit lokální MySQL databázi za databázi spravovanou třetí stranou (jako je například [Amazon RDS](http://aws.amazon.com/rds/)) bez jakýchkoliv změn v aplikačním kódu. Obdobně může být lokální SMTP server nahrazen SMTP službou třetí strany (jako Postmark) bez změn v kódu. V obou případech se změní pouze přístupové a přihlašovací údaje v konfiguraci. diff --git a/content/cs/build-release-run.md b/content/cs/build-release-run.md index 7a75ccf08..a7097de12 100644 --- a/content/cs/build-release-run.md +++ b/content/cs/build-release-run.md @@ -15,5 +15,5 @@ Nástroje pro nasazení obvykle poskytují i správu vydání a zejména pak sch Každé vydaní by mělo mít vždy unikátní ID, jako je například časová značka ( `2011-04-06-20:32:17`) nebo inkrementální číslo (například `v100`). Vydání již nelze po vytvoření jakkoliv upravovat, libovolná změna musí vždy vytvořit nové vydání. -Sestavení iniciují vývojáři aplikace, kdykoliv se nasazuje nový kód. Naopak ke spuštění v běhovém prostředí může dojít automaticky v případě restartu serveru nebo restartem havarovaného procesu pomocí správce procesů. Proto by měla mít fáze spuštění co nejméně pohyblivých částí, jelikož problémy bránící aplikaci v běhu mohou nastat uprostřed noci, kdy nejsou žádní vývořáji k dispozici. Fáze sestavení pak může být složitější, protože chyby jsou více na očích pro vývojáře kontrolující nasazení aplikace. +Sestavení iniciují vývojáři aplikace, kdykoliv se nasazuje nový kód. Naopak ke spuštění v běhovém prostředí může dojít automaticky v případě restartu serveru nebo restartem havarovaného procesu pomocí správce procesů. Proto by měla mít fáze spuštění co nejméně pohyblivých částí, jelikož problémy bránící aplikaci v běhu mohou nastat uprostřed noci, kdy nejsou žádní vývojáři k dispozici. Fáze sestavení pak může být složitější, protože chyby jsou více na očích pro vývojáře kontrolující nasazení aplikace. diff --git a/content/cs/codebase.md b/content/cs/codebase.md index fbe6f75a2..916e83704 100644 --- a/content/cs/codebase.md +++ b/content/cs/codebase.md @@ -9,7 +9,7 @@ Twelve-factor aplikace je vždy sledována ve verzovacím systému, jako je nap Vždy existuje korelace jedna-ku-jedné mezi zdrojovým kódem a aplikací: -* Pokud existuje více zdrojových kódů, nejedná se o aplikaci, ale o distribuovaný systém. Každá komponenta distibuovaného systému je dílčí aplikace, která může samostatně podléhat twelve-factor metodice. +* Pokud existuje více zdrojových kódů, nejedná se o aplikaci, ale o distribuovaný systém. Každá komponenta distribuovaného systému je dílčí aplikace, která může samostatně podléhat twelve-factor metodice. * Více aplikací sdílejících stejný kód je porušení twelve-factor metodiky. Řešením je oddělení sdíleného kódu do knihovny, která se připojí pomocí [systému na správu závislostí](./dependencies). Každá aplikace má pouze jeden zdrojový kód, ale nasazení jedné aplikace bude vícero. *Nasazení* je běžící instance aplikace. Typicky je to produkční web a jeden nebo více testovacích webů. Každý vývojář má navíc lokální vývojovou kopii běžící aplikace, každou takovou kopii lze také považovat za nasazení. diff --git a/content/cs/concurrency.md b/content/cs/concurrency.md index 65baefe08..24cd5d96f 100644 --- a/content/cs/concurrency.md +++ b/content/cs/concurrency.md @@ -9,6 +9,6 @@ Každý počítačový program se po spuštění prezentuje jako jeden nebo víc To nevylučuje, že si jednotlivé procesy nemohou spravovat interní multiplexování přes vlákna nebo pomocí async/event modelu, jako je tomu v [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) nebo [Node.js](http://nodejs.org/). Jednotlivé VM však mohou růst jen omezeně (vertikální škálování), aplikace tedy musí být schopná i běhu v několika procesech na více fyzických strojích. -Proces model obvzlášť vyniká, když přijde čas na škálování. [Nesdílená a horizontálně dělitelná podstata procesů twelve-factor aplikace](./processes) znamená, že přidání větší souběžnosti je jednoduchá a spolehlivá operace. Sada typu procesů a množství procesů každého typu se nazývá *formace procesů*. +Proces model obzvlášť vyniká, když přijde čas na škálování. [Nesdílená a horizontálně dělitelná podstata procesů twelve-factor aplikace](./processes) znamená, že přidání větší souběžnosti je jednoduchá a spolehlivá operace. Sada typu procesů a množství procesů každého typu se nazývá *formace procesů*. Procesy twelve-factor aplikace by [nikdy neměly démonizovat](http://dustin.github.com/2010/02/28/running-processes.html) nebo zapisovat PID soubory. Namísto toho by se měly spoléhat na správce procesů operačního systému (jako je například [systemd](https://www.freedesktop.org/wiki/Software/systemd/), správce distribuovaných procesů na cloudové platformě nebo nástroje typu [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) během vývoje), který obstará [výstupní proudy](./logs), reakci na havarované procesy a obsluhu uživatelem vyvolaných restartů a zastavení. diff --git a/content/cs/dependencies.md b/content/cs/dependencies.md index 5f989da32..cf9baf84f 100644 --- a/content/cs/dependencies.md +++ b/content/cs/dependencies.md @@ -7,6 +7,6 @@ Většina programovacých jazyků poskytuje balíčkovací systém pro distribuc Například [Bundler](https://bundler.io/) pro Ruby poskytuje `Gemfile` manifest formát pro deklaraci závislostí a `bundle exec` pro izolaci závislostí. Pro Python jsou to dva rozdílné nástroje, [Pip](http://www.pip-installer.org/en/latest/) je použit pro deklaraci závislostí a [Virtualenv](http://www.virtualenv.org/en/latest/) pro jejich izolaci. Dokonce i C má [Autoconf](http://www.gnu.org/s/autoconf/) pro deklaraci závislostí a statické linkování poskytuje izolaci závislostí. Nehledě na použitou sadu nástrojů, deklarace a izolace závislostí musí být vždy aplikovány společně, použití pouze jednoho nebo pouze druhého není dostatečné pro splnění podmínek twelve-factor metodiky. -Jednou z výhod explicintní deklarace závislostí je to, že zjednodušuje počáteční rozběhnutí aplikace pro nové vývojáře. Nový vývojář si jen naklonuje repozitář aplikace do svého vývojového prostředí a jako prerekvizity mu postačí nainstalované běhové prostředí jazyka a příslušný správce závislostí. Vše potřebné pro rozběhnutí aplikace se zajistí deterministicky *build příkazem* . Například, build příkaz pro Ruby/Bundler je `bundle install`, pro Cloujure/[Leiningen](https://github.com/technomancy/leiningen#readme) je to `lein deps`. +Jednou z výhod explicitní deklarace závislostí je to, že zjednodušuje počáteční rozběhnutí aplikace pro nové vývojáře. Nový vývojář si jen naklonuje repozitář aplikace do svého vývojového prostředí a jako prerekvizity mu postačí nainstalované běhové prostředí jazyka a příslušný správce závislostí. Vše potřebné pro rozběhnutí aplikace se zajistí deterministicky *build příkazem* . Například, build příkaz pro Ruby/Bundler je `bundle install`, pro Cloujure/[Leiningen](https://github.com/technomancy/leiningen#readme) je to `lein deps`. Twelve-factor aplikace se nespoléhají na implicitní existenci jakýchkoli systémových nástrojů. Příkladem může být spouštění ImageMagick nebo `curl` přes shell. I když tyto nástroje existují na mnoha a možná i většině aktuálně používaných systémů, neexistuje žadná záruka, že tyto nástroje budou existovat na systémech, kde aplikace poběží v budoucnu a nebo že budou na budoucích systémech dostupné v kompatibilní verzi. Pokud aplikace potřebuje spouštět nějaký nástroj přes shell, tak by měl být daný nástroj součástí aplikace. \ No newline at end of file diff --git a/content/cs/dev-prod-parity.md b/content/cs/dev-prod-parity.md index ffd3b7549..53cd2cf63 100644 --- a/content/cs/dev-prod-parity.md +++ b/content/cs/dev-prod-parity.md @@ -27,7 +27,7 @@ Souhrn výše popsaného v tabulce: Hodiny - Autoři kódu vs ti kdo kód nasazují + Autoři kódu vs ti, kdo kód nasazují Rozdílní lidé Stejní lidé @@ -67,10 +67,10 @@ Souhrn výše popsaného v tabulce: -Vývojáři někdy rádi používají odlehčené varianty podpůrných služeb pro lokální vývoj, přesto že na produkci budou použity jejich plnohodnotné varianty. Například použití SQLite lokálně a PostgreSQL na produkci nebo lokální pamět použitá jako cache pro vývoj oproti Memcached v produkci. +Vývojáři někdy rádi používají odlehčené varianty podpůrných služeb pro lokální vývoj, přestože na produkci budou použity jejich plnohodnotné varianty. Například použití SQLite lokálně a PostgreSQL na produkci nebo lokální pamět použitá jako cache pro vývoj oproti Memcached v produkci. -**Twelve-factor vývojáři dokáží odolat nutkání používat rozdílné podpůrné služby ve vývojovém a produkčním prostředí**, i přesto že adaptéry teoreticky odstraňují jakékoliv rozdíly v podpůrných službách. Rozdíly mezi podpůrnými službami a drobné nekompatibility se vždy vynoří a způsobí, že kód který prošel testy ve vývojovém a testovacím prostředí pak nefunguje na produkci. Tento typ chyb způsobuje obtíže a odrazuje od průběžného nasazování. Náklady spojené s těmito obtížemi a následným útlumem v průběžném nasazování jsou velmi vysoké, zvažujeme-li je souhrně za celou dobu životnosti aplikace. +**Twelve-factor vývojáři dokáží odolat nutkání používat rozdílné podpůrné služby ve vývojovém a produkčním prostředí** i přesto, že adaptéry teoreticky odstraňují jakékoliv rozdíly v podpůrných službách. Rozdíly mezi podpůrnými službami a drobné nekompatibility se vždy vynoří a způsobí, že kód který prošel testy ve vývojovém a testovacím prostředí pak nefunguje na produkci. Tento typ chyb způsobuje obtíže a odrazuje od průběžného nasazování. Náklady spojené s těmito obtížemi a následným útlumem v průběžném nasazování jsou velmi vysoké, zvažujeme-li je souhrně za celou dobu životnosti aplikace. -Odlehčené varianty služeb jsou méně lákavé než bývaly dříve. Moderní podpůrné služby jako Memcached, PostgreSQL a RabbitMQ nejsou díky moderním balíčkovacím systémům jako [Homebrew](http://mxcl.github.com/homebrew/) a [apt-get](https://help.ubuntu.com/community/AptGet/Howto) složité na instalaci. Deklarativní nástroje pro provisioning, jako jsou například [Chef](http://www.opscode.com/chef/), či [Puppet](http://docs.puppetlabs.com/) v kombinaci s odlehčenými virtuálními prostředími typu [Docker](https://www.docker.com/) nebo [Vagrant](http://vagrantup.com/), umožňují vývojářům provozovat lokální vývojové prostředí, které velmi věrně odpovídá tomu produkčnímu. Cena za instalaci a provoz těchto systémů je poměrně nizká v porovnání s výhodami, které přináší podobnost vývoj/produkce a průběžné nasazování. +Odlehčené varianty služeb jsou méně lákavé než bývaly dříve. Moderní podpůrné služby jako Memcached, PostgreSQL a RabbitMQ nejsou díky moderním balíčkovacím systémům jako [Homebrew](http://mxcl.github.com/homebrew/) a [apt-get](https://help.ubuntu.com/community/AptGet/Howto) složité na instalaci. Deklarativní nástroje pro provisioning, jako jsou například [Chef](http://www.opscode.com/chef/), či [Puppet](http://docs.puppetlabs.com/) v kombinaci s odlehčenými virtuálními prostředími typu [Docker](https://www.docker.com/) nebo [Vagrant](http://vagrantup.com/), umožňují vývojářům provozovat lokální vývojové prostředí, které velmi věrně odpovídá tomu produkčnímu. Cena za instalaci a provoz těchto systémů je poměrně nízká v porovnání s výhodami, které přináší podobnost vývoj/produkce a průběžné nasazování. Adaptéry pro různé podpůrné služby mají stále svůj význam, protože umožňují přechod na nové podpůrné služby poměrně bezbolestně. Všechna nasazení aplikace (vývojové, testovací a produkční) by však měla používat stejný typ a verzi každé podpůrné služby. diff --git a/content/cs/disposability.md b/content/cs/disposability.md index ffba0b637..a8b63120b 100644 --- a/content/cs/disposability.md +++ b/content/cs/disposability.md @@ -8,8 +8,8 @@ Procesy by se měly snažit **minimalizovat čas spuštění**. Ideálně by pro Procesy **se korektně ukončí po přijetí signálu [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** od správce procesů. Pro webový proces znamená korektní ukončení to, že přestane naslouchat na příslušném portu (tedy začne odmítat nové požadavky), aktuálně běžící požadavky zpracuje a pak se vypne. V tomto modelu předpokládáme, že HTTP požadavky jsou poměrně krátké (ne delší než pár sekund). V případě dlouho trvajícího spojení by se měl klient umět znovu sám připojit, dojde-li ke ztrátě spojení. -Pro proces typu worker je korektní ukončení dosaženo vrácením aktuální úlohy zpět do pracovní fronty. Například v [RabbitMQ](http://www.rabbitmq.com/) může worker poslat [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack), u [Beanstalkd](https://beanstalkd.github.io) se úloha vrátí do fronty automaticky, pokud se worker odpojí. Systémy postavené na zamykání, jako například [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) musí uvolnit zámek pro záznam své úlohy. V tomto modelu předpokládáme, že všechny úlohy jsou [opakovatelné](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), čehož se typicky dosáhne obalením výsledku do transakce anebo tím, že operaci učiníme [idempotetní](http://en.wikipedia.org/wiki/Idempotence). +Pro proces typu worker je korektní ukončení dosaženo vrácením aktuální úlohy zpět do pracovní fronty. Například v [RabbitMQ](http://www.rabbitmq.com/) může worker poslat [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack), u [Beanstalkd](https://beanstalkd.github.io) se úloha vrátí do fronty automaticky, pokud se worker odpojí. Systémy postavené na zamykání, jako například [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) musí uvolnit zámek pro záznam své úlohy. V tomto modelu předpokládáme, že všechny úlohy jsou [opakovatelné](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), čehož se typicky dosáhne obalením výsledku do transakce anebo tím, že operaci učiníme [idempotentní](http://en.wikipedia.org/wiki/Idempotence). -Procesy by měli být dostatečné **robustní pro případ náhle smrti**, dojde-li například k selhání podkladového hardwaru. I když se to stává velmi zřídka narozdíl od koretního ukončení signálem `SIGTERM`, stále se to ale může stát. Doporučený postup je použít robustní systém, jako je Beanstalkd, který vrací úlohy zpět do fronty v případě odpojení klienta nebo vypršení časového limitu. V každém případě, twelve-factor aplikace je navržena tak, aby zvládna neočekávané a nekorektní ukončení. [Crash-only design](http://lwn.net/Articles/191059/) je tedy pro tento koncept [logickým východiskem](http://docs.couchdb.org/en/latest/intro/overview.html). +Procesy by měly být dostatečně **robustní pro případ náhle smrti**, dojde-li například k selhání podkladového hardwaru. I když se to stává velmi zřídka narozdíl od koretního ukončení signálem `SIGTERM`, stále se to ale může stát. Doporučený postup je použít robustní systém, jako je Beanstalkd, který vrací úlohy zpět do fronty v případě odpojení klienta nebo vypršení časového limitu. V každém případě, twelve-factor aplikace je navržena tak, aby zvládna neočekávané a nekorektní ukončení. [Crash-only design](http://lwn.net/Articles/191059/) je tedy pro tento koncept [logickým východiskem](http://docs.couchdb.org/en/latest/intro/overview.html). diff --git a/content/cs/logs.md b/content/cs/logs.md index 647e1c552..30b5542b5 100644 --- a/content/cs/logs.md +++ b/content/cs/logs.md @@ -3,13 +3,13 @@ *Logy* poskytují náhled na chování běžící aplikace. V prostředí serveru se obvykle zapisují do souboru na disku ("logfile"), ale to je jen výstupní formát. -Logy jsou [proudy](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) agregovaných a časově seřazených událostí, posbíraných z výstupních proudů všech běžících procesů a podpůrných služeb. Logy jsou ve své syrové formě typicky v textovém formátu s jednou událostí na řádek (avšak výpis vyjímky může zabírat i více řádků). Logy nemají žádný pevný začátek ani konec, ale plynule proudí po celou dobu běhu aplikace. +Logy jsou [proudy](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) agregovaných a časově seřazených událostí, posbíraných z výstupních proudů všech běžících procesů a podpůrných služeb. Logy jsou ve své syrové formě typicky v textovém formátu s jednou událostí na řádek (avšak výpis výjimky může zabírat i více řádků). Logy nemají žádný pevný začátek ani konec, ale plynule proudí po celou dobu běhu aplikace. -**Twelve-factor aplikace se nikdy nestará o routování anebo ukládání svého výstupního proudu.** Neměla by se ani pokoušet zapisovat nebo si spravovat své log soubory. Místo toho zapisuje každy její běžící proces nebufferovaně na `stdout`. Během lokálního vývoje vidí vývojář proud událostí ve svém terminále a sleduje chování aplikace. +**Twelve-factor aplikace se nikdy nestará o routování anebo ukládání svého výstupního proudu.** Neměla by se ani pokoušet zapisovat nebo si spravovat své log soubory. Místo toho zapisuje každy její běžící proces nebufferovaně na `stdout`. Během lokálního vývoje vidí vývojář proud událostí ve svém terminálu a sleduje chování aplikace. V testovacím a produkčním prostředí je proud každého procesu zachycen běhovým prostředím, spojen s ostatnímy proudy aplikace a nasměrován do jedné nebo více cílových destinací, určených pro zobrazení nebo k dlouhodobé archivaci logů. Tyto cílové destinace nejsou pro aplikaci viditelné ani konfigurovatelné, jejich správa je plně pod kontrolou běhového prostředí. Open source směrovače logů (jako jsou [Logplex](https://github.com/heroku/logplex) a [Fluentd](https://github.com/fluent/fluentd) slouží přesně k těmto účelům. -Proudy událostí aplikace mohou být směrovány do souboru, nebo sledovány v reálněm čase přes tail v terminále. Důležitější však je, že tyto proudy mohou být zaslány do systému na indexaci a analýzu logů, jako je například [Splunk](http://www.splunk.com/) anebo do univerzálnějších systémů pro datové sklady jako je [Hadoop/Hive](http://hive.apache.org/). Tyto systémy jsou flexibilní a velmi mocné, chceme-li zkoumát chování aplikace v průběhu času, například při: +Proudy událostí aplikace mohou být směrovány do souboru, nebo sledovány v reálněm čase přes tail v terminálu. Důležitější však je, že tyto proudy mohou být zaslány do systému na indexaci a analýzu logů, jako je například [Splunk](http://www.splunk.com/) anebo do univerzálnějších systémů pro datové sklady jako je [Hadoop/Hive](http://hive.apache.org/). Tyto systémy jsou flexibilní a velmi mocné, chceme-li zkoumát chování aplikace v průběhu času, například při: * Hledání konkrétních událostí v minulosti. * Velkoplošném vykreslení trendů (požadavky za minutu) do grafu. From fd53b1d6ce9b00f168b907e4cec5b30fdd04f835 Mon Sep 17 00:00:00 2001 From: dangen <23185799+dangen-effy@users.noreply.github.com> Date: Mon, 4 May 2020 13:01:26 +0900 Subject: [PATCH 457/472] =?UTF-8?q?Fix=20Korean=20postpositions=20(?= =?UTF-8?q?=EC=9D=84=20->=20=EB=A5=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Korean postpositions (을 -> 를) --- content/ko/dev-prod-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ko/dev-prod-parity.md b/content/ko/dev-prod-parity.md index 1c4e952c8..eb90cdd47 100644 --- a/content/ko/dev-prod-parity.md +++ b/content/ko/dev-prod-parity.md @@ -9,7 +9,7 @@ **Twelve Factor App은 개발 환경과 production 환경의 차이를 작게 유지하여 [지속적인 배포](http://avc.com/2011/02/continuous-deployment/)가 가능하도록 디자인 되었습니다.** 위에서 언급한 3가지 차이에 대한 대응책은 아래와 같습니다. -* 시간의 차이을 최소화: 개발자가 작성한 코드는 몇 시간, 심지어 몇 분 후에 배포됩니다. +* 시간의 차이를 최소화: 개발자가 작성한 코드는 몇 시간, 심지어 몇 분 후에 배포됩니다. * 담당자의 차이를 최소화: 코드를 작성한 개발자들이 배포와 production에서의 모니터링에 깊게 관여합니다. * 툴의 차이를 최소화: 개발과 production 환경을 최대한 비슷하게 유지합니다. From 5aa3c9c497a61079060c1972880a2c86c817b39e Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Thu, 2 Apr 2020 15:41:51 +0300 Subject: [PATCH 458/472] Fix ugly literal translation. --- content/ru/concurrency.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ru/concurrency.md b/content/ru/concurrency.md index c33a979dd..1e3b5b5a9 100644 --- a/content/ru/concurrency.md +++ b/content/ru/concurrency.md @@ -5,10 +5,10 @@ ![Масштабирование выражается в количестве запущенных процессов, различие рабочей нагрузки выражается в типах процессов.](/images/process-types.png) -**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы своего *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны рабочим процессом. +**В приложении двенадцати факторов процессы являются сущностями первого класса.** Процессы в приложении двенадцати факторов взяли сильные стороны из [модели процессов Unix для запуска демонов](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). С помощью этой модели разработчик может спроектировать своё приложение таким образом, что для обработки различной рабочей нагрузки необходимо назначить каждому типу работы свой *типа процесса*. Например, HTTP-запросы могут быть обработаны веб-процессом, а длительные фоновые задачи обработаны воркером, выполняющим их в фоне. -Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограничено (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. +Это не исключает возможность использования внутреннего мультиплексирования для индивидуальных процессов через потоки выполнения виртуальной машины или асинхронные/событийные модели в инструментах таких, как [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) и [Node.js](http://nodejs.org/). Но каждая индивидуальная виртуальная машина может масштабироваться только ограниченно (вертикальное масштабирование), поэтому приложение должно иметь возможность быть запущенным как несколько процессов на различных физических машинах. -Модель, построенная на процессах, действительно сияет, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. +Модель, построенная на процессах в полной мере демонстрирует свои преимущества, когда приходит время масштабирования. [Отсутствие разделяемых данных и горизонтальное разделение процессов приложения двенадцати факторов](./processes) означает, что добавление большего параллелизма является простой и надёжной операцией. Массив процессов различного типа и количество процессов каждого типа называются *формированием процессов (process formation)*. Процессы приложения двенадцати факторов [никогда не должны демонизироваться](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), реагирования на падения процесса и обработки инициированных пользователем перезагрузки или завершения работы. From 54af32ec5c8dbeef9fc201c85ecc3219f4cf789c Mon Sep 17 00:00:00 2001 From: Raul Murciano Date: Tue, 23 Jun 2020 19:21:55 +0200 Subject: [PATCH 459/472] Ruby 2.6.6 --- .ruby-version | 2 +- .travis.yml | 2 +- Gemfile | 2 +- Gemfile.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ruby-version b/.ruby-version index 57cf282eb..338a5b5d8 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.5 +2.6.6 diff --git a/.travis.yml b/.travis.yml index 3339c363a..abd61d3d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: ruby rvm: - - 2.6.5 + - 2.6.6 script: exit 0 sudo: false diff --git a/Gemfile b/Gemfile index 1c3836091..df4a21da3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.6.5' +ruby '2.6.6' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index a3d8d918f..9808a77ea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,7 +30,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.6.5p114 + ruby 2.6.6p146 BUNDLED WITH 1.17.2 From c1c302f8f19c1ad92766ae936b3bb9373bee9468 Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Wed, 22 Jul 2020 22:31:30 +0300 Subject: [PATCH 460/472] updated home page Turkish translations --- content/tr/background.md | 7 +++---- content/tr/intro.md | 10 +++++----- content/tr/toc.md | 32 ++++++++++++++++---------------- content/tr/who.md | 2 +- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/content/tr/background.md b/content/tr/background.md index aa472d841..1dd181d7d 100644 --- a/content/tr/background.md +++ b/content/tr/background.md @@ -1,9 +1,8 @@ Arkaplan ========== -Bu belgeye katkıda bulunan kişiler, yüzlerce uygulamanın geliştirilmesi ve dağıtılmasında doğrudan yer almış, ve dolaylı olarak Heroku platformundaki üzerinde çalıştığımız yüz binlerce uygulamanın geliştirilmesi, çalıştırılması ve ölçeklendirilmesine tanık olmuştur. +Bu belgeye katkıda bulunan kişiler, yüzlerce uygulamanın geliştirilmesi ve yayınlanmasında doğrudan yer almış, ve dolaylı olarak Heroku platformundaki üzerinde çalıştığımız yüz binlerce uygulamanın geliştirilmesi, çalıştırılması ve ölçeklendirilmesine tanık olmuştur. -Bu belge, çok çeşitli yazılım servislerinin, yabancı ortamdaki deneyim ve gözlemlerini birleştirir. -Bu uygulama geliştirimindeki uygun, ideal uygulamalarda bir üçgenleştirme vardır; uygulamanın zamanla olan doğal gelişmesinin, büyümesinin temel etmenlerine dikkat etmek, uygulamanın kod tabanında çalışan yazılımcıların arasındaki işbirliğinin önemli noktaları ve yazılım erozyonunun getirdiği ücretten kaçmak. +Bu belge birçok yazılım servisinde edindiğimiz deneyim ve gözlemlerimizin bir sentezidir. Uygulama geliştirme aşamasındaki ideal pratiklerin, uygulamaların zaman içindeki organik büyüyüşlerine gösterilen özel ilginin, bir uygulamanın kodları üzerinde çalışan geliştiriciler arasındaki işbirliği dinamiklerinin, ve yazılım erozyonunun getirdiği masraftan kaçınmanın toplamı niteliğindedir. -Bizim motivasyonumuz, modern uygulama geliştirmesinde gördüğümüz bazı sistemik problemlerin farkındalığını arttırmak, terimlerle birlikte geniş kavramsal çözüm setleri sağlamak ve bu problemleri tartışmak için ortak bir kelime sunmakdır. Martin Fowler'ın kitabları *Patterns of Enterprise Application Architecture* ve *Refactoring'den* ilham alınmıştır. +Motivasyonumuz modern uygulama geliştirmelerinde gördüğümüz bazı sistemik problemlere olan farkındalığı arttırmak, bahsi geçen problemler için ortak bir terminoloji belirlemek, ve bu problemlere karşı bir dizi çözüm konsepti sunmaktır. Martin Fowler'ın kitapları olan *Patterns of Enterprise Application Architecture* ve *Refactoring*'den ilham alınmıştır. diff --git a/content/tr/intro.md b/content/tr/intro.md index b6c51b9ae..a0e7749b0 100644 --- a/content/tr/intro.md +++ b/content/tr/intro.md @@ -1,11 +1,11 @@ Giriş ========== -Modern çağda yazılımlar yaygın olarak servis olarak sunulur;*web uygulamaları* ya da *yazılım hizmetleri*. On iki faktörlü uygulama, aşağıdaki gibi bir yazılım hizmeti oluşturmak için bir yöntemdir: +Modern çağda yazılımlar çoğunlukla "web uygulaması" ya da "yazılım hizmeti" olarak isimlendirilen servisler olarak sunulurlar. *On iki faktörlü uygulama*, servis olarak çalışan yazılımlar (İng. *software as a service* veya *SaaS*) geliştirmek için bir yöntembilimdir. Bu yöntembilimin kuralları ve faydaları şunlardır: -* Projeye katılan yeni geliştiriciler için zaman ve maliyeti en aza indirmek için ayar otomasyonu için **bildirim** biçimleri kullanılır; -* Çalışma ortamları arasında maksimum taşınabilirlik sunan temel işletim sistemi ile **şifresiz sözleşmesi** vardır +* Projenin kurulum otomasyonu için **açıklayıcı** (İng. declarative) biçimler kullanır. Bu şekilde, projeye yeni katılan geliştiricilerin geliştirmeye başlama zamanını ve maliyetinı en aza indirir; +* Üzerinde çalıştığı işletim sistemi ile arasında **basit bir bağlılık** vardır. Bu, tüm çalıştırma ortamlarına (Docker gibi *container* sistemleri ve sıradan işletim sistemlerine) **maksimum uyumluluk** sağlar; * Sunucu ve sistem yönetimine olan ihtiyacı ortadan kaldıran modern **bulut platformlarına kurulum** için uygundur; -* İşlem, mimari veya geliştirme uygulamalarında önemli değişiklikler olmaksızın **ölçek büyültülebilir**. +* Kullanılan araçlarda, mimaride veya geliştirme pratiklerinde önemli değişikliklere gerek duymadan **ölçeklenebilir**. -On iki faktör uygulaması herhangi bir programlama dili ile yazılmış uygulamalara uygulanabilir ve destek servislerinin herhangi bir kombinasyonu kullanılabilir (Veritabanı, kuyruk, önbellek vb.). +On iki faktör uygulaması herhangi bir programlama dili ile yazılmış ve yardımcı (veritabanları, kuyruk işleyiciler, önbellek, vb. gibi) servislerin herhangi bir kombinasyonuna sahip tüm uygulamalara uygulanabilir. diff --git a/content/tr/toc.md b/content/tr/toc.md index a5f5bc5c1..89aec543a 100644 --- a/content/tr/toc.md +++ b/content/tr/toc.md @@ -1,35 +1,35 @@ On İki Faktör ============= -## [I. Kod Tabanı](./codebase) -### Bir çok dağıtım kod tabanı gözden geçirme kontrolünde izleme +## [I. Kod tabanı](./codebase) +### Versiyon kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım -## [II. Bağımlıklar](./dependencies) -### Bağımlıkları açık bir şekilde açıklama ve ayırma +## [II. Bağımlılıklar](./dependencies) +### Bağımlılıkların açıkça tanımlanması ve izole edilmesi ## [III. Yapılandırma](./config) -### Ortamda yapılandırma depolama +### Yapılandırma ayarlarını ortamda saklama -## [IV. Destek servisi](./backing-services) -### Destek servislerine ekli kaynak olarak davranma +## [IV. Yardımcı servisler](./backing-services) +### Yardımcı servislere iliştirilmiş kaynaklar olarak davranmak -## [V. Derleme, Sürüm, Çalıştırma](./build-release-run) +## [V. Derleme, yayınlama, çalıştırma](./build-release-run) ### Derleme ve çalıştırma aşamalarını tam olarak ayırma ## [VI. Süreç](./processes) -### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma +### Uygulamayı bir veya daha fazla bağımsız işlem olarak çalıştırma -## [VII. Port Bağlama](./port-binding) -### Port bağlama yolu üzerinden dışarı aktarma +## [VII. Port bağlama](./port-binding) +### Servisin portlar üzerinden sunulması -## [VIII. Eş Zamanlılık](./concurrency) -### Süreç modeli yardımıyla dağıtıklaştırma +## [VIII. Eş zamanlılık](./concurrency) +### Süreç modeli ile ölçeklendirme -## [IX. Kullanıma Hazır Olma Durumu](./disposability) -### Hızlı başlangıç ve otomatik zararsız kapama ile sağlamlığı üst düzeye çıkarma +## [IX. İmha edilebilirlik](./disposability) +### Hızlı başlangıç ve zararsız sonlanma ile maksimum servis sağlığı ## [X.Geliştirme/Üretim Eşitliği](./dev-prod-parity) -### Gelişim, evreleme ve üretimi olabildikçe benzer tutma +### Geliştirme, test etme ve gerçek çalışma ortamının birbirine olabildiğince benzer olması ## [XI. Günlükler](./logs) ### Günlüklere olay akışı gibi davranma diff --git a/content/tr/who.md b/content/tr/who.md index c87b0edca..2a539286f 100644 --- a/content/tr/who.md +++ b/content/tr/who.md @@ -1,4 +1,4 @@ Bu belgeyi kim okumalı? ======================= -Herhangi bir çalışan uygulama geliştirenler. Bu tür uygulamaları dağıtan ve yöneten Ops mühendisleri. +Servis yazılımı geliştiren tüm geliştiriciler. Bu tür uygulamaları yayınlayan ve yöneten operasyon mühendisleri. From 92837a0fa1f96393d91f64303441630b9153097e Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Wed, 22 Jul 2020 22:32:01 +0300 Subject: [PATCH 461/472] updated codebase page Turkish translations --- content/tr/codebase.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/content/tr/codebase.md b/content/tr/codebase.md index 73d68b7c3..f36dc0a7c 100644 --- a/content/tr/codebase.md +++ b/content/tr/codebase.md @@ -1,18 +1,17 @@ ## I. Kod Tabanı -### Bir çok dağıtım kod tabanı gözden geçirme kontrolünde izlenmeli +### Versiyon kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım -On iki faktör bir uygulama her zaman [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) veya [Subversion](http://subversion.apache.org/) gibi bir sürüm takip sistemiyle izlenir. VEritabanının gözden geçirme sisteminin bir kopyası *kod deposu* olarak bilinir. *kod repo* ya da sadece *repo* olarak kısaltılır. +On iki faktör bir uygulama her zaman [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) veya [Subversion](http://subversion.apache.org/) gibi bir versiyon kontrol sistemiyle izlenir. Bu versiyon kontrol sistemindeki dosya veritabanına kod deposu (İng. code repository) veya kısaca depo (İng. repo) denir. -Bir *kod tabanı* herhangi tek bir depo(Subversion gibi merkezi gözden geçirme kontrol sistemi) ya da kök işleyicini paylaşan bir takım repodur(Git gibi merkezi olmayan gözden geçirme kontrol sistemi). +Bir *kod tabanı*, tek bir depo (Subversion gibi merkezi versiyon kontrol sistemi) ya da kök *commit* paylaşan birden fazla depodan (Git gibi merkezi olmayan versiyon kontrol sistemi) oluşur. ![Bir kod tabanı bir çok dağıtımla eşlenir](/images/codebase-deploys.png) -Kod tabanı ve uygulama arasında bire-bir ilişki her zaman vardır: +Kod tabanı ve uygulama arasında her zaman birebir ilişki vardır: * Eğer birden fazla kod tabanı varsa bu bir uygulama değil, dağıtık sistemdir. Dağıtık sistemdeki her bileşen bir uygulamadır ve her biri on iki faktörle bireysel olarak uyumlu olmalıdır. * Aynı kodu paylaşan birden fazla uygulama, on iki faktörü ihlal eder. Burada çözüm, paylaşılan kodun [bağımlılık yöneticisi](./dependencies) aracılığıyla dahil edilebilecek kütüphanelere dönüştürülmesidir. +Uygulamanın sadece bir kod tabanı vardır fakat birden fazla dağıtımı olacaktır. Bir *dağıtım*, uygulamanın çalışan bir örneğidir. Bu dağıtımlar genelde bir gerçek ortam (İng. production) ve bir veya birkaç test ortamıdır. Ayrıca her geliştiricinin kendi yerel geliştirme ortamında çalışan bir kopyası vardır ve bunların her biri aynı zamanda dağıtım olarak nitelendirilirler. -Uygulamanın sadece bir kod tabanı vardır fakat birden fazla dağıtımı olacaktır. Bir *dağıtım*, uygulamanın çalışan bir örneğidir. Ayrıca her geliştiricinin kendi yerel geliştirme ortamında çalışan bir kopyası vardır ve bunların her biri aynı zamanda dağıtım olarak nitelendirilirler. - -Sürümler her bir dağıtımda etkin olabilir fakat kod temeli tüm dağıtımlarda aynıdır. Örneğin, geliştiricilerin henüz uygulamaya eklenmemiş commitleri olabilir. Bu nedenle hepsi ayrı dağıtım olarak tanımlanır ama kod tabanı aynıdır. +Dağıtımlarda anlık olarak farklı sürümler etkin olabilir fakat kod tabanı tüm dağıtımlarda aynıdır. Örneğin, bir geliştirici henüz commit'lemediği değişiklikleri çalıştırıyor olabilir, veya test ortamında henüz gerçek ortama dağıtılmamış bir sürüm çalışıyor olabilir. Bu nedenle hepsi ayrı dağıtım olarak tanımlanır ama kod tabanı aynıdır. From 1ee1b5fd31fdb8084da673799eba8141e21cd0ee Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Wed, 22 Jul 2020 22:32:13 +0300 Subject: [PATCH 462/472] updated dependencies page Turkish translations --- content/tr/dependencies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/tr/dependencies.md b/content/tr/dependencies.md index c85851f00..b4ac5d1df 100644 --- a/content/tr/dependencies.md +++ b/content/tr/dependencies.md @@ -1,12 +1,12 @@ ## II. Bağımlıklar -### Bağımlıkları açık bir şekilde açıklama ve ayırma +### Bağımlılıkların açıkça tanımlanması ve izole edilmesi -Çoğu programlama dili destek kitaplıklarını dağıtmak için bir paketleme sistemi sunar, Perl için [CPAN](http://www.cpan.org/), Ruby için [Rubygems](http://rubygems.org/). Bir paketleme sistemi aracılığıyla yüklenen kütüphaneler, sistem genelinde ("site paketleri" olarak bilinir) yüklenebilir veya uygulamanın bulunduğu dizine ("sağlayıcı" veya "paketleme" olarak bilinir) dahil edilebilir. +Çoğu programlama dili destek kütüphanelerini dağıtmak için bir paketleme sistemi sunar. Mesela Perl için [CPAN](http://www.cpan.org/), Ruby için [Rubygems](http://rubygems.org/). Bir paketleme sistemi aracılığıyla yüklenen kütüphaneler, sistem genelinde ("site paketleri" olarak bilinir) yüklenebilir veya uygulamanın bulunduğu dizine ("sağlayıcı" veya "paketleme" olarak bilinir) dahil edilebilir. -**On iki faktör bir uygulama asla sistem çapında paketlerin gizli var olmasına dayanmaz.** Bir *bağımlılık bildirimi* ile tüm bağımlılıkları tamamen ve eksiksiz olarak bildirir. Üstelik bağımlılıkların çevredeki sistemden sızmamasını sağlamak için yürütme sırasında bir *bağımlılık yalıtım* aracı kullanılır. Tam ve açık bağımlılık belirtimi hem üretim hem de geliştirme için eşit olarak uygulanmaktadır. +**On iki faktör bir uygulama asla bir sistem geneli paketin yüklü olduğunu varsaymaz.** Bir *bağımlılık bildirimi* manifestosu ile tüm bağımlılıkları tam ve eksiksiz olarak bildirir. Üstelik bağımlılıkların çevredeki sistemden sızmamasını sağlamak için çalıştırma sırasında bir *bağımlılık yalıtım* aracı kullanılır. Tam ve açık bağımlılık belirtimi hem üretim hem de geliştirme için eşit olarak uygulanmaktadır. -Örneğin, Ruby için [Bundler](https://bundler.io/), bağımlılık bildirimi için `Gemfile` manifest formatını ve bağımlılık yalıtımı için `bundle exec`'i önerir. Python'da bu adımlar için iki ayrı araç bulunur: [Pip](http://www.pip-installer.org/en/latest/), bildirimde ve [Virtualenv'de](http://www.virtualenv.org/en/latest/) yalıtımda kullanılır. C bile bağımlılık bildirimi için [Autoconf'a](http://www.gnu.org/s/autoconf/) sahiptir ve bağımlılık yalıtımı statik link ile sağlanır. Ne olursa olsun birbiriyle uyumlu çalışan yazılım uygulaması, bağımlılık bildirimi ve bağımlılık yalıtımı birlikte kullanılmalıdır, sadece herhangi birinin olması on iki faktör için yeterli değildir. +Örneğin, Ruby'nin [Bundler](https://bundler.io/)'ı, bağımlılık bildirimi için `Gemfile` manifesto formatını ve bağımlılık yalıtımı için `bundle exec`'i sunar. Python'da bu adımlar için iki ayrı araç bulunur: [Pip](http://www.pip-installer.org/en/latest/) bildirimde, [Virtualenv](http://www.virtualenv.org/en/latest/) de yalıtımda kullanılır. C bile bağımlılık bildirimi için [Autoconf](http://www.gnu.org/s/autoconf/)'a sahiptir ve bağımlılık yalıtımı statik link ile sağlanır. Ne olursa olsun birbiriyle uyumlu çalışan yazılım uygulaması, bağımlılık bildirimi ve bağımlılık yalıtımı birlikte kullanılmalıdır, sadece birinin olması on iki faktör için yeterli değildir. -Açık bağımlılık bildiriminin bir faydası da uygulamaya yeni olan geliştiriciler için kurulumu kolaylaştırır. Yeni geliştirici geliştirme aracında uygulamanın kod tabanını kontrol edebilir, ön koşul olarak dil çalıştırma platformu ve bağımlılık yöneticisinin yüklenmiş olmasını ister. Rastgele olmayan *derleme komutları* ile birlikte uygulama kodunun çalışması için ihtiyaç duyulan her şeyi yükleyebilecekler. Örneğin, Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) için `lein deps` iken, Ruby/Bundler için `bundle install`'dir. +Açık bağımlılık bildiriminin bir faydası da uygulamaya yeni katılan geliştiriciler için kurulumu kolaylaştırmasıdır. Yeni geliştirici bilgisayarında yalnızca programlama dilini ve bağımlılık yöneticisine sahip olarak uygulamanın kod tabanını indirebilir. Uygulamanın içindeki önceden belirlenmiş bir *derleme komutu* uygulama kodunun çalışması için ihtiyaç duyulan her şeyi yükleyebilecektir. Örneğin bu komut Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) için `lein deps` iken, Ruby/Bundler için `bundle install`'dur. -On iki faktör uygulamaları ayrıca herhangi bir sistem aracının kapalı olmasına güvenmez. Örnekler `ImageMagick` yada `curl` kullanımını içerir. Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına geçirilmesi gerekiyorsa, o aracın uygulamayı sağlaması gerekiyor. +On iki faktör uygulamaları herhangi bir sistem aracının yüklü olduğunu varsaymaz. Örnekler `ImageMagick` yada `curl` kullanımını içerir. Bu araçlar çoğu sistemde var olabilse de, uygulamanın gelecekte çalışabileceği sistemlerde bu araçların var olup olmayacağının veya bu araçların sürümlerinin uygulamayla uyumlu olup olmayacağının garantisi yoktur. Uygulamanın bir sistem aracına ihtiyacı oluşuyorsa, o aracın uygulamanın içine dahil edilmesi gerekir. From bb4c1afb5b44f06a47d86c5b60a811c4d7ccaf6c Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Wed, 22 Jul 2020 23:27:34 +0300 Subject: [PATCH 463/472] updated config page Turkish translations --- content/tr/config.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/content/tr/config.md b/content/tr/config.md index 37f39c1c7..deb115f93 100644 --- a/content/tr/config.md +++ b/content/tr/config.md @@ -1,22 +1,22 @@ ## III. Yapılandırma -### Ortamda yapılandırma depolama +### Yapılandırma ayarlarını ortamda saklama -Bir uygulamanın *yapılandırması* muhtemelen [dağıtımlar](./codebase) arasındaki değişikliktir(kademelendirme, ürün, geliştirici ortamları vb.). Bunları içerir: +Bir uygulamanın *yapılandırma ayarları* [dağıtımlar](./codebase) arasında farklı olma ihtimali olan her şeydir. Örneğin: -* Veri tabanını ele alan kaynaklar, önbellek ve diğer [destek servisleri](./backing-services) +* Veritabanlarının, önbellekleme servislerinin ve diğer [yardımcı servislerin](./backing-services) erişim bilgileri * Amazon S3 ve Twitter gibi dış servisler için kimlik bilgileri -* Dağıtımlar için standart sunucu ismi gibi her dağıtım için değerler +* Dağıtımlar için standart sunucu ismi gibi dağıtım-öncesi değerler -Uygulamalar bazen yapılandırmayı koddaki sabitler gibi saklar. Bu on iki faktörün, **yapılandırmayı koddan mutlak ayırmayı** gerektiren bir ihlalidir. Yapılandırma dağıtımlar arasında önemli derecede değişime uğrar, kod uğramaz. +Uygulamalar bazen yapılandırma ayarlarını kod içerisinde saklar. Bu on iki faktörün, **yapılandırmayı koddan mutlak ayrımını** gerektiren kuralın ihlalidir. Yapılandırma ayarları dağıtımlar arasında değişir, ama kod değişmez. -Bir uygulamanın tüm yapılandırmaları koddan doğru bir biçimde çıkarılıp çıkarılmadığına dair bir litot testi, herhangi bir kimlik bilgilerinden ödün vermeksizin kod tabanının her an açık kaynak yapıp yapamayacağına karar verir. +Bir uygulamanın herhangi bir kimlik bilgisinin gizliliğini ihlal etmeden açık kaynak yapılabilip yapılamayacak olması, tüm yapılandırmaları koddan doğru bir biçimde çıkarılıp çıkarılmadığını belirleyebilecek bir litmus testidir. -Bu *yapılandırma* tanımlamasının, [Spring](http://spring.io/)'de [kod modullerinin bağlantısında](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) olduğu gibi ve Rails'de `config/routes.rb` gibi dahili uygulama yapılandırmasını **içermediğini** unutmayın. Bu tip yapılandırma dağıtımlar arasında değişiklik göstermez ve bu kod içinde en iyi şekilde gerçekleştirilmiştir. +Bu *yapılandırma ayarı* tanımının, [Spring](http://spring.io/)'de [kod modüllerinin bağlantısında](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) olduğu gibi ve Rails'deki `config/routes.rb` gibi dahili uygulama yapılandırmasını **içermediğini** unutmayın. Bu tip yapılandırmalar, dağıtımlar arasında değişiklik göstermeyeceği için, kod içinde gerçekleştirilmeleri mantıklıdır. -Yapılandırmaya diğer bir yaklaşım Rails'deki `config/database.yml` gibi gözden geçirme kontrolünde kontrol edilmemiş yapılandırma dosyalarının kullanımıdır. Bu kod deposundaki kontrol edilmiş sabitlerin kullanımındaki büyük bir gelişmedir, fakat hala zayıflıkları vardır: Depoda, yapılandırma dosyalarının kontrolünde hata kolay yapılabilir; Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması için bir eğilim vardır, bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Bu formatların özel dil veya çatı olma eğilimi vardır. +Yapılandırmaya diğer bir yaklaşım da Rails'deki `config/database.yml` gibi dosyaların versiyon kontrol sistemine dahil edilmeden kullanımıdır. Bu, kod deposuna dahil edilmiş sabitler kullanmaya göre büyük bir gelişimdir, fakat hala zayıflıkları vardır: Bu dosyaların yanlışlıkla versiyon kontrol sistemine dahil edilme olasılığı oldukça yüksektir. Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması eğilimi mevcuttur, ve bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Dahası, bu formatlar genelde dil veya çatı için özelleşmiştir. -**On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir**(sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunda yanlışlıkla kontrol edilme şansı az; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. +**On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir** (sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunaa yanlışlıkla dahil edilme ihtimali düşüktür; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. -Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `üretim` ortamları gibi belirli dağıtımlardan sonra adlandırılmış, adlandrılmış guruplar içinde yapılandırılır(genellikle "environments" olarak adlandırılır). Bu method temiz bir ölçüm yapmaz: uygulamanın daha fazla dağıtımı oluştuğu sürece, yeni ortam isimleri gereklidir, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir, dağıtım yönetimini çok hassas yapan yapılandırmanın birleşimsel infilakıyla sonuçlanır. +Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `gerçek` ortamları gibi belirli dağıtımlardan sonra adlandırılmış gruplar içinde yapılandırılır. Bu yöntem temiz bir şekilde ölçeklenemez. Çünkü uygulamanın daha fazla dağıtımı oluştukça, yeni ortam isimleri gerekli olur, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir. Bu da yapılandırma dosyalarının hızla artmasıyla sonuçlanarak dağıtım yönetimini oldukça kırılganlaştırır. -On iki faktör uygulamasında ortam değişkenleri parçacıklı kontrol edilirler, her biri diğer ortam değişkenlerine karşı suffix/prefix olarak gelmez ayrı tanımlanır. Asla "environments" olarak beraber gruplandırılamaz, fakat onun yerine her bir dağıtım için bağımsız yönetilir. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca büyüten bir modeldir. +On iki faktör uygulamasında ortam değişkenleri parçacıklı kontrol edilirler, birbirlerinden bağımsızlardır. Asla gruplandırılmazlar, onun yerine her bir dağıtım için bağımsız olarak yönetilirler. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca ölçeklendiren bir modeldir. From 0e0544315a3f0b7c7267908f032a377fcd3fe873 Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Sat, 25 Jul 2020 11:22:14 +0300 Subject: [PATCH 464/472] updated intro and ToC --- content/tr/intro.md | 1 + content/tr/toc.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/content/tr/intro.md b/content/tr/intro.md index a0e7749b0..879ff1105 100644 --- a/content/tr/intro.md +++ b/content/tr/intro.md @@ -6,6 +6,7 @@ Modern çağda yazılımlar çoğunlukla "web uygulaması" ya da "yazılım hizm * Projenin kurulum otomasyonu için **açıklayıcı** (İng. declarative) biçimler kullanır. Bu şekilde, projeye yeni katılan geliştiricilerin geliştirmeye başlama zamanını ve maliyetinı en aza indirir; * Üzerinde çalıştığı işletim sistemi ile arasında **basit bir bağlılık** vardır. Bu, tüm çalıştırma ortamlarına (Docker gibi *container* sistemleri ve sıradan işletim sistemlerine) **maksimum uyumluluk** sağlar; * Sunucu ve sistem yönetimine olan ihtiyacı ortadan kaldıran modern **bulut platformlarına kurulum** için uygundur; +* Geliştirme ve canlı yayın ortamları arasında **farklılıklaşmayı minimize ederek**, maksimum çeviklik ile **sürekli dağıtımı**n önünü açar; * Kullanılan araçlarda, mimaride veya geliştirme pratiklerinde önemli değişikliklere gerek duymadan **ölçeklenebilir**. On iki faktör uygulaması herhangi bir programlama dili ile yazılmış ve yardımcı (veritabanları, kuyruk işleyiciler, önbellek, vb. gibi) servislerin herhangi bir kombinasyonuna sahip tüm uygulamalara uygulanabilir. diff --git a/content/tr/toc.md b/content/tr/toc.md index 89aec543a..21fa0389a 100644 --- a/content/tr/toc.md +++ b/content/tr/toc.md @@ -16,7 +16,7 @@ On İki Faktör ## [V. Derleme, yayınlama, çalıştırma](./build-release-run) ### Derleme ve çalıştırma aşamalarını tam olarak ayırma -## [VI. Süreç](./processes) +## [VI. İşlemler](./processes) ### Uygulamayı bir veya daha fazla bağımsız işlem olarak çalıştırma ## [VII. Port bağlama](./port-binding) @@ -29,7 +29,7 @@ On İki Faktör ### Hızlı başlangıç ve zararsız sonlanma ile maksimum servis sağlığı ## [X.Geliştirme/Üretim Eşitliği](./dev-prod-parity) -### Geliştirme, test etme ve gerçek çalışma ortamının birbirine olabildiğince benzer olması +### Geliştirme, test etme ve canlı yayın ortamının birbirine olabildiğince benzer olması ## [XI. Günlükler](./logs) ### Günlüklere olay akışı gibi davranma From 05001eced277062d2577f1c7ae43e96e85b76916 Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Sat, 25 Jul 2020 11:22:33 +0300 Subject: [PATCH 465/472] updated Turkish translation for 12 factors --- content/tr/admin-processes.md | 14 +++++++------- content/tr/backing-services.md | 16 ++++++++-------- content/tr/build-release-run.md | 18 +++++++++--------- content/tr/codebase.md | 4 ++-- content/tr/concurrency.md | 14 +++++++------- content/tr/config.md | 2 +- content/tr/dependencies.md | 2 +- content/tr/dev-prod-parity.md | 28 ++++++++++++++-------------- content/tr/disposability.md | 14 +++++++------- content/tr/logs.md | 16 ++++++++-------- content/tr/port-binding.md | 12 ++++++------ content/tr/processes.md | 16 ++++++++-------- 12 files changed, 78 insertions(+), 78 deletions(-) diff --git a/content/tr/admin-processes.md b/content/tr/admin-processes.md index 74b1e6bae..a6ef6d390 100644 --- a/content/tr/admin-processes.md +++ b/content/tr/admin-processes.md @@ -1,14 +1,14 @@ ## XII. Yönetici Süreci ### Yönetici/yönetim görevlerini tek seferlik işlem olarak çalıştırma -[Süreç oluşumu](./concurrency) uygulama çalışırken uygulamanın sıradan işlerini (web isteklerini idare etmek gibi) yapmakta kullanılan süreçlerin bir dizisidir. Ayrı olarak, geliştiriciler çoğunlukla uygulamanın bir kereye mahsus yönetimsel veya bakım görevlerini yapmayı dileyecekler, şunun gibi: +[İşlem formasyonu](./concurrency) uygulama çalışırken uygulamanın sıradan işlerini (web isteklerini idare etmek gibi) yapmakta kullanılan işlemlerin bir dizisidir. Ayrı olarak, geliştiriciler çoğunlukla uygulamanın bir kereye mahsus yönetimsel veya bakım görevlerini yapmayı dileyecekler. Örneğin: -* Veri tabanı göçü çalıştırmak (Django'da `manage.py migrate`, Rails'de `rake db:migrate`). -* Konsolu ([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) kabuğu olarakta bilinir), rastgele kodu çalıştırmak veya canlı veritabanına karşılık uygulamanın modellerini denetlemek için çalıştırmak. Çoğu dil hiç bir arguman olmadan (`python` veya `perl`), yorumlayıcı veya bazı durumlarda ayrı komutlarla (Ruby için `irb`, Rails için `rails console`) çalıştırarak bir REPL sağlar. -* Uygulamanın deposuna commit'lenmiş betikleri çalıştırmak (`php scripts/fix_bad_records.php`). +* Veritabanı değişikliklerini (İng. migrations) çalıştırmak (Django'da `manage.py migrate`, Rails'de `rake db:migrate`). +* Herhangi bir kodu çalıştırmak veya canlı yayın veritabanındaki verileri denetlemek için konsolu ([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) kabuğu olarak da bilinir) çalıştırmak. Çoğu dil hiçbir argüman olmadan (`python` veya `perl`), veya bazı durumlarda ayrı komutlarla (Ruby için `irb`, Rails için `rails console`) bir REPL sağlar. +* Uygulamanın kod deposundaki betikleri çalıştırmak (`php scripts/fix_bad_records.php`). -Bir kerelik yönetici süreçleri uygulamanın sıradan [uzun çalışan süreçleri](./processes) gibi aynı ortamlarda çalışmalıdır. Onlar herhangi bir sürecin çalıştığı gibi [sürüme](./build-release-run) karşı aynı [kod tabanı](./codebase) ve [yapılandırmayı](./config) kullanarak çalışır. Yönetici uygulama kodunu senkronizasyon sorunundan kaçınmak için yüklemelidir. +Bir kerelik yönetim işlemleri uygulamanın sıradan [işlemleri](./processes) ile aynı ortamlarda çalışmalıdır. Bu yönetim işlemleri de aynı [sürümdeki](./build-release-run) aynı [kod tabanı](./codebase) ve [yapılandırmayı](./config) kullanarak çalışır. Yönetim kodları da uygulama kodu ile aynı kod deposunda bulunmalıdır. -Aynı [bağımlılık yalıtımı](./dependencies) teknikleri bütün süreç yönetiminde kullanılmalıdır. Örneğin, eğer Ruby web süreçleri `bundle exec thin start` komutunu kullanıyorsa, veri tabanı göçü `bundle exec rake db:migrate` komutu kullanmalıdır. Aynı durumda, Virtualenv kullanan bir Python programı, Tornado web sunucusu ve herhangi bir `manage.py` yönetici süreçlerinin ikisini de çalıştırabilmek için `bin/python` kullanmalıdır. +Aynı [bağımlılık yalıtımı](./dependencies) teknikleri bütün işlem yönetiminde kullanılmalıdır. Örneğin, eğer Ruby web işlemleri `bundle exec thin start` komutunu kullanıyorsa, veritabanı göçü de `bundle exec rake db:migrate` komutu kullanmalıdır. Aynı durumda, Virtualenv kullanan bir Python programı, Tornado web sunucusu ve herhangi bir `manage.py` yönetici işlemlerinin ikisini de çalıştırabilmek için `bin/python` kullanmalıdır. -On iki faktör, REPL kabuğunu kural dışı sağlayan ve tek seferlik betikleri çalıştırmayı kolaylaştıran dilleri fazlasıyla destekler. Yerel dağıtımda, geliştiriciler uygulamanın kontrol dizinindeki açık kabuk komutuyla tek seferlik yönetici süreçlerini çalıştırır. Ürün dağıtımında, geliştiriciler bu gibi bir süreci çalıştırmak için ssh veya dağıtımın çalışma ortamı tarafından sağlanan diğer uzak komut çalıştırma mekanizmasını kullanabilir. +On iki faktör, REPL kabuğunu kendisi sağlayan ve tek seferlik betikleri çalıştırmayı kolaylaştıran dilleri fazlasıyla destekler. Yerel dağıtımda, geliştiriciler uygulamanın dizininde doğrudan komut satırında tek seferlik yönetici işlemlerini çalıştırır. Canlı yayın dağıtımında ise, geliştiriciler bu gibi bir işlemi çalıştırmak için ssh veya dağıtımın çalışma ortamı tarafından sağlanan diğer uzak komut çalıştırma mekanizmasını kullanabilir. diff --git a/content/tr/backing-services.md b/content/tr/backing-services.md index 9c0008049..36cc14ca8 100644 --- a/content/tr/backing-services.md +++ b/content/tr/backing-services.md @@ -1,14 +1,14 @@ -## IV. Destek servisi -### Destek servislerine ekli kaynak olarak davranma +## IV. Yardımcı servisler +### Yardımcı servislere iliştirilmiş kaynaklar olarak davranmak -Bir *destek servisi* uygulamanın kendi normal işleminin bir parçası olarak ağ üzerinden tüketim yapan bir servistir. Örnekler veri deposu([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlama/kuyruklama sistemleri( [RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](https://beanstalkd.github.io)), giden email için SMTP servisi([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemleri([Memcached](http://memcached.org/) gibi) içerir. +Bir *yardımcı servis* uygulamanın kendi işlevselliğinin bir parçası olarak ağ üzerinden tükettiği herhangi bir servistir. Örnekler veritabanları ([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlaşma/kuyruk sistemleri ([RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](https://beanstalkd.github.io)), e-posta göndermek için SMTP servisi ([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemlerini ([Memcached](http://memcached.org/) gibi) içerir. -Destek servisleri, veri tabanı gibi, uygulamaların çalışma zamanlı dağıtımlarında olduğu gibi benzer sistem yöneticileri tarafından geleneksel olarak yönetilirler. Bu yerel yönetilen servislere ilave olarak, uygulama üçüncü parti uygulamalar tarafından onaylanmış ve yönetilmiş servislere sahip olabilirler. Örnekler SMTP servisleri([Postmark](http://postmarkapp.com/) gibi), Metrik toplama servisleri( [New Relic](http://newrelic.com/) veya [Loggly](http://www.loggly.com/) gibi), binary servisler([Amazon S3](http://aws.amazon.com/s3/) gibi) ve API-erişilebilir tüketici servisleri bile [Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ve [Last.fm](http://www.last.fm/api) gibi) içerir. +Veritabanları gibi yardımcı servisler, geleneksel olarak uygulamayı da yöneten sistem yöneticileri tarafından yönetilirler. Ancak bu yerel servislere ilave olarak, uygulama üçüncü parti uygulamalar tarafından sağlanan ve yönetilen servislere de sahip olabilirler. Bunlardan bazıları; SMTP servisleri ([Postmark](http://postmarkapp.com/) gibi), metrik toplama servisleri ([New Relic](http://newrelic.com/) veya [Loggly](http://www.loggly.com/) gibi), statik içerik barındırma servisleri ([Amazon S3](http://aws.amazon.com/s3/) gibi) ve hatta API-erişilebilir tüketici servisleridir ([Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ve [Last.fm](http://www.last.fm/api) gibi). -**On iki faktör uygulaması için bu kod, yerel ve üçüncü parti servisler arasında ayrım yapmaz.** Uygulamada, her ikiside ek kaynaktır, [yapılandırmada](./config) saklanmış yer belirleyici/kimlik bilgileri ve URL aracılığıyla erişilir. On iki faktör uygulamasının bir dağıtımı, uygulama kodunda hiçbir değişiklik olmadan üçüncü parti([Amazon RDS](http://aws.amazon.com/rds/) gibi) tarafından yönetilenle yerel MySQL veritabanı silebilmelidir. Aynı şekilde bir yerel SMTP servisi(Postmark gibi), kod değişikliksiz bir üçüncü parti SMTP servisiyle değiş tokuş yapılabilir. Her iki durumda da, kaynak sadece değişmesi gereken yapılandırmada ele alınır. +**On iki faktör uygulamaları için bir servisin yerel veya üçüncü parti olmasının farkı yoktur.** Uygulama için, her ikisi de ek kaynaktır ve [yapılandırmada](./config) saklanmış URL'ler veya yer belirleyici ve kimlik bilgileri ikilisi aracılığıyla erişilir. On iki faktör uygulamasının bir dağıtımı, uygulama kodunda hiçbir değişiklik yapmak zorunda kalmadan yerel bir MySQL veritabanı kullanmaktan üçüncü parti bir veritabanı ([Amazon RDS](http://aws.amazon.com/rds/) gibi) kullanmaya geçebilmelidir. Aynı şekilde yerel bir SMTP servisinden (Postmark gibi), kod değişikliği olmaksızın bir üçüncü parti SMTP servisine geçiş yapılabilir. Her iki durumda da, değişmesi gereken şey sadece yapılandırma ayarlarındaki bağlantı bilgileridir. -Her bir belirgin destek servisi bir *kaynaktır*. Örneğin, bir MySQL veritabanı(Uygulama katmanında parçalanma için kullanılmış) bir kaynaktır; iki MySQL veritabanı iki belirgin kaynak olarak nitelendirilir. On iki faktör uygulaması veritabanlarına, bağlı oldukları dağıtımlara gevşek bağlaşımlarını belirten *ek kaynak* olarak davranır. +Her bir destek servisi bir *kaynaktır*. Örneğin, bir MySQL veritabanı bir kaynaktır; iki MySQL veritabanı (uygulama katmanında parçalanma [İng. sharding] için kullanılan) iki farklı kaynak olarak nitelendirilir. On iki faktör uygulaması bu veritabanlarına, bağlı oldukları dağıtımlara gevşek bağlaşımlarını belirten *ek kaynak* olarak davranır. -A production deploy attached to four backing services. +Canlı yayın dağıtımı dört destek servisine bağlanmış. -Kaynaklar dağıtımlara istenilen zamanda eklenilip çıkartılabilir. Örneğin, eğer uygulamanın veritabanı donanım sorununa göre yanlış davranıyorsa, uygulamanın yöneticisi son yedeklemeden geri yüklenmiş yeni bir veri tabanı sunucusunu döndürebilir. Şuanki veritabanı ekten çıkarılmış olabilir ve yeni veri tabanı eklenmiş olabilir, hiç bir kod değişikliği olmadan. +Kaynaklar dağıtımlara istenilen zamanda eklenilip çıkartılabilir. Örneğin, eğer uygulamanın veritabanı donanımsal sorunlar yaşıyorsa, uygulamanın yöneticisi son yedeklemeden geri yüklenmiş yeni bir veritabanı sunucusu oluşturabilir. Problemli veritabanının uygulamadan bağlantısı kesilip, yeni veritabanı bağlanabilir, hem de hiçbir kod değişikliği olmadan. diff --git a/content/tr/build-release-run.md b/content/tr/build-release-run.md index 3ba750c7a..edfdb5916 100644 --- a/content/tr/build-release-run.md +++ b/content/tr/build-release-run.md @@ -1,18 +1,18 @@ -## V. Derleme, Sürüm, Çalıştırma +## V. Derleme, yayınlama, çalıştırma ### Derleme ve çalıştırma aşamalarını tam olarak ayırma -Bir [kod tabanı](./codebase) üç aşamada dağıtıma dönüşebilir: +Bir [kod tabanı](./codebase) üç aşamada (geliştirme dağıtımı olmayan) dağıtıma dönüşür: -* *Derleme aşaması* kod deposunun *derleme* olarak bilinen çalıştırılabilir pakette çeviren bir dönüşümdür.Dağıtım süreci tarafından belirlenen bir commit'deki kodun versiyonunu kullanırken, derleme aşaması sağlayıcı [bağımlılıkları](./dependencies) getirir ve binary'leri derler. -* *Sürüm aşaması*, derleme aşaması tarafından üretilmiş derlemeyi alır ve dağıtımı şu anki [yapılandırmasıyla](./config) birleştirir. Son durumda oluşan *sürüm* derleme ve yapılandırmanın ikisinide içerir ve çalışma ortamındaki doğrudan çalıştırma için hazırdır. -* *Çalıştırma evresi* (aynı zamanda "runtime" olarak bilinir) seçili sürümün karşılığındaki uygulamanın [süreçlerini](./processes) bazı setlerini başlatarak, çalıştırma ortamındaki uygulamayı çalıştırır. +* *Derleme aşaması* kod deposunun *derleme* olarak bilinen çalıştırılabilir bir pakete çevrilmesidir. Dağıtım evresi tarafından seçilen commit'teki kod kullanılır. Sistem, üçüncü parti [bağımlılıkları](./dependencies) toparlar ve çalıştırılabilirleri ve statik dosyaları derler. +* *Yayınlama aşaması*, derleme aşaması tarafından üretilmiş derlemeyi alır ve dağıtımı güncel [yapılandırmasıyla](./config) birleştirir. Son durumda oluşan *yayın* derleme ve yapılandırmanın ikisini de içerir ve çalışma ortamında çalıştırmak için hazırdır. +* *Çalıştırma evresi* (aynı zamanda "runtime" olarak bilinir) seçili yayının karşılığındaki [işlemleri](./processes) başlatarak, çalıştırma ortamındaki uygulamayı çalıştırır. ![Kod, sürüm oluşturmak için yapılandırmayla birleşmiş derlemeye dönüşür.](/images/release.png) -**On iki faktör uygulamaları derleme,sürüm ve çalıştırma aşamaları arasında mutlak ayırmayı kullanır.** Örneğin, koddaki değişiklikleri derleme aşamasına geri döndürmenin bir yolu olmadığı için çalışma zamanında kodda değişiklik yapmak imkansızdır. +**On iki faktör uygulamalarının derleme, yayınlama ve çalıştırma aşamaları tamamen birbirinden bağımsızdır.** Örneğin, koddaki değişiklikleri derleme aşamasına geri döndürmenin bir yolu olmadığı için çalışma zamanında kodda değişiklik yapmak imkansızdır. -Dağıtım araçları genel olarak sürüm yönetim araçlarını önerir, en dikkat çekeni bir önceki sürüme geri dönme yeteneğidir. Örneğin, [Capistrano](https://github.com/capistrano/capistrano/wiki) dağıtım aracı sürümleri, şu anki sürümün şimdiki sürüm dizinine bir sembolik link olduğu, `releases` adlı alt dizinde depolar. `rollback` komutu, bir önceki sürüme hızlı geri dönüşü kolaylaştırır. +Dağıtım araçları genelde yayın yönetim araçları da sunar. En dikkat çeken yetenekleri ise bir önceki yayına geri dönebilmeleridir. Örneğin, [Capistrano](https://github.com/capistrano/capistrano/wiki) farklı yayınları `releases` adındaki bir alt dizinde depolar. Çalışıyor olan yayın ise bu alt dizinlerden birine oluşturulmuş bir kısayol dosyasıdır. Capistrano'nun `rollback` komutu, kısayol dosyasının işaret ettiği dizini değiştirerek önceki bir yayına dönüş yapmayı kolaylaştırır. -Her sürüm her zaman sürümlerin zaman damgası gibi (`2011-04-06-20:32:17` gibi) özel sürüm ID'sine veya artış numarasına (`v100` gibi) sahip olmalıdır. Sürümler yalnızca eklemeli bir defterdir ve bir kere oluşturulduğu zaman dönüştürülemez. Herhangi bir değişiklik yeni bir sürüm oluşturmalıdır. +Her yayın zaman damgası gibi (`2011-04-06-20:32:17` gibi) özel bir ID'ye veya her yeni yayında artan bir numaraya (`v100` gibi) sahip olmalıdır. Yayınlar yalnızca eklemeli bir defterdir ve bir kere oluşturulduğu zaman değiştirilemez. Herhangi bir değişiklik yeni bir yayın oluşturmalıdır. -Derlemeler, herhangi bir zamanda yeni kod dağıtıldığında uygulama geliştiricileri tarafından başlatılır. Çalışma zamanı yürütmesi, kontras tarafından, sunucu tekrar çalıştırılması veya çökmüş süreçlerin süreç yöneticisi tarafından tekrar başlatılması gibi durumlarda otomatik olarak olabilir. Bunun sonucunda, çalıştırma evresi, gecenin bir yarısında çalışan geliştiriciler yokken uygulamanın çalışmasını engelleyen problemler uygulamanın bozulmasına yol açabildiği için, olabildiği kadar az sayıda hareketli bölüm olarak tutulmalıdır. Derleme evresinde, hatalar dağıtımı çalıştıran geliştiriciler için her zaman ön planda olduğu için daha fazla karış olabilir. +Derlemeler, geliştiricilerin kod değişikliklerini kod depolarına yüklemesiyle başlatılır. Çalıştırma evresi ise, sunucuların yeniden başlatılması veya çökmüş işlemlerin tekrar ayağa kaldırılması gibi durumlarda otomatik olarak gerçekleştirilir. Bu yüzden çalıştırma evresi olabildiği kadar az sayıda hareketli parçaya sahip olmalıdır ki, gecenin bir yarısında, işinin başında olan hiçbir geliştirici yokken bozulmasın. Derleme evresi ise daha karmaşık olabilir, çünkü hatalar dağıtımı çalıştıran geliştiricilerin her zaman önündedir. diff --git a/content/tr/codebase.md b/content/tr/codebase.md index f36dc0a7c..73e80f139 100644 --- a/content/tr/codebase.md +++ b/content/tr/codebase.md @@ -12,6 +12,6 @@ Kod tabanı ve uygulama arasında her zaman birebir ilişki vardır: * Eğer birden fazla kod tabanı varsa bu bir uygulama değil, dağıtık sistemdir. Dağıtık sistemdeki her bileşen bir uygulamadır ve her biri on iki faktörle bireysel olarak uyumlu olmalıdır. * Aynı kodu paylaşan birden fazla uygulama, on iki faktörü ihlal eder. Burada çözüm, paylaşılan kodun [bağımlılık yöneticisi](./dependencies) aracılığıyla dahil edilebilecek kütüphanelere dönüştürülmesidir. -Uygulamanın sadece bir kod tabanı vardır fakat birden fazla dağıtımı olacaktır. Bir *dağıtım*, uygulamanın çalışan bir örneğidir. Bu dağıtımlar genelde bir gerçek ortam (İng. production) ve bir veya birkaç test ortamıdır. Ayrıca her geliştiricinin kendi yerel geliştirme ortamında çalışan bir kopyası vardır ve bunların her biri aynı zamanda dağıtım olarak nitelendirilirler. +Uygulamanın sadece bir kod tabanı vardır fakat birden fazla dağıtımı olacaktır. Bir *dağıtım*, uygulamanın çalışan bir örneğidir. Bu dağıtımlar genelde bir canlı yayın (İng. production) ve bir veya birkaç test ortamıdır. Ayrıca her geliştiricinin kendi yerel geliştirme ortamında çalışan bir kopyası vardır ve bunların her biri aynı zamanda dağıtım olarak nitelendirilirler. -Dağıtımlarda anlık olarak farklı sürümler etkin olabilir fakat kod tabanı tüm dağıtımlarda aynıdır. Örneğin, bir geliştirici henüz commit'lemediği değişiklikleri çalıştırıyor olabilir, veya test ortamında henüz gerçek ortama dağıtılmamış bir sürüm çalışıyor olabilir. Bu nedenle hepsi ayrı dağıtım olarak tanımlanır ama kod tabanı aynıdır. +Dağıtımlarda anlık olarak farklı sürümler etkin olabilir fakat kod tabanı tüm dağıtımlarda aynıdır. Örneğin, bir geliştirici henüz commit'lemediği değişiklikleri çalıştırıyor olabilir, veya test ortamında henüz canlı yayına dağıtılmamış bir sürüm çalışıyor olabilir. Bu nedenle hepsi ayrı dağıtım olarak tanımlanır ama kod tabanı aynıdır. diff --git a/content/tr/concurrency.md b/content/tr/concurrency.md index 0d9a628a0..519986129 100644 --- a/content/tr/concurrency.md +++ b/content/tr/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Eş Zamanlılık -### Süreç modeli yardımıyla dağıtıklaştırma +### İşlem modeli yardımıyla dağıtıklaştırma -Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha fazla süreç tarafından temsil edilir. Web uygulamaları çeşitli süreç çalışma formlarını alır. Örneğin, Php süreçleri Apache'nin çocuk süreçleri olarak çalışır, istek üzerine talep hacmine tarafından ihtiyaç duyulduğunda başlatılır. Java süreçleri, karşıt yaklaşımı benimser; JVM, başlangıçta çok sayıda sistem kaynağı (CPU ve bellek) ayıran büyük bir uber işlemi sağlar ve eşzamanlılık iş parçacıkları aracılığıyla dahili olarak yönetilir. Her iki durumda, çalışan süreçler, uygulamanın geliştiricilerine yalnızca minimum düzeyde görünürdür. +Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha fazla işlem tarafından temsil edilir. Web uygulamaları çeşitli işlem çalıştırma formlarına sahiptir. Örneğin, PHP işlemleri Apache'nin alt işlemi olarak çalışır, ve istek hacmine göre ihtiyaç duyuldukça başlatılır. Java işlemleri karşıt yaklaşımı benimser; JVM, başlangıçta büyük miktarda sistem kaynağı (CPU ve bellek) ayıran büyük bir işlemi başlatır, ve eşzamanlılık iş parçacıkları (İng. threads) aracılığıyla dahili olarak yönetilir. Her iki durumda, çalışan işlemler, uygulamanın geliştiricilerine minimum düzeyde görünürdür. -![Ölçek, çalışan süreçler olarak ifade edilir, iş yükü çeşitliliği, süreç tipi olarak tanımlanır.](/images/process-types.png) +![Ölçek, çalışan işlemler olarak ifade edilir, iş yükü çeşitliliği ise işlem tipi olarak tanımlanır.](/images/process-types.png) -**On iki faktör uygulamasında, süreçler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki süreçler [arka planda çalışan servis programları için olan unix süreç modelinden](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/) güçlü ipuçları alır. Bu modeli kullanarak geliştirici uygulamasını her bir tip işe bir *süreç tipi* atayarak, ayrı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web süreçleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi süreçler tarafından işlenir. +**On iki faktör uygulamasında, işlemler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki işlemler arkaplan servis programları çalıştırmak için olan [unix işlem modeli](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)nden güçlü ipuçları alır. Bu modeli kullanarak geliştirici, uygulamasının her iş tipini bir *işlem tipine* atayarak, farklı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web işlemleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi işlemler tarafından işlenir. -Bu, bireysel süreçlerin kendi dahili çoklu işlemelerini içermiyor değil, çalışma zamanı içindeki iş parçacıkları aracılığıyla VM, veya [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron model. Fakat bireysel VM yalnızca çok aşırı büyüyebilir (dikey ölçekte), bu yüzden uygulama aynı zamanda çoklu fiziksel makinelerde çalışan çoklu süreçleri içerebilmelidir. +Bu, çalışma zamanı (İng. runtime) içindeki iş parçacıkları veya [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) ve [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron/olay-bazlı model gibi, işlemlerin kendi çok-kanallılığını hariç tutmaz. Fakat bir sanal makinanın dikey ölçekte büyümesinin bir sınırı vardır. Bu yüzden uygulama aynı zamanda birden fazla fiziksel makinede çalışan çoklu işlemleri içerebilmelidir. -Bu süreç modeli, konu ölçeklendirme zamanına geldiğinde gerçekten çok başarılıdır. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama süreçleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir işlem olduğu anlamına gelir. Süreç tipleri dizisi ve her bir tipin süreçlerinin numarası *süreç oluşumu* olarak bilinir. +Bu işlem modeli, konu ölçeklendirmeye geldiğinde gerçekten farkını ortaya koyar. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama işlemleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir iş olduğu anlamına gelir. İşlem tipleri dizisi ve her bir tipin işlem sayısı *işlem formasyonu* olarak bilinir. -On iki faktör uygulama süreçleri [asla arka planda çalışmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyalarını yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş süreçlere cevap vermek, kullanıcı başlatımlı tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin süreç yöneticisine( [systemd](https://www.freedesktop.org/wiki/Software/systemd/) gibi bulut platformunda yayınlanmış süreç yöneticisi veya geliştirme sürecinde [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar ) dayanır. +On iki faktör uygulama işlemleri [asla arkaplan işlemleri başlatmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyaları yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş işlemlere cevap vermek, kullanıcı sebepli tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin işlem yöneticisine ([systemd](https://www.freedesktop.org/wiki/Software/systemd/) gibi bulut platformunda yayınlanmış işlem yöneticisi veya geliştirme sırasında [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar) dayanır. diff --git a/content/tr/config.md b/content/tr/config.md index deb115f93..99e0bd6fe 100644 --- a/content/tr/config.md +++ b/content/tr/config.md @@ -17,6 +17,6 @@ Yapılandırmaya diğer bir yaklaşım da Rails'deki `config/database.yml` gibi **On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir** (sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunaa yanlışlıkla dahil edilme ihtimali düşüktür; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. -Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `gerçek` ortamları gibi belirli dağıtımlardan sonra adlandırılmış gruplar içinde yapılandırılır. Bu yöntem temiz bir şekilde ölçeklenemez. Çünkü uygulamanın daha fazla dağıtımı oluştukça, yeni ortam isimleri gerekli olur, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir. Bu da yapılandırma dosyalarının hızla artmasıyla sonuçlanarak dağıtım yönetimini oldukça kırılganlaştırır. +Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `canlı` ortamları gibi belirli dağıtımlardan sonra adlandırılmış gruplar içinde yapılandırılır. Bu yöntem temiz bir şekilde ölçeklenemez. Çünkü uygulamanın daha fazla dağıtımı oluştukça, yeni ortam isimleri gerekli olur, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir. Bu da yapılandırma dosyalarının hızla artmasıyla sonuçlanarak dağıtım yönetimini oldukça kırılganlaştırır. On iki faktör uygulamasında ortam değişkenleri parçacıklı kontrol edilirler, birbirlerinden bağımsızlardır. Asla gruplandırılmazlar, onun yerine her bir dağıtım için bağımsız olarak yönetilirler. Bu, uygulamayı yaşam süresi boyunca daha fazla dağıtıma genişletmeyi sorunsuzca ölçeklendiren bir modeldir. diff --git a/content/tr/dependencies.md b/content/tr/dependencies.md index b4ac5d1df..017302353 100644 --- a/content/tr/dependencies.md +++ b/content/tr/dependencies.md @@ -3,7 +3,7 @@ Çoğu programlama dili destek kütüphanelerini dağıtmak için bir paketleme sistemi sunar. Mesela Perl için [CPAN](http://www.cpan.org/), Ruby için [Rubygems](http://rubygems.org/). Bir paketleme sistemi aracılığıyla yüklenen kütüphaneler, sistem genelinde ("site paketleri" olarak bilinir) yüklenebilir veya uygulamanın bulunduğu dizine ("sağlayıcı" veya "paketleme" olarak bilinir) dahil edilebilir. -**On iki faktör bir uygulama asla bir sistem geneli paketin yüklü olduğunu varsaymaz.** Bir *bağımlılık bildirimi* manifestosu ile tüm bağımlılıkları tam ve eksiksiz olarak bildirir. Üstelik bağımlılıkların çevredeki sistemden sızmamasını sağlamak için çalıştırma sırasında bir *bağımlılık yalıtım* aracı kullanılır. Tam ve açık bağımlılık belirtimi hem üretim hem de geliştirme için eşit olarak uygulanmaktadır. +**On iki faktör bir uygulama asla bir sistem geneli paketin yüklü olduğunu varsaymaz.** Bir *bağımlılık bildirimi* manifestosu ile tüm bağımlılıkları tam ve eksiksiz olarak bildirir. Üstelik bağımlılıkların çevredeki sistemden sızmamasını sağlamak için çalıştırma sırasında bir *bağımlılık yalıtım* aracı kullanılır. Tam ve açık bağımlılık belirtimi hem canlı yayın hem de geliştirme için eşit olarak uygulanmaktadır. Örneğin, Ruby'nin [Bundler](https://bundler.io/)'ı, bağımlılık bildirimi için `Gemfile` manifesto formatını ve bağımlılık yalıtımı için `bundle exec`'i sunar. Python'da bu adımlar için iki ayrı araç bulunur: [Pip](http://www.pip-installer.org/en/latest/) bildirimde, [Virtualenv](http://www.virtualenv.org/en/latest/) de yalıtımda kullanılır. C bile bağımlılık bildirimi için [Autoconf](http://www.gnu.org/s/autoconf/)'a sahiptir ve bağımlılık yalıtımı statik link ile sağlanır. Ne olursa olsun birbiriyle uyumlu çalışan yazılım uygulaması, bağımlılık bildirimi ve bağımlılık yalıtımı birlikte kullanılmalıdır, sadece birinin olması on iki faktör için yeterli değildir. diff --git a/content/tr/dev-prod-parity.md b/content/tr/dev-prod-parity.md index c20be1f2b..469aef692 100644 --- a/content/tr/dev-prod-parity.md +++ b/content/tr/dev-prod-parity.md @@ -1,17 +1,17 @@ ## X.Geliştirme/Üretim Eşitliği -### Gelişim, evreleme ve üretimi olabildikçe benzer tutma +### Geliştirme, test etme ve canlı yayın ortamının birbirine olabildiğince benzer olması -Tarihsel olarak, geliştirme (bir geliştirici uygulamanın yerel [dağıtımına](./codebase) canlı düzenlemeler yapar) ve ürün (uygulamanın çalışan dağıtımı son kullanıcılar tarafından erişilmiştir) arasında önemli aralıklar vardır. Bu aralıklar üç alanda belirtilir: +Tarihsel olarak, geliştirme ortamı (geliştiricinin uygulamanın yerel [dağıtımına](./codebase) anlık düzenlemeler yaptığı) ve canlı yayın (uygulamanın son kullanıcılar tarafından erişilen çalışan dağıtımı) arasında önemli aralıklar olurdu. Bu aralıklar üç alanda belirtilir: -* **Zaman aralığı:** bir geliştirici kod üzerinde günler,haftalar hatta aylar boyunca bile ürünü oluşturmak için çalışabilir. -* **Eleman aralığı:** Geliştiriciler kod yazar, ops mühendisleri dağıtır. -* **Araçların aralığı:** Geliştiriciler ürün dağıtımı Apache, MySQL ve Linux kullanırken; Nginx, SQLite, ve OS X gibi yığınları kullanıyor olabilir. +* **Zaman aralığı:** bir geliştirici kod üzerinde günler, haftalar hatta aylar boyunca bile çalışabilir. +* **Çalışan aralığı:** Geliştiriciler kod yazar, operasyon mühendisleri dağıtımını sağlar. +* **Araçların aralığı:** Geliştiriciler Apache, MySQL ve Linux kullanırken; canlı yayında Nginx, SQLite, ve OS X gibi teknolojiler kullanıyor olabilir. -**On iki faktör uygulaması, geliştirme ve ürün aralığını küçük tutarak, [sürekli dağıtım](http://avc.com/2011/02/continuous-deployment/) için tasarlanmıştır.** Yukarda tanımlanan üç aralığa bakarsak: +**On iki faktör uygulaması, geliştirme ve canlı yayın aralığını küçük tutarak, [sürekli dağıtım](http://avc.com/2011/02/continuous-deployment/) için tasarlanmıştır.** Yukarda tanımlanan üç aralığa bakarsak: * Zaman aralığını küçültme: bir geliştirici kod yazabilir ve bu kodu saatler veya hatta dakikalar sonra dağıtmış olabilir. -* Eleman aralığını küçültme: kodu yazan geliştiriciler, kodu dağıtmakla yakından ilişkilidir ve üründeki davranışını izler. -* Araçların aralığını küçültme: geliştirmeyi ve ürünü olabildiği kadar benzer tut. +* Eleman aralığını küçültme: kodu yazan geliştiriciler, kodu dağıtmakla ve canlı yayındaki davranışını izlemekle yakından ilişkilidir. +* Araçların aralığını küçültme: geliştirmeyi ve canlı yayını olabildiği kadar benzer tut. Üstekileri bir tablo olarak özetlersek: @@ -32,13 +32,13 @@ Tarihsel olarak, geliştirme (bir geliştirici uygulamanın yerel [dağıtımın Aynı insanlar - Geliştirme ve ürün ortamı + Geliştirme ve canlı yayın ortamı Farklı Olabildiğince benzer -[Destek servisler](./backing-services); uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi, geliştirme/üretim eşitliğinin önemli olduğu bir alandır. Bir çok dil, farklı tipteki servislerin *uyarlayıcılarını* içeren, destek servislerine ulaşımı kolaylaştıran kütüphanleri önerir. Bazı örnekler aşağıdaki tabloda vardır. +Uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi [destek servisleri](./backing-services), geliştirme/canlı yayın eşitliğinin önemli olduğu bir alandır. Birçok dil, farklı tipteki servislerin *uyarlayıcılarını* (adaptörlerini) içeren, destek servislerine ulaşımı kolaylaştıran kütüphaneler önerir. Bazı örnekler aşağıdaki tabloda vardır. @@ -67,10 +67,10 @@ Tarihsel olarak, geliştirme (bir geliştirici uygulamanın yerel [dağıtımın
-Geliştiriciler, üründe ciddi ve sağlam destek servisleri kullanırken, bazen kendi yerel ortamlarında önemsiz destek servislerini kullanmak için istek duyarlar. Örneğin, yerelde SQLite üründe PostgreSQL kullanılır veya geliştirmede depolama için yerel süreç belleği ve üründe de Memcached kullanılır. +Geliştiriciler, canlı yayında daha ciddi ve sağlam destek servisleri kullanırken, bazen kendi yerel ortamlarında hafif destek servislerini kullanmak isterler. Örneğin, yerelde SQLite, canlı yayında ise PostgreSQL kullanılır, veya yerelde depolama için işlem belleği, canlı yayında ise Memcached kullanılır. -**On iki faktör geliştiricisi**, uyarlayıcılar teorik olarak destek servislerindeki herhangi bir farklılığı soyutladığı zaman bile **geliştirme ve ürün arasında faklı destek servisi kullanma isteğine karşı direnir.** Destek hizmetleri arasındaki farklılıklar, küçük uyumsuzlukların ortaya çıkması, kodun işe yaraması ve geliştirme aşamasında testlere geçilmesi veya üretimde başarısız olmaya neden olması anlamına gelir. Bu tür hatalar, sürekli dağıtımın etkisini azaltan bir sürtüşme yaratır. Bu sürtünme maliyeti ve sonraki devamlı dağıtımın azaltılması, bir uygulamanın ömrü süresince toplamda düşünüldüğünde oldukça yüksektir. +**On iki faktör geliştiricisi**, uyarlayıcılar teorik olarak destek servislerindeki herhangi bir farklılığı soyutluyor olsa bile, **geliştirme ve canlı yayın arasında faklı destek servisi kullanma isteğine karşı direnir.** Destek hizmetleri arasındaki farklılıklar, küçük uyumsuzlukların ortaya çıkmasına, yerelde çalışan ve testleri geçen kodun, canlı yayında başarısız olmaya neden olmasına sebep olabilir. Bu tür hatalar, sürekli dağıtıma köstek olan bir sürtünme yaratır. Bu sürtünme maliyeti ve sonraki devamlı dağıtımın azaltılması, bir uygulamanın ömrü süresince toplamda düşünüldüğünde oldukça yüksektir. -Önemsiz yerel servisler bir zamanlar olduğundan daha zorlayıcıdır. Memcached, PostgreSQL ve RabbitMQ gibi modern destek servisleri, [Homebrew](http://mxcl.github.com/homebrew/) ve [apt-get](https://help.ubuntu.com/community/AptGet/Howto) gibi modern paket sistemleri sayesinde yüklemesi ve çalıştırılması zor değildir. Alternatif olarak, [Chef](http://www.opscode.com/chef/) ve [Puppet](http://docs.puppetlabs.com/) gibi bildiri sağlayıcı araçlar önemsiz sanal ortamlarla birleşir, [Vagrant](http://vagrantup.com/) gibi, geliştiricilerin yerel ortamda çalışmalarına izin verir, yaklaşık olarak ürün ortamına benzer. Bu sistemlerin yüklenmesi ve kullanımının maliyeti, geliştirme üretim eşitliği ve sürekli dağıtımın faydasıyla karşılaştırıldığında düşüktür. +Hafif yerel servisler eskiye göre daha az çekicidir. Memcached, PostgreSQL ve RabbitMQ gibi modern destek servisleri, [Homebrew](http://mxcl.github.com/homebrew/) ve [apt-get](https://help.ubuntu.com/community/AptGet/Howto) gibi modern paket sistemleri sayesinde kolayca yüklenebilir ve çalıştırılabilir. Alternatif olarak, [Chef](http://www.opscode.com/chef/) ve [Puppet](http://docs.puppetlabs.com/) gibi ortam hazırlayıcı araçlar, ve [Vagrant](http://vagrantup.com/) ve [Docker](https://www.docker.com/) gibi hafif sanal ortam sağlayıcıları, geliştiricilerin canlı yayın ortamına çok benzeyen yerel ortamda çalışabilmelerini sağlar. Bu sistemlerin yüklenmesi ve kullanımının maliyeti, geliştirme ve canlı yayın eşitliği ve sürekli dağıtımın faydasıyla karşılaştırıldığında oldukça düşüktür. -Farklı destek servislerinin uyarlayıcıları hala kullanışlıdır, çünkü yeni destek servislerine bağlanmayı nispeten zahmetsiz yapar. Ama uygulamanın bütün dağıtımları (geliştirme ortamları, evreleme, ürün) her bir destek servisinin aynı tip ve versiyonunu kullanmalıdır. +Farklı destek servislerinin uyarlayıcıları hala kullanışlıdır, çünkü yeni destek servislerine bağlanmayı nispeten zahmetsiz yapar. Ama uygulamanın bütün dağıtımları (geliştirme, test, canlı yayın ortamları) her bir destek servisinin aynı tip ve versiyonunu kullanmalıdır. diff --git a/content/tr/disposability.md b/content/tr/disposability.md index 05c4ac759..b8b53850a 100644 --- a/content/tr/disposability.md +++ b/content/tr/disposability.md @@ -1,12 +1,12 @@ -## IX. Kullanıma Hazır Olma Durumu -### Hızlı başlangıç ve otomatik zararsız kapama ile sağlamlığı üst düzeye çıkarma +## IX. İmha edilebilirlik +### Hızlı başlangıç ve zararsız sonlanma ile maksimum servis sağlığı -**On iki faktör uygulamalarını [süreçleri](./processes) *tek kullanımlıktır*, anlamı anlık uyarıda başlatılabilirler veya durdurulabilirler.** Bu hızlı esnek ölçeklemeyi, [kod](./codebase) ve [yapılandırma](./config) değişikliğinin hızlı dağıtımı ve üretim dağıtımının sağlamlığı kolaylaştırır. +**On iki faktör uygulamalarının [işlemleri](./processes) *tek kullanımlıktır*, yani anlık olarak başlatılabilir ve durdurulabilirler.** Bu hızlı esnek ölçeklemeyi, [kod](./codebase) ve [yapılandırma](./config) değişikliklerinin hızlı dağıtımı ve canlı yayın dağıtımlarının sağlamlığını arttırır. -Süreçler **başlangıç zamanını küçültmeye* çabalamalıdır. İdeal olarak, bir süreç başlatma komutunun çalıştırılıp, sürecin ayağa kalkmış ve istek veya işleri almaya hazır olana kadar olan süre bir kaç saniye alır. Kısa başlama zamanı [sürüm](./build-release-run) süreci ve arttırım için daha fazla çabukluk sağlar; ve sağlamlığına yardımcı olur, çünkü süreç yöneticisi izin verildiğinde süreçleri yeni fiziksel makinelere daha kolay taşıyabilir. +İşlemler **başlangıç zamanını küçültmeye** çabalamalıdır. İdeal olarak, bir işlemin başlatma komutunun çalıştırılmasından, işlemin ayağa kalkmış ve istek/işleri karşılamaya hazır hale gelmesine kadar olan süre bir kaç saniyedir. Kısa başlama zamanı [yayınlama](./build-release-run) işlemi ve ölçeklenme için daha fazla çeviklik sağlar; ve sağlamlığına yardımcı olur, çünkü işlem yöneticisi işlemleri yeni fiziksel makinelere daha kolay taşıyabilir. -Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, incelikli kapanır.** Web süreci için incelikli kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), herhangi bir o anki isteklerin bitmesine izin verilmesi ve daha sonra çıkılmasıyla sonuçlanır. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. +İşlemler, işlem yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, kontrollü şekilde kapanırlar.** Bir web işlemi için kontrollü kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), eğer varsa o an işleniyor olan isteğin tamamlanmasına izin verilmesi ve daha sonra işlemin sonlandırılması şeklinde gerçekleşir. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. -Bir işçi süreç için incelikli kapama şu anki işi iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda çalışan oturumu kapattığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, iş kayıdındaki kilitlerini yayınlamak için emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişlidir] [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29), genellikle sonuçların işlemde saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. +Bir işçi işlem için kontrollü kapama, güncel işin iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) sinyali gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda işçi işlem bağlantıyı kopardığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, üzerinde çalışıyor oldukları işin kilitlerini kaldırdıklarından emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişli](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)dir, genellikle sonuçların bir transaksiyonda (İng. transaction) saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. -Süreçler esas donanımdaki hata durumlarında **ani kapanmaya karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile incelikli kapamadan daha az yaygın bir olay olduğu için hala olabilir. Önerilen yaklaşım sağlam arkaplan kuyruklama kullanımıdır, Beanstalkd gibi, istemciler oturumu kapattığı zaman veya süre dolduğu zaman işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması incelikli olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only dezaynı](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucunu](http://docs.couchdb.org/en/latest/intro/overview.html) alır. +İşlemler, donanımsal sorun oluşması gibi durumlarda oluşacak **ani sonlanmalara karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile kontrollü kapamadan daha az yaygın bir olaydır, ancak yine de gerçekleşebilir. Önerilen yaklaşım, Beanstalkd gibi sağlam arkaplan kuyruklama sistemlerinin kullanımıdır. Bu sistemler, istemciler oturumu kapattığı zaman veya süre aşımı durumlarında işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması kontrollü olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only tasarım](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucu](http://docs.couchdb.org/en/latest/intro/overview.html)na ulaştırır. diff --git a/content/tr/logs.md b/content/tr/logs.md index e8d61b386..52e51056d 100644 --- a/content/tr/logs.md +++ b/content/tr/logs.md @@ -1,16 +1,16 @@ ## XI. Günlükler ### Günlüklere olay akışı gibi davranma -*Günlükler* çalışan bir uygulamanın davranışının görünür olmasını sağlar. Sunucu tabanlı ortamlarda genellikle diskteki bir dosyaya yazılırlar("logfile"); ama bu sadece çıktı formatındadır. +*Günlükler* çalışan bir uygulamanın davranışlarını izleyebilme imkanı sağlar. Sunucu tabanlı ortamlarda genellikle diskteki bir dosyaya yazılırlar (ve bunlara log dosyası denir); ama bu sadece bir çıktı formatıdır. -Günlükler, bütün çalışan süreçler ve destek servislerinin çıktı akışlarından kümelenmiş, zaman sıralı olayların [akışıdır](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/). Günlükler ilk formda her bir satır için bir olay olacak şekilde yazı formatındadır(Bununla birlikte istisnalardaki geri dönüşleri birden fazla satırda ölçebilir). Günlükler başta ve sonda düzeltilmemiş ama akış, uygulama işlediği sürece devam eder. +Günlükler, bütün çalışan işlemler ve destek servislerinin çıktı akışlarından kümelenmiş, zaman sıralı olayların [akışıdır](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/). Günlükler en ham haliyle her bir satırda bir olay içeren yazı formatındadır (ancak hata kayıtlarındaki detaylar birden fazla satıra yayılabilir). Günlüklerin belirlenmiş bir başlangıcı ve sonu yoktur, uygulama işlediği sürece akış devam eder. -**On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Günlük dosyalarını yazma ve yönetme yapmamalıdır. Bunun yerine, her çalışan süreç kendi olay akışını tamponlamadan `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinin önplanında bu akışı inceleyecekler. +**On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Log dosyalarını yazma ve yönetme yapmamalıdır. Bunun yerine, her çalışan işlem kendi olay akışını tamponlamadan `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinde bu akışı inceleyebilirler. -Evreleme ve ürün dağıtımlarında herbir sürecin akışı çalışma ortamı tarafından yakalanmış diğer uygulamadaki, diğer bütün akışlarla birlikte sıralanmış, görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilmiş olacaklar. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, bunun yerine tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak günlük yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluentd](https://github.com/fluent/fluentd) gibi) bu amaç için erişilebilirdir. +Test ve canlı yayın dağıtımlarında her bir sürecin akışı çalışma ortamı tarafından yakalanır, diğer bütün akışlarla birleştirilir, ve görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilirler. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak log yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluentd](https://github.com/fluent/fluentd) gibi) bu amaç için kullanılabilir. -Bir uygulama için olay akışı dosyaya yönlendirilebilir veya terminalden gerçek zamanlı kuyruklama aracılığla izlenebilir. En önemlisi, akış [Splunk](http://www.splunk.com/) gibi günlük numaralandırma ve analiz sistemine veya [Hadoop/Hive](http://hive.apache.org/) gibi genel amaçlı veri depolama sistemine gönderilebilir. Bu sistemler uygulamanın zamanla olan davranışlarında iç gözlem yapmak için büyük güç ve esnekliğe izin verir. Bunları içerir: +Bir uygulamanın olay akışı dosyaya yönlendirilebilir veya terminalden gerçek zamanlı olarak izlenebilir. En önemlisi, akış [Splunk](http://www.splunk.com/) gibi log saklama ve analiz sistemine veya [Hadoop/Hive](http://hive.apache.org/) gibi genel amaçlı bir veri depolama sistemine gönderilebilir. Bu sistemler uygulamanın zaman içindeki davranışlarında gözlem yapmak için büyük güç ve esneklik sağlar. Örneğin: -* Geçmişteki özel olayları bulmak. -* Eğilimlerin geniş aralıklı grafikleri(her bir dakika için olan istekler gibi). -* Kullanıcı tanımlı kestirme yollara göre aktif uyarma(Bir dakikadaki hataların niceliği belirli bir alt sınırı geçtiği zaman olan uyarı gibi). +* Geçmişteki spesifik olayları bulmak. +* Eğilimlerin geniş aralıklı grafikleri (her bir dakika için olan istekler gibi). +* Kullanıcı tanımlı davranışları algılayıp aktif uyarı sağlama (Bir dakikadaki hataların miktarı belirli bir alt sınırı geçtiği zaman olan uyarı gibi). diff --git a/content/tr/port-binding.md b/content/tr/port-binding.md index cf1cb1313..5b8f12c58 100644 --- a/content/tr/port-binding.md +++ b/content/tr/port-binding.md @@ -1,14 +1,14 @@ ## VII. Port Bağlama ### Port bağlama yolu üzerinden dışarı aktarma -Web uygulamaları bazı zamanlar web sunucu taşıyıcıları içinde çalıştırılırlar. Örneğin, PHP uygulamaları modül olarak [Apache HTTPD](http://httpd.apache.org/) içinde veya Java uygulamaları [Tomcat](http://tomcat.apache.org/) içinde çalıştırılabilirler. +Web uygulamaları bazen web sunucu taşıyıcıları içinde çalıştırılırlar. Örneğin, PHP uygulamaları modül olarak [Apache HTTPD](http://httpd.apache.org/) içinde veya Java uygulamaları [Tomcat](http://tomcat.apache.org/) içinde çalıştırılabilirler. -**On iki faktör uygulama tamamen bağımsız** ve web dönüştürme servisi oluşturmak için çalışma ortamı içindeki web sunucunun çalışma zamanlı enjeksiyonuna dayanmaz. Bu web uygulaması port bağlama tarafından HTTP'yi servis olarak dışa aktarır ve o porta gelen istekleri dinler. +**On iki faktör uygulama tamamen kendi kendine yeterlidir** ve web'e açılan bir servis sunmak için çalıştırma ortamına başka bir web sunucusu enjekte edilmesini beklemez. Bu web uygulaması servisini HTTP üzerinden bir porta bağlanarak sunar ve o porta gelen istekleri dinler. -Yerel geliştirme ortamında, geliştiriciler `http://localhost:5000/` gibi servis URL'ini, onların duygulamaları tarafından dışa aktarılan servise erişmek için ziyaret ederler. Dağıtımda, yönlendirme katmanı dışa bakan makine adından port bağımlı web süreçlerine gelen yönlendirme isteklerini ele alır. +Yerel geliştirme ortamında, geliştiriciler uygulamanın servislerine ulaşmak için `http://localhost:5000/` gibi bir URL'yi ziyaret eder. Dağıtımda, bir yönlendirme katmanı halka açık bir adrese gelen istekleri karşılayıp porta bağlanmış web işlemlerine aktarırlar. -Bu tipik olarak, uygulamaya web sunucusu kütüphanesi eklemek için bağımlılık tanımlaması kullanılarak geliştirilmiştir, Python için [Tornado](http://www.tornadoweb.org/), Ruby için [Thin](http://code.macournoyer.com/thin/) veya Java ve diğer JVM-tabanlı diller için [Jetty](http://jetty.codehaus.org/jetty/). Bu uygulamanın kodu içinde *kullanıcı alanında* gerçekleşir. Çalışma ortamıyla olan anlaşma isteklere hizmet veren bir porta bağlıdır. +Uygulamalar web sunucusu özelliği edinmek için genellikle [bağımlılık tanımlaması](./dependencies) kullanarak Python için [Tornado](http://www.tornadoweb.org/), Ruby için [Thin](http://code.macournoyer.com/thin/) veya Java ve diğer JVM-tabanlı diller için [Jetty](http://jetty.codehaus.org/jetty/) gibi kütüphaneler kullanırlar. Bu, *kullanıcı alanında* yani uygulamanın kodu içinde gerçekleşir. Çalışma ortamıyla olan anlaşma isteklere hizmet veren bir porta bağlanmaktır. -HTTP port bağlama ile dışarı aktarılabilen tek servis değildir. Nerdeyse herhangi bir sunucu yazılım tipi port için süreç bağlama aracılığıyla çalışır ve gelen istekleri bekler. Örnekler [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/) ile haberleşir) ve [Redis](http://redis.io/) ([Redis protocol](http://redis.io/topics/protocol) ile haberleşir) içerir. +HTTP, port bağlama ile dışarı aktarılabilen tek protokol değildir. Nerdeyse her sunucu yazılım tipi bir porta bağlanarak ve gelen istekleri dinleyerek çalışabilir. Örnekler [ejabberd](http://www.ejabberd.im/) ([XMPP](http://xmpp.org/) ile haberleşir) ve [Redis](http://redis.io/)'i ([Redis protocol](http://redis.io/topics/protocol) ile haberleşir) içerir. -Port bağlama yaklaşımı bir uygulamanın,tüketici uygulama için yapılandırmadaki kaynak olanağı gibi destek uygulamasına URL sağlayarak diğer bir uygulamanın [destek servisi](./backing-services) olabileceği anlamına geldiğini de unutmayın. +Ayrıca not edilmelidir ki, porta bağlanma yaklaşımı, bir uygulamanın başka bir uygulamaya [yardımcı servis](./backing-services) olmasını sağlayabilir. Bunu, uygulamanın servise bağlanabileceği bir URL sağlayarak yapar. diff --git a/content/tr/processes.md b/content/tr/processes.md index cefa6e703..e58af9e66 100644 --- a/content/tr/processes.md +++ b/content/tr/processes.md @@ -1,14 +1,14 @@ -## VI. Süreç -### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma +## VI. İşlemler +### Uygulamayı bir veya daha fazla bağımsız işlem olarak çalıştırma -Uygulama bir veya birden fazla *süreç* olarak çalıştırma ortamında çalıştırılır. +Uygulama bir veya birden fazla *işlem* olarak çalıştırma ortamında çalıştırılır. -En basit senaryoda, kod bağımsız bir betiktir, çalışma ortamı, dil çalışma zamanı yüklenmiş, geliştiricilerin yerel laptopudur ve süreç komut satırı aracılığıyla başlatılır (Örneğin, `python my_script.py`). Diğeri spekturumun sonunda, çok yönlü uygulamanın ürün dağıtımı birden fazla [süreç tipi kullanabilir, sıfır veya daha fazla çalışan süreci somutlaştırabilir](./concurrency). +En basit senaryoda, kod bağımsız çalışan bir betiktir, çalışma ortamı ise geliştiricinin dil çalışma zamanı yüklenmiş bilgisayarıdır ve işlem komut satırı aracılığıyla başlatılır (Örneğin, `python my_script.py`). Spekturumun diğer ucunda, gelişmiş bir uygulamanın canlı yayın dağıtımı birden fazla [sıfır veya daha fazla aktif işlemi bulunan bir işlem tipi](./concurrency)ne sahip olabilir. -**On iki faktör süreçleri durumsuz ve [paylaşımsızdır](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Devamlılığa ihtiyaç duyan herhangi bir veri kapsamlı [destek servisinde](./backing-services) saklanmalıdır, genel olarak bir veri tabananında. +**On iki faktör işlemleri durumsuz ve [paylaşımsızdır](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Saklanmasına ihtiyaç duyulan herhangi bir veri, durum-sahibi bir [destek servisinde](./backing-services) saklanmalıdır. Bu servis genelde bir veritabanı olur. -Süreçlerin bellek uzayı ve dosya sistemi, kısa tek işlemli önbellek olarak kullanılabilir. Örneğin, büyük bir dosya indirirken, çalıştırırken, işlem sonuçlarını veri tabanında saklarken. On iki faktör uygulaması, bellek veya önbellekteki depolanmış hiçbir şeyin gelecekteki istek veya işlerde erişilebilir olacağını hiçbir zaman varsaymaz, çalışan her bir tipin bir çok süreciyle birlikte, gelecek isteğin farklı süreç tarafından sunulma şansı yüksektir. Sadece bir süreç çalıştırıldığında bile, tekrar başlatma (kod dağıtımı, yapılandırma değişikliği veya çalışma ortamı sürecin farklı fiziksel adrese tekrar yerleştirimi tarafından tetiklenir) genellikle bütün yerel (bellek ve dosya sistemi v.b gibi) durumları temizler. +İşlemler, bellekleri ve dosya sistemini, kısa süreli tek işlemli önbellekler olarak kullanabilirler. Örneğin, büyük bir dosya indiririp, üzerinde bir operasyon uygulayıp, operasyonun sonuçlarını veri tabanında saklayabilir. On iki faktör uygulaması, bellek veya diskte depolanmış hiçbir şeyin gelecekteki istek veya işlerde erişilebilir olacağını varsaymaz. Birden çok işlem çalıştıran sistemlerde, gelecekteki bir isteğin farklı bir işlem tarafından sunulma şansı yüksektir. Sadece bir süreç çalıştırıldığında bile, tekrar başlatma (kod dağıtımı, yapılandırma değişikliği veya çalışma ortamı işlemin farklı fiziksel adrese tekrar yerleştirimi tarafından tetiklenebilir) genellikle bütün yerel (bellek ve dosya sistemi v.b gibi) durumları temizler. -Varlık paketleyicileri ( [Jammit](http://documentcloud.github.com/jammit/) veya [django-compressor](http://django-compressor.readthedocs.org/) gibi), derlenmiş varlıklar için önbellek olarak dosya sistemi kullanılır. On iki faktör uygulaması [derleme aşaması](./build-release-run) boyunca, [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) gibi, bu derlemeyi yapmayı tercih eder, çalışma zamanında yapmaktansa. +[django-assetpackager](http://code.google.com/p/django-assetpackager/) gibi statik içerik paketleyicileri dosya sistemini derlenmiş statikleri önbelleklemek için kullanır. On iki faktör uygulaması, bu derlemeyi uygulamanın derlenmesi aşamasında yapmayı tercih eder. [Jammit](http://documentcloud.github.com/jammit/) ve [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) gibi paketleyiciler derleme aşamasında çalışmak için yapılandırılabilir. -Bazı web sistemleri ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) dayanır, bu, kullanıcı oturum verisini uygulama sürecinin belleğinde saklar ve aynı sürece yönlendirilecek olan gelecek istekleri aynı ziyaretçiden bekler. Sticky sessions on iki faktörü ihlal eder ve asla kullanılmamalıdır veya buna güvenmemelidir. Oturum durum verisi [Memcached](http://memcached.org/) veya [Redis](http://redis.io/) gibi bitiş süresi öneren veri deposu için iyi bir adaydır. +Bazı web sistemleri [yapışkan oturum (İng. sticky sessions)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) denilen giriş yapmış kullanıcı bilgisini uygulamanın belleğinde tutan yöntemi kullanır. "Sticky sessions" on iki faktör kurallarını ihlal eden bir yöntemdir ve asla kullanılmamalıdır. Oturum verisi [Memcached](http://memcached.org/) ve [Redis](http://redis.io/)gibi zaman aşımı özelliği sunan veritabanları için iyi bir veridir. From e64037e11428bf62b81a3301adbdcf5056855e43 Mon Sep 17 00:00:00 2001 From: Hakan Aktas Date: Sun, 17 Jan 2021 13:43:10 +0300 Subject: [PATCH 466/472] changed the translation of a few words --- content/tr/admin-processes.md | 14 +++++++------- content/tr/background.md | 2 +- content/tr/backing-services.md | 4 ++-- content/tr/build-release-run.md | 4 ++-- content/tr/codebase.md | 6 +++--- content/tr/concurrency.md | 14 +++++++------- content/tr/config.md | 4 ++-- content/tr/dev-prod-parity.md | 10 +++++----- content/tr/disposability.md | 10 +++++----- content/tr/logs.md | 4 ++-- content/tr/port-binding.md | 2 +- content/tr/processes.md | 14 +++++++------- content/tr/toc.md | 14 +++++++------- 13 files changed, 51 insertions(+), 51 deletions(-) diff --git a/content/tr/admin-processes.md b/content/tr/admin-processes.md index a6ef6d390..73f35724b 100644 --- a/content/tr/admin-processes.md +++ b/content/tr/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Yönetici Süreci -### Yönetici/yönetim görevlerini tek seferlik işlem olarak çalıştırma +## XII. Yönetim Süreçleri +### Yönetim görevlerini tek seferlik süreçler olarak çalıştırma -[İşlem formasyonu](./concurrency) uygulama çalışırken uygulamanın sıradan işlerini (web isteklerini idare etmek gibi) yapmakta kullanılan işlemlerin bir dizisidir. Ayrı olarak, geliştiriciler çoğunlukla uygulamanın bir kereye mahsus yönetimsel veya bakım görevlerini yapmayı dileyecekler. Örneğin: +[Süreç formasyonu](./concurrency) uygulama çalışırken uygulamanın sıradan işlerini (web isteklerini idare etmek gibi) yapmakta kullanılan süreçlerin bir dizisidir. Ayrı olarak, geliştiriciler çoğunlukla uygulamanın bir kereye mahsus yönetimsel veya bakım görevlerini yapmayı dileyecekler. Örneğin: -* Veritabanı değişikliklerini (İng. migrations) çalıştırmak (Django'da `manage.py migrate`, Rails'de `rake db:migrate`). +* Veri modelindeki (İng. migrations) değişiklikleri veritabanına yansıtmak (Django'da `manage.py migrate`, Rails'de `rake db:migrate`). * Herhangi bir kodu çalıştırmak veya canlı yayın veritabanındaki verileri denetlemek için konsolu ([REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) kabuğu olarak da bilinir) çalıştırmak. Çoğu dil hiçbir argüman olmadan (`python` veya `perl`), veya bazı durumlarda ayrı komutlarla (Ruby için `irb`, Rails için `rails console`) bir REPL sağlar. * Uygulamanın kod deposundaki betikleri çalıştırmak (`php scripts/fix_bad_records.php`). -Bir kerelik yönetim işlemleri uygulamanın sıradan [işlemleri](./processes) ile aynı ortamlarda çalışmalıdır. Bu yönetim işlemleri de aynı [sürümdeki](./build-release-run) aynı [kod tabanı](./codebase) ve [yapılandırmayı](./config) kullanarak çalışır. Yönetim kodları da uygulama kodu ile aynı kod deposunda bulunmalıdır. +Tek sefer çalıştırılması gereken yönetsel işlere ait süreçler de, uygulamanın uzun süre çalışan sıradan [süreçleri](./processes) ile birebir aynı ortamda, aynı [sürümdeki](./build-release-run) [kod tabanı](./codebase) ve [yapılandırmayı](./config) kullanarak çalışmalıdır. Uyum sorunu yaşamamak için, uygulamanın yönetimini sağlayan kod da uygulama ile birlikte geliştirilmeli ve yayınlanmalıdır. -Aynı [bağımlılık yalıtımı](./dependencies) teknikleri bütün işlem yönetiminde kullanılmalıdır. Örneğin, eğer Ruby web işlemleri `bundle exec thin start` komutunu kullanıyorsa, veritabanı göçü de `bundle exec rake db:migrate` komutu kullanmalıdır. Aynı durumda, Virtualenv kullanan bir Python programı, Tornado web sunucusu ve herhangi bir `manage.py` yönetici işlemlerinin ikisini de çalıştırabilmek için `bin/python` kullanmalıdır. +Aynı [bağımlılık yalıtımı](./dependencies) teknikleri bütün süreç tiplerinde kullanılmalıdır. Örneğin, eğer Ruby web süreçleri `bundle exec thin start` komutunu kullanıyorsa, veritabanı göçü de `bundle exec rake db:migrate` komutu kullanmalıdır. Aynı durumda, Virtualenv kullanan bir Python programı, Tornado web sunucusu ve herhangi bir `manage.py` yönetici süreçlerinin ikisini de çalıştırabilmek için `bin/python` kullanmalıdır. -On iki faktör, REPL kabuğunu kendisi sağlayan ve tek seferlik betikleri çalıştırmayı kolaylaştıran dilleri fazlasıyla destekler. Yerel dağıtımda, geliştiriciler uygulamanın dizininde doğrudan komut satırında tek seferlik yönetici işlemlerini çalıştırır. Canlı yayın dağıtımında ise, geliştiriciler bu gibi bir işlemi çalıştırmak için ssh veya dağıtımın çalışma ortamı tarafından sağlanan diğer uzak komut çalıştırma mekanizmasını kullanabilir. +On iki faktör, REPL kabuğunu kendisi sağlayan ve tek seferlik betikleri çalıştırmayı kolaylaştıran dilleri fazlasıyla destekler. Yerel dağıtımda, geliştiriciler uygulamanın dizininde doğrudan komut satırında tek seferlik yönetici süreçlerini çalıştırır. Canlı yayın dağıtımında ise, geliştiriciler bu gibi bir süreci çalıştırmak için ssh veya dağıtımın çalışma ortamı tarafından sağlanan diğer uzak komut çalıştırma mekanizmasını kullanabilir. diff --git a/content/tr/background.md b/content/tr/background.md index 1dd181d7d..dd37f9f62 100644 --- a/content/tr/background.md +++ b/content/tr/background.md @@ -5,4 +5,4 @@ Bu belgeye katkıda bulunan kişiler, yüzlerce uygulamanın geliştirilmesi ve Bu belge birçok yazılım servisinde edindiğimiz deneyim ve gözlemlerimizin bir sentezidir. Uygulama geliştirme aşamasındaki ideal pratiklerin, uygulamaların zaman içindeki organik büyüyüşlerine gösterilen özel ilginin, bir uygulamanın kodları üzerinde çalışan geliştiriciler arasındaki işbirliği dinamiklerinin, ve yazılım erozyonunun getirdiği masraftan kaçınmanın toplamı niteliğindedir. -Motivasyonumuz modern uygulama geliştirmelerinde gördüğümüz bazı sistemik problemlere olan farkındalığı arttırmak, bahsi geçen problemler için ortak bir terminoloji belirlemek, ve bu problemlere karşı bir dizi çözüm konsepti sunmaktır. Martin Fowler'ın kitapları olan *Patterns of Enterprise Application Architecture* ve *Refactoring*'den ilham alınmıştır. +Motivasyonumuz modern uygulama geliştirmelerinde gördüğümüz bazı sistemik problemlere olan farkındalığı arttırmak, bahsi geçen problemler için ortak bir terminoloji belirlemek, ve bu problemlere karşı bir dizi çözüm konsepti sunmaktır. Bu konsept oluşturulurken, Martin Fowler'ın kitapları olan *Patterns of Enterprise Application Architecture* ve *Refactoring*'den ilham alınmıştır. diff --git a/content/tr/backing-services.md b/content/tr/backing-services.md index 36cc14ca8..52b55c678 100644 --- a/content/tr/backing-services.md +++ b/content/tr/backing-services.md @@ -1,7 +1,7 @@ ## IV. Yardımcı servisler -### Yardımcı servislere iliştirilmiş kaynaklar olarak davranmak +### Yardımcı servisleri iliştirilmiş kaynaklar olarak ele almak -Bir *yardımcı servis* uygulamanın kendi işlevselliğinin bir parçası olarak ağ üzerinden tükettiği herhangi bir servistir. Örnekler veritabanları ([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlaşma/kuyruk sistemleri ([RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](https://beanstalkd.github.io)), e-posta göndermek için SMTP servisi ([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemlerini ([Memcached](http://memcached.org/) gibi) içerir. +Bir *yardımcı servis* uygulamanın kendi işlevselliğinin bir parçası olarak ağ üzerinden tükettiği herhangi bir servistir. Yardımcı servislere örnek olarak; veritabanları ([MySQL](http://dev.mysql.com/) veya [CouchDB](http://couchdb.apache.org/) gibi), mesajlaşma/kuyruk sistemleri ([RabbitMQ](http://www.rabbitmq.com/) veya [Beanstalkd](https://beanstalkd.github.io)), e-posta göndermek için SMTP servisleri ([Postfix](http://www.postfix.org/) gibi) ve önbellekleme sistemleri ([Memcached](http://memcached.org/) gibi) gösterilebilir. Veritabanları gibi yardımcı servisler, geleneksel olarak uygulamayı da yöneten sistem yöneticileri tarafından yönetilirler. Ancak bu yerel servislere ilave olarak, uygulama üçüncü parti uygulamalar tarafından sağlanan ve yönetilen servislere de sahip olabilirler. Bunlardan bazıları; SMTP servisleri ([Postmark](http://postmarkapp.com/) gibi), metrik toplama servisleri ([New Relic](http://newrelic.com/) veya [Loggly](http://www.loggly.com/) gibi), statik içerik barındırma servisleri ([Amazon S3](http://aws.amazon.com/s3/) gibi) ve hatta API-erişilebilir tüketici servisleridir ([Twitter](http://dev.twitter.com/), [Google Maps](http://code.google.com/apis/maps/index.html), ve [Last.fm](http://www.last.fm/api) gibi). diff --git a/content/tr/build-release-run.md b/content/tr/build-release-run.md index edfdb5916..fa0c99184 100644 --- a/content/tr/build-release-run.md +++ b/content/tr/build-release-run.md @@ -5,7 +5,7 @@ Bir [kod tabanı](./codebase) üç aşamada (geliştirme dağıtımı olmayan) d * *Derleme aşaması* kod deposunun *derleme* olarak bilinen çalıştırılabilir bir pakete çevrilmesidir. Dağıtım evresi tarafından seçilen commit'teki kod kullanılır. Sistem, üçüncü parti [bağımlılıkları](./dependencies) toparlar ve çalıştırılabilirleri ve statik dosyaları derler. * *Yayınlama aşaması*, derleme aşaması tarafından üretilmiş derlemeyi alır ve dağıtımı güncel [yapılandırmasıyla](./config) birleştirir. Son durumda oluşan *yayın* derleme ve yapılandırmanın ikisini de içerir ve çalışma ortamında çalıştırmak için hazırdır. -* *Çalıştırma evresi* (aynı zamanda "runtime" olarak bilinir) seçili yayının karşılığındaki [işlemleri](./processes) başlatarak, çalıştırma ortamındaki uygulamayı çalıştırır. +* *Çalıştırma evresi* (aynı zamanda "runtime" olarak bilinir) seçili yayının karşılığındaki [süreçleri](./processes) başlatarak, çalıştırma ortamındaki uygulamayı çalıştırır. ![Kod, sürüm oluşturmak için yapılandırmayla birleşmiş derlemeye dönüşür.](/images/release.png) @@ -15,4 +15,4 @@ Dağıtım araçları genelde yayın yönetim araçları da sunar. En dikkat çe Her yayın zaman damgası gibi (`2011-04-06-20:32:17` gibi) özel bir ID'ye veya her yeni yayında artan bir numaraya (`v100` gibi) sahip olmalıdır. Yayınlar yalnızca eklemeli bir defterdir ve bir kere oluşturulduğu zaman değiştirilemez. Herhangi bir değişiklik yeni bir yayın oluşturmalıdır. -Derlemeler, geliştiricilerin kod değişikliklerini kod depolarına yüklemesiyle başlatılır. Çalıştırma evresi ise, sunucuların yeniden başlatılması veya çökmüş işlemlerin tekrar ayağa kaldırılması gibi durumlarda otomatik olarak gerçekleştirilir. Bu yüzden çalıştırma evresi olabildiği kadar az sayıda hareketli parçaya sahip olmalıdır ki, gecenin bir yarısında, işinin başında olan hiçbir geliştirici yokken bozulmasın. Derleme evresi ise daha karmaşık olabilir, çünkü hatalar dağıtımı çalıştıran geliştiricilerin her zaman önündedir. +Derlemeler, geliştiricilerin kod değişikliklerini kod depolarına yüklemesiyle başlatılır. Çalıştırma evresi ise, sunucuların yeniden başlatılması veya çökmüş süreçlerin tekrar ayağa kaldırılması gibi durumlarda otomatik olarak gerçekleştirilir. Bu yüzden çalıştırma evresi olabildiği kadar az sayıda hareketli parçaya sahip olmalıdır ki, gecenin bir yarısında, işinin başında olan hiçbir geliştirici yokken bozulmasın. Derleme evresi ise daha karmaşık olabilir, çünkü hatalar dağıtımı çalıştıran geliştiricilerin her zaman önündedir. diff --git a/content/tr/codebase.md b/content/tr/codebase.md index 73e80f139..06187f0e2 100644 --- a/content/tr/codebase.md +++ b/content/tr/codebase.md @@ -1,9 +1,9 @@ ## I. Kod Tabanı -### Versiyon kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım +### Sürüm kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım -On iki faktör bir uygulama her zaman [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) veya [Subversion](http://subversion.apache.org/) gibi bir versiyon kontrol sistemiyle izlenir. Bu versiyon kontrol sistemindeki dosya veritabanına kod deposu (İng. code repository) veya kısaca depo (İng. repo) denir. +On iki faktör bir uygulama her zaman [Git](http://git-scm.com/), [Mercurial](http://mercurial.selenic.com/) veya [Subversion](http://subversion.apache.org/) gibi bir sürüm kontrol sistemiyle izlenir. Bu sürüm kontrol sistemindeki dosya veritabanına kod deposu (İng. code repository) veya kısaca depo (İng. repo) denir. -Bir *kod tabanı*, tek bir depo (Subversion gibi merkezi versiyon kontrol sistemi) ya da kök *commit* paylaşan birden fazla depodan (Git gibi merkezi olmayan versiyon kontrol sistemi) oluşur. +Bir *kod tabanı*, tek bir depo (Subversion gibi merkezi sürüm kontrol sistemi) ya da kök *commit* paylaşan birden fazla depodan (Git gibi merkezi olmayan sürüm kontrol sistemi) oluşur. ![Bir kod tabanı bir çok dağıtımla eşlenir](/images/codebase-deploys.png) diff --git a/content/tr/concurrency.md b/content/tr/concurrency.md index 519986129..9ef8f593f 100644 --- a/content/tr/concurrency.md +++ b/content/tr/concurrency.md @@ -1,14 +1,14 @@ ## VIII. Eş Zamanlılık -### İşlem modeli yardımıyla dağıtıklaştırma +### Süreç modeli yardımıyla dağıtıklaştırma -Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha fazla işlem tarafından temsil edilir. Web uygulamaları çeşitli işlem çalıştırma formlarına sahiptir. Örneğin, PHP işlemleri Apache'nin alt işlemi olarak çalışır, ve istek hacmine göre ihtiyaç duyuldukça başlatılır. Java işlemleri karşıt yaklaşımı benimser; JVM, başlangıçta büyük miktarda sistem kaynağı (CPU ve bellek) ayıran büyük bir işlemi başlatır, ve eşzamanlılık iş parçacıkları (İng. threads) aracılığıyla dahili olarak yönetilir. Her iki durumda, çalışan işlemler, uygulamanın geliştiricilerine minimum düzeyde görünürdür. +Herhangi bir bilgisayar programı bir kere çalıştığı zaman bir veya daha fazla süreç tarafından temsil edilir. Web uygulamaları çeşitli süreç çalıştırma formlarına sahiptir. Örneğin, PHP süreçleri Apache'nin alt süreci olarak çalışır, ve istek hacmine göre ihtiyaç duyuldukça başlatılır. Java süreçleri karşıt yaklaşımı benimser; JVM, başlangıçta büyük miktarda sistem kaynağı (CPU ve bellek) ayıran büyük bir süreci başlatır, ve eşzamanlı iş parçacıkları (İng. threads) aracılığıyla JVM içerisinde dahili olarak yönetilir. Her iki durumda, çalışan süreçler, uygulamanın geliştiricilerine minimum düzeyde görünürdür. -![Ölçek, çalışan işlemler olarak ifade edilir, iş yükü çeşitliliği ise işlem tipi olarak tanımlanır.](/images/process-types.png) +![Ölçek, çalışan süreçler olarak ifade edilir, iş yükü çeşitliliği ise süreç tipi olarak tanımlanır.](/images/process-types.png) -**On iki faktör uygulamasında, işlemler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki işlemler arkaplan servis programları çalıştırmak için olan [unix işlem modeli](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)nden güçlü ipuçları alır. Bu modeli kullanarak geliştirici, uygulamasının her iş tipini bir *işlem tipine* atayarak, farklı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web işlemleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi işlemler tarafından işlenir. +**On iki faktör uygulamasında, süreçler birinci sınıf üyelerdir.** On iki faktör uygulamasındaki süreçler arkaplan servis programları çalıştırmak için olan [Unix süreç modeli](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/)nden güçlü ipuçları alır. Bu modeli kullanarak geliştirici, uygulamasının her iş tipini bir *süreç tipine* atayarak, farklı iş yüklerini kontrol etmek için uygulamasını planlayabilir. Örneğin, HTTP istekleri web süreçleri tarafından işlenir ve uzun çalışan arkaplan görevleri, işçi süreçler tarafından işlenir. -Bu, çalışma zamanı (İng. runtime) içindeki iş parçacıkları veya [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) ve [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron/olay-bazlı model gibi, işlemlerin kendi çok-kanallılığını hariç tutmaz. Fakat bir sanal makinanın dikey ölçekte büyümesinin bir sınırı vardır. Bu yüzden uygulama aynı zamanda birden fazla fiziksel makinede çalışan çoklu işlemleri içerebilmelidir. +Bu, çalışma zamanı (İng. runtime) içindeki iş parçacıkları veya [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/) ve [Node.js](http://nodejs.org/) gibi araçlarda bulunan asenkron/olay-bazlı model gibi, süreçlerin kendi çok-kanallılığını hariç tutmaz. Fakat bir sanal makinanın dikey ölçekte büyümesinin bir sınırı vardır. Bu yüzden uygulama aynı zamanda birden fazla fiziksel makinede çalışan çoklu süreçleri içerebilmelidir. -Bu işlem modeli, konu ölçeklendirmeye geldiğinde gerçekten farkını ortaya koyar. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama işlemleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir iş olduğu anlamına gelir. İşlem tipleri dizisi ve her bir tipin işlem sayısı *işlem formasyonu* olarak bilinir. +Bu süreç modeli, konu ölçeklendirmeye geldiğinde gerçekten farkını ortaya koyar. Paylaşımsız, yatay olarak bölümlenebilir bir doğası olan on iki faktör uygulama süreçleri, daha fazla eş zamanlılık eklemenin kolay ve güvenilir bir iş olduğu anlamına gelir. Süreç tipleri dizisi ve her bir tipin süreç sayısı *süreç formasyonu* olarak bilinir. -On iki faktör uygulama işlemleri [asla arkaplan işlemleri başlatmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyaları yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş işlemlere cevap vermek, kullanıcı sebepli tekrar başlatma ve kapatmaları işlemek için işletim sistemlerinin işlem yöneticisine ([systemd](https://www.freedesktop.org/wiki/Software/systemd/) gibi bulut platformunda yayınlanmış işlem yöneticisi veya geliştirme sırasında [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar) dayanır. +On iki faktör uygulama süreçleri [asla arkaplan süreçleri başlatmamalı](http://dustin.github.com/2010/02/28/running-processes.html) ya da PID dosyaları yazmamalıdır. Bunun yerine, [çıktı akışlarını](./logs) kontrol etmek, çökmüş süreçlere cevap vermek, kullanıcı sebepli tekrar başlatma ve kapatmaları süreçek için işletim sistemlerinin süreç yöneticisine ([systemd](https://www.freedesktop.org/wiki/Software/systemd/) gibi bulut platformunda yayınlanmış süreç yöneticisi veya geliştirme sırasında [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html)'e benzer araçlar) dayanır. diff --git a/content/tr/config.md b/content/tr/config.md index 99e0bd6fe..4fa9b30d3 100644 --- a/content/tr/config.md +++ b/content/tr/config.md @@ -1,5 +1,5 @@ ## III. Yapılandırma -### Yapılandırma ayarlarını ortamda saklama +### Yapılandırma ayarlarını ortam değişkeni saklama Bir uygulamanın *yapılandırma ayarları* [dağıtımlar](./codebase) arasında farklı olma ihtimali olan her şeydir. Örneğin: @@ -15,7 +15,7 @@ Bu *yapılandırma ayarı* tanımının, [Spring](http://spring.io/)'de [kod mod Yapılandırmaya diğer bir yaklaşım da Rails'deki `config/database.yml` gibi dosyaların versiyon kontrol sistemine dahil edilmeden kullanımıdır. Bu, kod deposuna dahil edilmiş sabitler kullanmaya göre büyük bir gelişimdir, fakat hala zayıflıkları vardır: Bu dosyaların yanlışlıkla versiyon kontrol sistemine dahil edilme olasılığı oldukça yüksektir. Yapılandırma dosyalarının farklı yerlerde ve farklı formatlarda dağılmış olması eğilimi mevcuttur, ve bu durum bütün yapılandırmayı bir yerde görmeyi ve yönetmeyi zorlaştırır. Dahası, bu formatlar genelde dil veya çatı için özelleşmiştir. -**On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir** (sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposunaa yanlışlıkla dahil edilme ihtimali düşüktür; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. +**On iki faktör uygulamalarında yapılandırma *ortam değişkenlerinde* kaydedilir** (sıklıkla *env vars* veya *env* olarak kısaltılır). Ortam değişkenleri herhangi bir kod değişikliği olmadan, dağıtımlar arasında kolay değişebilir; Yapılandırma dosyalarının aksine, kod deposuna yanlışlıkla dahil edilme ihtimali düşüktür; ve özel yapılandırma dosyalarının veya Java sistem özellikleri gibi yapılandırma mekanizmalarının aksine, onlar dil ve işletim sisteminden etkilenmez. Yapılandırma yönetiminin diğer bir açısı da gruplandırmadır. Bazen uygulamalar, Rails'deki `geliştirme`, `test` ve `canlı` ortamları gibi belirli dağıtımlardan sonra adlandırılmış gruplar içinde yapılandırılır. Bu yöntem temiz bir şekilde ölçeklenemez. Çünkü uygulamanın daha fazla dağıtımı oluştukça, yeni ortam isimleri gerekli olur, `staging` veya `qa` gibi. Projeler ilerde geliştikçe, geliştiriciler `joes-staging` kendi özel ortam değişkenlerini ekleyebilir. Bu da yapılandırma dosyalarının hızla artmasıyla sonuçlanarak dağıtım yönetimini oldukça kırılganlaştırır. diff --git a/content/tr/dev-prod-parity.md b/content/tr/dev-prod-parity.md index 469aef692..38678a3d6 100644 --- a/content/tr/dev-prod-parity.md +++ b/content/tr/dev-prod-parity.md @@ -38,7 +38,7 @@ Tarihsel olarak, geliştirme ortamı (geliştiricinin uygulamanın yerel [dağı -Uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi [destek servisleri](./backing-services), geliştirme/canlı yayın eşitliğinin önemli olduğu bir alandır. Birçok dil, farklı tipteki servislerin *uyarlayıcılarını* (adaptörlerini) içeren, destek servislerine ulaşımı kolaylaştıran kütüphaneler önerir. Bazı örnekler aşağıdaki tabloda vardır. +Uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi [yardımcı servisleri](./backing-services), geliştirme/canlı yayın eşitliğinin önemli olduğu bir alandır. Birçok dil, farklı tipteki servislerin *uyarlayıcılarını* (adaptörlerini) içeren, yardımcı servislere ulaşımı kolaylaştıran kütüphaneler önerir. Bazı örnekler aşağıdaki tabloda vardır. @@ -67,10 +67,10 @@ Uygulamanın veritabanı, kuyruk sistemi veya önbellek gibi [destek servisleri]
-Geliştiriciler, canlı yayında daha ciddi ve sağlam destek servisleri kullanırken, bazen kendi yerel ortamlarında hafif destek servislerini kullanmak isterler. Örneğin, yerelde SQLite, canlı yayında ise PostgreSQL kullanılır, veya yerelde depolama için işlem belleği, canlı yayında ise Memcached kullanılır. +Geliştiriciler, canlı yayında daha ciddi ve sağlam yardımcı servisleri kullanırken, bazen kendi yerel ortamlarında hafif yardımcı servisleri kullanmak isterler. Örneğin, yerelde SQLite, canlı yayında ise PostgreSQL kullanılır, veya yerelde geçici depolama (İng. cache) için süreç belleği, canlı yayında ise Memcached kullanılır. -**On iki faktör geliştiricisi**, uyarlayıcılar teorik olarak destek servislerindeki herhangi bir farklılığı soyutluyor olsa bile, **geliştirme ve canlı yayın arasında faklı destek servisi kullanma isteğine karşı direnir.** Destek hizmetleri arasındaki farklılıklar, küçük uyumsuzlukların ortaya çıkmasına, yerelde çalışan ve testleri geçen kodun, canlı yayında başarısız olmaya neden olmasına sebep olabilir. Bu tür hatalar, sürekli dağıtıma köstek olan bir sürtünme yaratır. Bu sürtünme maliyeti ve sonraki devamlı dağıtımın azaltılması, bir uygulamanın ömrü süresince toplamda düşünüldüğünde oldukça yüksektir. +**On iki faktör geliştiricisi**, uyarlayıcılar teorik olarak yardımcı servislerdeki herhangi bir farklılığı soyutluyor olsa bile, **geliştirme ve canlı yayın arasında faklı yardımcı servisi kullanma isteğine karşı direnir.** Yardımcı servisler arasındaki farklılıklar, küçük uyumsuzlukların ortaya çıkmasına, yerelde çalışan ve testleri geçen kodun, canlı yayında başarısız olmaya neden olmasına sebep olabilir. Bu tür hatalar, sürekli dağıtıma köstek olan bir sürtünme yaratır. Bu sürtünme maliyeti ve sonraki devamlı dağıtımın azaltılması, bir uygulamanın ömrünün toplamı düşünüldüğünde oldukça yüksektir. -Hafif yerel servisler eskiye göre daha az çekicidir. Memcached, PostgreSQL ve RabbitMQ gibi modern destek servisleri, [Homebrew](http://mxcl.github.com/homebrew/) ve [apt-get](https://help.ubuntu.com/community/AptGet/Howto) gibi modern paket sistemleri sayesinde kolayca yüklenebilir ve çalıştırılabilir. Alternatif olarak, [Chef](http://www.opscode.com/chef/) ve [Puppet](http://docs.puppetlabs.com/) gibi ortam hazırlayıcı araçlar, ve [Vagrant](http://vagrantup.com/) ve [Docker](https://www.docker.com/) gibi hafif sanal ortam sağlayıcıları, geliştiricilerin canlı yayın ortamına çok benzeyen yerel ortamda çalışabilmelerini sağlar. Bu sistemlerin yüklenmesi ve kullanımının maliyeti, geliştirme ve canlı yayın eşitliği ve sürekli dağıtımın faydasıyla karşılaştırıldığında oldukça düşüktür. +Hafif yerel servisler eskiye göre daha az çekicidir. Memcached, PostgreSQL ve RabbitMQ gibi modern yardımcı servisleri, [Homebrew](http://mxcl.github.com/homebrew/) ve [apt-get](https://help.ubuntu.com/community/AptGet/Howto) gibi modern paket sistemleri sayesinde kolayca yüklenebilir ve çalıştırılabilir. Alternatif olarak, [Chef](http://www.opscode.com/chef/) ve [Puppet](http://docs.puppetlabs.com/) gibi ortam hazırlayıcı araçlar, ve [Vagrant](http://vagrantup.com/) ve [Docker](https://www.docker.com/) gibi hafif sanal ortam sağlayıcıları, geliştiricilerin canlı yayın ortamına çok benzeyen yerel ortamda çalışabilmelerini sağlar. Bu sistemlerin yüklenmesi ve kullanımının maliyeti, geliştirme ve canlı yayın eşitliği ve sürekli dağıtımın faydasıyla karşılaştırıldığında oldukça düşüktür. -Farklı destek servislerinin uyarlayıcıları hala kullanışlıdır, çünkü yeni destek servislerine bağlanmayı nispeten zahmetsiz yapar. Ama uygulamanın bütün dağıtımları (geliştirme, test, canlı yayın ortamları) her bir destek servisinin aynı tip ve versiyonunu kullanmalıdır. +Farklı yardımcı servislerin uyarlayıcıları hala kullanışlıdır, çünkü yeni yardımcı servislere bağlanmayı nispeten zahmetsiz yapar. Ama uygulamanın bütün dağıtımları (geliştirme, test, canlı yayın ortamları) her bir yardımcı servisinin aynı tip ve versiyonunu kullanmalıdır. diff --git a/content/tr/disposability.md b/content/tr/disposability.md index b8b53850a..3c29257eb 100644 --- a/content/tr/disposability.md +++ b/content/tr/disposability.md @@ -1,12 +1,12 @@ ## IX. İmha edilebilirlik ### Hızlı başlangıç ve zararsız sonlanma ile maksimum servis sağlığı -**On iki faktör uygulamalarının [işlemleri](./processes) *tek kullanımlıktır*, yani anlık olarak başlatılabilir ve durdurulabilirler.** Bu hızlı esnek ölçeklemeyi, [kod](./codebase) ve [yapılandırma](./config) değişikliklerinin hızlı dağıtımı ve canlı yayın dağıtımlarının sağlamlığını arttırır. +**On iki faktör uygulamalarının [süreçleri](./processes) *tek kullanımlıktır*, yani anlık olarak başlatılabilir ve durdurulabilirler.** Bu hızlı esnek ölçeklemeyi, [kod](./codebase) ve [yapılandırma](./config) değişikliklerinin hızlı dağıtımı ve canlı yayın dağıtımlarının sağlamlığını arttırır. -İşlemler **başlangıç zamanını küçültmeye** çabalamalıdır. İdeal olarak, bir işlemin başlatma komutunun çalıştırılmasından, işlemin ayağa kalkmış ve istek/işleri karşılamaya hazır hale gelmesine kadar olan süre bir kaç saniyedir. Kısa başlama zamanı [yayınlama](./build-release-run) işlemi ve ölçeklenme için daha fazla çeviklik sağlar; ve sağlamlığına yardımcı olur, çünkü işlem yöneticisi işlemleri yeni fiziksel makinelere daha kolay taşıyabilir. +Süreçler **başlangıç zamanını küçültmeye** çabalamalıdır. İdeal olarak, bir sürecin başlatma komutunun çalıştırılmasından, sürecin ayağa kalkmış ve istek/işleri karşılamaya hazır hale gelmesine kadar olan süre birkaç saniyedir. Kısa başlama zamanı [yayınlama](./build-release-run) süreci ve ölçeklenme için daha fazla çeviklik sağlar; ve sağlamlığına yardımcı olur, çünkü süreç yöneticisi süreçleri yeni fiziksel makinelere daha kolay taşıyabilir. -İşlemler, işlem yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, kontrollü şekilde kapanırlar.** Bir web işlemi için kontrollü kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), eğer varsa o an işleniyor olan isteğin tamamlanmasına izin verilmesi ve daha sonra işlemin sonlandırılması şeklinde gerçekleşir. Bu modelin içeriğinde HTTP istekleri kısadır (bir kaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. +Süreçler, süreç yöneticisinden **[SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) sinyalini aldıkları zaman, kontrollü şekilde kapanırlar.** Bir web süreci için kontrollü kapama, servis portunun dinlenmesinin kesilmesi (dolayısıyla herhangi bir yeni istek reddedilir), eğer varsa o an işleniyor olan isteğin tamamlanmasına izin verilmesi ve daha sonra sürecin sonlandırılması şeklinde gerçekleşir. Bu modelin içeriğinde HTTP istekleri kısadır (birkaç saniyeden fazla değildir) veya uzun sorgulama durumlarında, istemci bağlantıyı kaybettiği zaman sorunsuzca tekrar bağlanmayı denemelidir. -Bir işçi işlem için kontrollü kapama, güncel işin iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) sinyali gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda işçi işlem bağlantıyı kopardığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, üzerinde çalışıyor oldukları işin kilitlerini kaldırdıklarından emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişli](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)dir, genellikle sonuçların bir transaksiyonda (İng. transaction) saklanması veya işlemi [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. +Bir işçi süreç için kontrollü kapama, güncel işin iş kuyruğuna döndürülmesiyle sonuçlanır. Örneğin [RabbitMQ](http://www.rabbitmq.com/)'da işçi [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) sinyali gönderebilir; [Beanstalkd](https://beanstalkd.github.io)'da herhangi bir zamanda işçi süreç bağlantıyı kopardığında iş kuyruğa otomatik olarak döndürülür. Kilit tabanlı sistemler, [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) gibi, üzerinde çalışıyor oldukları işin kilitlerini kaldırdıklarından emin olmalıdır. Bu modelin içeriğinde bütün işler [tekrar girişli](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29)dir, genellikle sonuçların bir transaksiyonda (İng. transaction) saklanması veya süreci [eşgüçlü](http://en.wikipedia.org/wiki/Idempotence) yapmasıyla gerçekleşir. -İşlemler, donanımsal sorun oluşması gibi durumlarda oluşacak **ani sonlanmalara karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile kontrollü kapamadan daha az yaygın bir olaydır, ancak yine de gerçekleşebilir. Önerilen yaklaşım, Beanstalkd gibi sağlam arkaplan kuyruklama sistemlerinin kullanımıdır. Bu sistemler, istemciler oturumu kapattığı zaman veya süre aşımı durumlarında işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması kontrollü olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only tasarım](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucu](http://docs.couchdb.org/en/latest/intro/overview.html)na ulaştırır. +Süreçler, donanımsal sorun oluşması gibi durumlarda oluşacak **ani sonlanmalara karşı dayanıklı olmalıdır.** Bu `SIGTERM` ile kontrollü kapamadan daha az yaygın bir olaydır, ancak yine de gerçekleşebilir. Önerilen yaklaşım, Beanstalkd gibi sağlam arkaplan kuyruklama sistemlerinin kullanımıdır. Bu sistemler, istemciler oturumu kapattığı zaman veya süre aşımı durumlarında işi kuyruğa döndürür. Her iki durumda, on iki faktör uygulaması kontrollü olmayan sonlandırmaları idare edebilmek için tasarlanmıştır. [Crash-only tasarım](http://lwn.net/Articles/191059/) bu konsepti [mantıksal sonucu](http://docs.couchdb.org/en/latest/intro/overview.html)na ulaştırır. diff --git a/content/tr/logs.md b/content/tr/logs.md index 52e51056d..4c9dfe306 100644 --- a/content/tr/logs.md +++ b/content/tr/logs.md @@ -3,9 +3,9 @@ *Günlükler* çalışan bir uygulamanın davranışlarını izleyebilme imkanı sağlar. Sunucu tabanlı ortamlarda genellikle diskteki bir dosyaya yazılırlar (ve bunlara log dosyası denir); ama bu sadece bir çıktı formatıdır. -Günlükler, bütün çalışan işlemler ve destek servislerinin çıktı akışlarından kümelenmiş, zaman sıralı olayların [akışıdır](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/). Günlükler en ham haliyle her bir satırda bir olay içeren yazı formatındadır (ancak hata kayıtlarındaki detaylar birden fazla satıra yayılabilir). Günlüklerin belirlenmiş bir başlangıcı ve sonu yoktur, uygulama işlediği sürece akış devam eder. +Günlükler, bütün çalışan süreçler ve destek servislerinin çıktı akışlarından kümelenmiş, zaman sıralı olayların [akışıdır](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/). Günlükler en ham haliyle her bir satırda bir olay içeren yazı formatındadır (ancak hata kayıtlarındaki detaylar birden fazla satıra yayılabilir). Günlüklerin belirlenmiş bir başlangıcı ve sonu yoktur, uygulama işlediği sürece akış devam eder. -**On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Log dosyalarını yazma ve yönetme yapmamalıdır. Bunun yerine, her çalışan işlem kendi olay akışını tamponlamadan `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinde bu akışı inceleyebilirler. +**On iki faktör uygulaması çıkış akışlarının depolaması veya yönlendirilmesiyle ilgilenmez.** Log dosyalarına yazmayı, ya da log dosyalarını yönetmeyi denememelidir. Bunun yerine, her çalışan süreç kendi olay akışını tamponlamadan (İng. buffer) `stdout`'a yazar. Yerel geliştirme süresince, geliştirici uygulamanın davranışını gözlemlemek için terminallerinde bu akışı inceleyebilirler. Test ve canlı yayın dağıtımlarında her bir sürecin akışı çalışma ortamı tarafından yakalanır, diğer bütün akışlarla birleştirilir, ve görüntüleme ve uzun dönem arşivleme için bir veya daha fazla son hedeflerine yönlendirilirler. Bu arşivsel hedefler uygulama tarafından görülebilir veya yapılandırılabilir değildir, tamamen çalışma ortamı tarafından yönetilirler. Açık kaynak log yönlendiricileri ([Logplex](https://github.com/heroku/logplex) ve [Fluentd](https://github.com/fluent/fluentd) gibi) bu amaç için kullanılabilir. diff --git a/content/tr/port-binding.md b/content/tr/port-binding.md index 5b8f12c58..f7c6871d2 100644 --- a/content/tr/port-binding.md +++ b/content/tr/port-binding.md @@ -5,7 +5,7 @@ Web uygulamaları bazen web sunucu taşıyıcıları içinde çalıştırılırl **On iki faktör uygulama tamamen kendi kendine yeterlidir** ve web'e açılan bir servis sunmak için çalıştırma ortamına başka bir web sunucusu enjekte edilmesini beklemez. Bu web uygulaması servisini HTTP üzerinden bir porta bağlanarak sunar ve o porta gelen istekleri dinler. -Yerel geliştirme ortamında, geliştiriciler uygulamanın servislerine ulaşmak için `http://localhost:5000/` gibi bir URL'yi ziyaret eder. Dağıtımda, bir yönlendirme katmanı halka açık bir adrese gelen istekleri karşılayıp porta bağlanmış web işlemlerine aktarırlar. +Yerel geliştirme ortamında, geliştiriciler uygulamanın servislerine ulaşmak için `http://localhost:5000/` gibi bir URL'yi ziyaret eder. Dağıtımda, bir yönlendirme katmanı halka açık bir adrese gelen istekleri karşılayıp porta bağlanmış web süreçlerine aktarırlar. Uygulamalar web sunucusu özelliği edinmek için genellikle [bağımlılık tanımlaması](./dependencies) kullanarak Python için [Tornado](http://www.tornadoweb.org/), Ruby için [Thin](http://code.macournoyer.com/thin/) veya Java ve diğer JVM-tabanlı diller için [Jetty](http://jetty.codehaus.org/jetty/) gibi kütüphaneler kullanırlar. Bu, *kullanıcı alanında* yani uygulamanın kodu içinde gerçekleşir. Çalışma ortamıyla olan anlaşma isteklere hizmet veren bir porta bağlanmaktır. diff --git a/content/tr/processes.md b/content/tr/processes.md index e58af9e66..645d68317 100644 --- a/content/tr/processes.md +++ b/content/tr/processes.md @@ -1,14 +1,14 @@ -## VI. İşlemler -### Uygulamayı bir veya daha fazla bağımsız işlem olarak çalıştırma +## VI. Süreçler +### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma -Uygulama bir veya birden fazla *işlem* olarak çalıştırma ortamında çalıştırılır. +Uygulama bir veya birden fazla *süreç* olarak çalıştırma ortamında çalıştırılır. -En basit senaryoda, kod bağımsız çalışan bir betiktir, çalışma ortamı ise geliştiricinin dil çalışma zamanı yüklenmiş bilgisayarıdır ve işlem komut satırı aracılığıyla başlatılır (Örneğin, `python my_script.py`). Spekturumun diğer ucunda, gelişmiş bir uygulamanın canlı yayın dağıtımı birden fazla [sıfır veya daha fazla aktif işlemi bulunan bir işlem tipi](./concurrency)ne sahip olabilir. +En basit senaryoda, kod bağımsız çalışan bir betiktir, çalışma ortamı ise geliştiricinin dil çalışma zamanı yüklenmiş bilgisayarıdır ve süreç komut satırı aracılığıyla başlatılır (Örneğin, `python my_script.py`). Spekturumun diğer ucunda, gelişmiş bir uygulamanın canlı yayın dağıtımı birden fazla [sıfır veya daha fazla aktif süreci bulunan bir süreç tipi](./concurrency)ne sahip olabilir. -**On iki faktör işlemleri durumsuz ve [paylaşımsızdır](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Saklanmasına ihtiyaç duyulan herhangi bir veri, durum-sahibi bir [destek servisinde](./backing-services) saklanmalıdır. Bu servis genelde bir veritabanı olur. +**On iki faktör süreçleri durumsuz ve [paylaşımsızdır](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Saklanmasına ihtiyaç duyulan herhangi bir veri, durum-sahibi bir [yardımcı serviste](./backing-services) saklanmalıdır. Bu servis genelde bir veritabanı olur. -İşlemler, bellekleri ve dosya sistemini, kısa süreli tek işlemli önbellekler olarak kullanabilirler. Örneğin, büyük bir dosya indiririp, üzerinde bir operasyon uygulayıp, operasyonun sonuçlarını veri tabanında saklayabilir. On iki faktör uygulaması, bellek veya diskte depolanmış hiçbir şeyin gelecekteki istek veya işlerde erişilebilir olacağını varsaymaz. Birden çok işlem çalıştıran sistemlerde, gelecekteki bir isteğin farklı bir işlem tarafından sunulma şansı yüksektir. Sadece bir süreç çalıştırıldığında bile, tekrar başlatma (kod dağıtımı, yapılandırma değişikliği veya çalışma ortamı işlemin farklı fiziksel adrese tekrar yerleştirimi tarafından tetiklenebilir) genellikle bütün yerel (bellek ve dosya sistemi v.b gibi) durumları temizler. +Süreçler, bellekleri ve dosya sistemini, kısa süreli tek süreçli önbellekler olarak kullanabilirler. Örneğin, büyük bir dosya indiririp, üzerinde bir operasyon uygulayıp, operasyonun sonuçlarını veri tabanında saklayabilir. On iki faktör uygulaması, bellek veya diskte depolanmış hiçbir şeyin gelecekteki istek veya işlerde erişilebilir olacağını varsaymaz. Birden çok süreç çalıştıran sistemlerde, gelecekteki bir isteğin farklı bir süreç tarafından sunulma şansı yüksektir. Sadece bir süreç çalıştırıldığında bile, tekrar başlatma (kod dağıtımı, yapılandırma değişikliği veya çalışma ortamı sürecin farklı fiziksel adrese tekrar yerleştirimi tarafından tetiklenebilir) genellikle bütün yerel (bellek ve dosya sistemi v.b gibi) durumları temizler. [django-assetpackager](http://code.google.com/p/django-assetpackager/) gibi statik içerik paketleyicileri dosya sistemini derlenmiş statikleri önbelleklemek için kullanır. On iki faktör uygulaması, bu derlemeyi uygulamanın derlenmesi aşamasında yapmayı tercih eder. [Jammit](http://documentcloud.github.com/jammit/) ve [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) gibi paketleyiciler derleme aşamasında çalışmak için yapılandırılabilir. -Bazı web sistemleri [yapışkan oturum (İng. sticky sessions)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) denilen giriş yapmış kullanıcı bilgisini uygulamanın belleğinde tutan yöntemi kullanır. "Sticky sessions" on iki faktör kurallarını ihlal eden bir yöntemdir ve asla kullanılmamalıdır. Oturum verisi [Memcached](http://memcached.org/) ve [Redis](http://redis.io/)gibi zaman aşımı özelliği sunan veritabanları için iyi bir veridir. +Bazı web sistemleri [yapışkan oturum (İng. sticky sessions)](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) denilen giriş yapmış kullanıcı bilgisini uygulamanın belleğinde tutan yöntemi kullanır. "Sticky sessions" on iki faktör kurallarını ihlal eden bir yöntemdir ve asla kullanılmamalıdır. Oturum verisi [Memcached](http://memcached.org/) ve [Redis](http://redis.io/)gibi zaman aşımı özelliği sunan veritabanları için iyi bir veri adayıdır. diff --git a/content/tr/toc.md b/content/tr/toc.md index 21fa0389a..4f664e29d 100644 --- a/content/tr/toc.md +++ b/content/tr/toc.md @@ -2,22 +2,22 @@ On İki Faktör ============= ## [I. Kod tabanı](./codebase) -### Versiyon kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım +### Sürüm kontrol sistemi üzerinde tek bir kod tabanı, birden fazla dağıtım ## [II. Bağımlılıklar](./dependencies) ### Bağımlılıkların açıkça tanımlanması ve izole edilmesi ## [III. Yapılandırma](./config) -### Yapılandırma ayarlarını ortamda saklama +### Yapılandırma ayarlarını ortam değişkeni olarak saklama ## [IV. Yardımcı servisler](./backing-services) -### Yardımcı servislere iliştirilmiş kaynaklar olarak davranmak +### Yardımcı servisleri iliştirilmiş kaynaklar olarak ele almak ## [V. Derleme, yayınlama, çalıştırma](./build-release-run) ### Derleme ve çalıştırma aşamalarını tam olarak ayırma -## [VI. İşlemler](./processes) -### Uygulamayı bir veya daha fazla bağımsız işlem olarak çalıştırma +## [VI. Süreçler](./processes) +### Uygulamayı bir veya daha fazla bağımsız süreç olarak çalıştırma ## [VII. Port bağlama](./port-binding) ### Servisin portlar üzerinden sunulması @@ -32,7 +32,7 @@ On İki Faktör ### Geliştirme, test etme ve canlı yayın ortamının birbirine olabildiğince benzer olması ## [XI. Günlükler](./logs) -### Günlüklere olay akışı gibi davranma +### Günlükleri olay akışı olarak ele almak ## [XII. Yönetici Süreci](./admin-processes) -### Yönetici/yönetim görevlerini tek seferlik işlem olarak çalıştırma +### Yönetici/yönetim görevlerini tek seferlik süreçler olarak çalıştırma From 70e840e71f8ad3b7178bb55c0e582056093db064 Mon Sep 17 00:00:00 2001 From: svc-scm <48930134+svc-scm@users.noreply.github.com> Date: Tue, 26 Oct 2021 07:17:33 -0700 Subject: [PATCH 467/472] Updated/Added CODEOWNERS with ECCN --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..522fa4a0f --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. +#ECCN:Open Source From 1d56faeeb61e45190f8017ae6a02bbf294b6507e Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Tue, 30 May 2023 15:16:02 -0700 Subject: [PATCH 468/472] Add .DS_Store --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 365e22148..63743bdf2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .rvmrc .bundle .tool-versions +.DS_Store \ No newline at end of file From 0399ff79f748cb1b84e280650088820ec4a47bcd Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Tue, 30 May 2023 15:16:44 -0700 Subject: [PATCH 469/472] Bump to heroku 22 --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index 9e07c3198..6a233a8ea 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,6 @@ { "name": "12factor", - "stack": "heroku-18", + "stack": "heroku-22", "scripts": { }, "env": { From ecfb1a8a2cd67cb0e4a5536f2896f299fd5fd884 Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Tue, 30 May 2023 15:18:12 -0700 Subject: [PATCH 470/472] bump ruby version to 3.2.2 --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 36 +++++++++++++++++++++--------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.ruby-version b/.ruby-version index 338a5b5d8..be94e6f53 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.6 +3.2.2 diff --git a/Gemfile b/Gemfile index df4a21da3..cd795db60 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -ruby '2.6.6' +ruby '3.2.2' gem 'sinatra' gem 'thin' diff --git a/Gemfile.lock b/Gemfile.lock index 9808a77ea..8277456a9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,23 +1,29 @@ GEM remote: http://rubygems.org/ specs: - daemons (1.2.3) - eventmachine (1.2.0.1) - i18n (0.7.0) - maruku (0.7.2) - rack (1.6.12) - rack-protection (1.5.3) + concurrent-ruby (1.2.2) + daemons (1.4.1) + eventmachine (1.2.7) + i18n (1.13.0) + concurrent-ruby (~> 1.0) + maruku (0.7.3) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) + rack (2.2.7) + rack-protection (3.0.6) rack rack-ssl-enforcer (0.2.9) - sinatra (1.4.7) - rack (~> 1.5) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) - thin (1.6.4) + ruby2_keywords (0.0.5) + sinatra (3.0.6) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.0.6) + tilt (~> 2.0) + thin (1.8.2) daemons (~> 1.0, >= 1.0.9) eventmachine (~> 1.0, >= 1.0.4) - rack (~> 1.0) - tilt (2.0.4) + rack (>= 1, < 3) + tilt (2.1.0) PLATFORMS ruby @@ -30,7 +36,7 @@ DEPENDENCIES thin RUBY VERSION - ruby 2.6.6p146 + ruby 3.2.2p53 BUNDLED WITH - 1.17.2 + 2.4.10 From aafd012c3e30c7ea7730438dcd2c5f5fec4f4518 Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Tue, 30 May 2023 15:22:44 -0700 Subject: [PATCH 471/472] Add rexml for Ruby 3 --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index cd795db60..37e58a16f 100644 --- a/Gemfile +++ b/Gemfile @@ -7,3 +7,4 @@ gem 'thin' gem 'maruku' gem 'i18n' gem 'rack-ssl-enforcer' +gem 'rexml' diff --git a/Gemfile.lock b/Gemfile.lock index 8277456a9..93251c83e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,6 +13,7 @@ GEM rack-protection (3.0.6) rack rack-ssl-enforcer (0.2.9) + rexml (3.2.5) ruby2_keywords (0.0.5) sinatra (3.0.6) mustermann (~> 3.0) @@ -32,6 +33,7 @@ DEPENDENCIES i18n maruku rack-ssl-enforcer + rexml sinatra thin From fa572eb0ca789c211dc2c9f19b215dbcc1cd416e Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Tue, 30 May 2023 15:22:51 -0700 Subject: [PATCH 472/472] add CPRA link to footer --- public/css/screen.css | 6 ++++++ public/images/privacy.png | Bin 0 -> 23747 bytes views/layout.erb | 1 + 3 files changed, 7 insertions(+) create mode 100644 public/images/privacy.png diff --git a/public/css/screen.css b/public/css/screen.css index 798dff028..489301b59 100644 --- a/public/css/screen.css +++ b/public/css/screen.css @@ -168,3 +168,9 @@ article img.full { float: none; margin-left: 0; } + +.cpra a img { + height: 17px; + margin-bottom: -2px !important; + margin-right: 5px; +} \ No newline at end of file diff --git a/public/images/privacy.png b/public/images/privacy.png new file mode 100644 index 0000000000000000000000000000000000000000..565afc9791ac138479b1d73eace24d2c0e4d558d GIT binary patch literal 23747 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 literal 0 HcmV?d00001 diff --git a/views/layout.erb b/views/layout.erb index b9ae5911a..e7a2cbb41 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -42,6 +42,7 @@ +