mirror of
https://github.com/kennethreitz/12factor.git
synced 2026-06-05 23:10:17 +00:00
tweaks for final sections
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
## XII. Admin processes
|
||||
### One-off admin/management tasks
|
||||
|
||||
The [process formation](/concurrency) represents 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 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 `node`) 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`).
|
||||
|
||||
Twelve-factor apps are best written in 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.
|
||||
Twelve-factor apps are easiest to write in 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.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
## X. Dev/prod parity
|
||||
### Parity between development and production
|
||||
### Keep development and production and similar as possible
|
||||
|
||||
Historically, there is a substantial gap 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). This is a gap in time: a developer may work on code that doesn't go to production for days, weeks, or even months. It's a gap in personnel: developers write code, ops engineers deploy it. And it's a gap in environments: a developer may be using Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux.
|
||||
Historically, there is a substantial gap 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). A developer may work on code that doesn't go to production for days, weeks, or even months (a time gap). Developers write code, ops engineers deploy it (a personnel gap). Developers may be using a stack like Nginx, SQLite, and OS X, while the production deploy uses Apache, MySQL, and Linux (a tools gap).
|
||||
|
||||
The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html). The gap in time between writing code and deploying it is small: a developer may write code and have it deployed hours or even just minutes later. The gap in personnel is small: developers who wrote code are closely involved in deploying it and watching its behavior in production. So it follows that the gap between development and production environments should also be made small.
|
||||
**The twelve-factor app is designed for [continuous deployment](http://www.avc.com/a_vc/2011/02/continuous-deployment.html).** The gap in time between writing code and deploying it is small: a developer may write code and have it deployed hours or even just minutes later. The gap in personnel is small: developers who wrote code are closely involved in deploying it and watching its behavior in production. So it follows that the gap between development and production environments should also be made small.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -18,13 +18,13 @@ The twelve-factor app is designed for [continuous deployment](http://www.avc.com
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Code authors vs code deployers</th>
|
||||
<td>Different</td>
|
||||
<td>Same</td>
|
||||
<td>Different people</td>
|
||||
<td>Same people</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Dev vs production environments</th>
|
||||
<td>Different</td>
|
||||
<td>Same</td>
|
||||
<td>Divergent</td>
|
||||
<td>As similar as possible</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -59,7 +59,7 @@ The twelve-factor app is designed for [continuous deployment](http://www.avc.com
|
||||
|
||||
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 app developer resists the urge to use different backing services between development and production**, even when adapters theoretically abstract away any differences in backing services. Otherwise, tiny incompatibilities crop up, causing code that worked and passed tests in development or staging to fail in production. These types of errors, though infrequent, are maddening to debug, and create friction that disincentives continuous deployment. The cost of this frustration and the subsequent dampening of continuous deployment is extremely high, when considered in aggregate over the lifetime of an application.
|
||||
**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, though infrequent, are maddening to debug, and create friction that disincentives continuous deployment. The cost of this frustration and the subsequent dampening of continuous deployment is extremely high, when considered in aggregate over the lifetime of an application.
|
||||
|
||||
The value of lightweight local services is also much lower than it used to be. 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). The cost of installing and using one of these is low compared to the high benefit of dev/prod parity and continuous deployment.
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
## IX. Disposability
|
||||
### Fast startup and graceful shutdown maximize robustness
|
||||
|
||||
The twelve-factor app's [processes](/processes) are architected to be stopped and started at a moment's notice, facilitating fast elastic scaling and rapid deployment of [code](/codebase) or [config](/config) changes. This is a key element in ensuring robustness of a production deployment.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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 is written to seamlessly attempt a reconnect in the case of losing the long-poll connection.
|
||||
|
||||
For a worker process, graceful shutdown is achieved by returning the current job to the work queue. For example, on RabbitMQ the worker can send a `NACK`; on Beanstalkd, the job is returned to the queue automatically whenever a worker disconnects. Lock-based systems such as Delayed Job 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).
|
||||
|
||||
In this model, minimizing startup time of any individual app process is desirable. 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. But even a large app should try to keep its startup to to no more than 30 seconds. Briefer startup time provides more agility for deploys, code changes, scaling up; and it aids robustness, because the process manager can more easily move processes to new physical machines when warranted.
|
||||
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. Use of a robust queueing backend (such as Beanstalkd) that returns jobs to the queue when clients disconnect or time out, can make all the difference here. 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 extreme](http://couchdb.apache.org/docs/overview.html).
|
||||
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
## XI. Logs
|
||||
### Logs are event streams
|
||||
|
||||
*Logs* provide visibility into the behavior of a running app. While they are sometimes written to a file on disk, this is only an output format - not the essence of what logs really are.
|
||||
*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 for a twelve-factor app 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 its running processes and backing services.** Their raw form typically apepars as a text format with one event per line (though backtraces from exceptions may span multiple lines). The 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 continously 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 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.
|
||||
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.
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ The Twelve Factors
|
||||
### Fast startup and graceful shutdown maximize robustness
|
||||
|
||||
## [X. Dev/prod parity](/dev-prod-parity)
|
||||
### Parity between development and production
|
||||
### Keep development and production and similar as possible
|
||||
|
||||
## [XI. Logs](/logs)
|
||||
### Logs are event streams
|
||||
|
||||
Reference in New Issue
Block a user