From e4cd082f6feac4e30b9f1ef2aeec3447129906dd Mon Sep 17 00:00:00 2001 From: Adam Wiggins Date: Sat, 4 Jun 2011 23:06:02 -0700 Subject: [PATCH] flesh out release page, including diagram --- content/build-release-run.md | 19 ++++++++++++------- content/toc.md | 2 +- public/images/release.png | Bin 0 -> 16385 bytes 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 public/images/release.png diff --git a/content/build-release-run.md b/content/build-release-run.md index 00dcd78..1e12bde 100644 --- a/content/build-release-run.md +++ b/content/build-release-run.md @@ -1,20 +1,25 @@ ## V. Build, release, run -### Separate build and run stages +### Strict separation of build stage and run stage -The *build* stage is a transform which converts a [code repo](#) into an executable bundle with no external dependencies, suitable for immediate execution in the execution environment. This bundle is known as a *build* (noun). The build stage typically checks out a fresh copy of the code at a commit specified by the release process, fetches and vendors dependencies, and compile binaries or assets. One well-known example of a build stage is creating a JAR file for a Java (or other JVM-based) language. +The *build stage* is a transform which converts a [code repo](/codebase) into an executable bundle with no external dependencies, suitable for immediate execution in the execution environment. This bundle is known as a *build*. The build stage typically checks out a fresh copy of the code at a commit specified by the release process, fetches and vendors dependencies, and compile binaries or assets. One example of a build stage is creating a JAR file for a Java (or other JVM-based) language. -The *run* stage (commonly also referred to as "at runtime") takes the bundle produced by the build stage and executes it in the execution environment. This typically happens by fetching and expanding the executable bundle, setting up the environment with the [config](#), and then launching one or more of the app [processes](#). +The *run stage* (also sometimes referenced as "at runtime") takes the build produced by the build stage and executes it in the execution environment. This typically happens by fetching and expanding the build, setting up the environment with the [config](/config), and then launching one or more of the app [processes](/processes). -In a traditional server-based hosting environment, it's easy to muddle together the build and run stages. For example, one might create the fresh checkout and install dependencies, but then tweak the code in-place on the disk. +In a traditional server-based hosting environment, it's easy to muddle together the build and run stages. For example, one might create the fresh checkout and install dependencies, but then tweak the code in-place on the disk of the production deploy. -The twelve-factor app uses strict separation between the build and run stages. 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 (or to other runtimes). Config is only accessible at runtime, since config can change without triggering a build. +**The twelve-factor app uses strict separation between the build and run stages.** 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. Config is accessible at runtime but not at build time, since config can change without triggering a build. -Builds only happen as the result of a developer-initiated action: deploying new code. Runtime execution, however, can often happen automatically in cases such as a server reboot, or a process restarting after it crashes. 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 around. The build stage can be more complex, since errors are always in the foreground for a developer who is actively engaged, and a failed build will abort the release process and avoid disrupting the running application. +Builds must be initiated by a developer, as an essential part of the process of deploying new code. 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. A failed build must abort the release process and avoid any disruption of the running app. -### Release = build + config +#### Release = build + config + +![Code becomes a build, which is combined with config to create a release.](/images/release.png) A *release* is a combination of a build (an executable bundle generated in the [build stage](#)) and a [config](#), a set of environment variables to determine runtime behavior. New builds always trigger new releases (since the build has been updated). Config changes also trigger a new release (since the config has been updated). A release requires restarting all running [processes](#) in order to bring all processes onto the new release. 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; and offers a `rollback` command. + +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 changes must create a new release. + diff --git a/content/toc.md b/content/toc.md index f9e4501..bc718d2 100644 --- a/content/toc.md +++ b/content/toc.md @@ -14,7 +14,7 @@ The Twelve Factors ### Treat backing services as attached resources ## [V. Build, release, run](/build-release-run) -### Separate build and run stages +### Strict separation of build stage and run stage ## [VI. Processes](/processes) ### Stateless, disposable processes handle application logic diff --git a/public/images/release.png b/public/images/release.png new file mode 100644 index 0000000000000000000000000000000000000000..a4a066e478adb11f7b5553afa6b9f5e0ee284f89 GIT binary patch literal 16385 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 literal 0 HcmV?d00001