From e1d08c8c9058a5d395a29d9e71c5588a6c54a9da Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Fri, 21 Jan 2022 21:35:49 +0100 Subject: [PATCH 01/17] Added new folder and translated intro --- content/nl/admin-processes.md | 14 ++++++ content/nl/background.md | 9 ++++ content/nl/backing-services.md | 14 ++++++ content/nl/build-release-run.md | 19 +++++++++ content/nl/codebase.md | 18 ++++++++ content/nl/concurrency.md | 14 ++++++ content/nl/config.md | 22 ++++++++++ content/nl/dependencies.md | 12 ++++++ content/nl/dev-prod-parity.md | 76 +++++++++++++++++++++++++++++++++ content/nl/disposability.md | 14 ++++++ content/nl/intro.md | 12 ++++++ content/nl/logs.md | 16 +++++++ content/nl/port-binding.md | 14 ++++++ content/nl/processes.md | 14 ++++++ content/nl/toc.md | 38 +++++++++++++++++ content/nl/who.md | 4 ++ 16 files changed, 310 insertions(+) create mode 100644 content/nl/admin-processes.md create mode 100644 content/nl/background.md create mode 100644 content/nl/backing-services.md create mode 100644 content/nl/build-release-run.md create mode 100644 content/nl/codebase.md create mode 100644 content/nl/concurrency.md create mode 100644 content/nl/config.md create mode 100644 content/nl/dependencies.md create mode 100644 content/nl/dev-prod-parity.md create mode 100644 content/nl/disposability.md create mode 100644 content/nl/intro.md create mode 100644 content/nl/logs.md create mode 100644 content/nl/port-binding.md create mode 100644 content/nl/processes.md create mode 100644 content/nl/toc.md create mode 100644 content/nl/who.md diff --git a/content/nl/admin-processes.md b/content/nl/admin-processes.md new file mode 100644 index 000000000..870a56096 --- /dev/null +++ b/content/nl/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/nl/background.md b/content/nl/background.md new file mode 100644 index 000000000..9be3f1677 --- /dev/null +++ b/content/nl/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/nl/backing-services.md b/content/nl/backing-services.md new file mode 100644 index 000000000..c8f59945e --- /dev/null +++ b/content/nl/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 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. + +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/nl/build-release-run.md b/content/nl/build-release-run.md new file mode 100644 index 000000000..83525c1ec --- /dev/null +++ b/content/nl/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/nl/codebase.md b/content/nl/codebase.md new file mode 100644 index 000000000..234ad6725 --- /dev/null +++ b/content/nl/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/nl/concurrency.md b/content/nl/concurrency.md new file mode 100644 index 000000000..9e7426fcf --- /dev/null +++ b/content/nl/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/nl/config.md b/content/nl/config.md new file mode 100644 index 000000000..0bc603b82 --- /dev/null +++ b/content/nl/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/nl/dependencies.md b/content/nl/dependencies.md new file mode 100644 index 000000000..d53fd4cd8 --- /dev/null +++ b/content/nl/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/nl/dev-prod-parity.md b/content/nl/dev-prod-parity.md new file mode 100644 index 000000000..e771d163c --- /dev/null +++ b/content/nl/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/nl/disposability.md b/content/nl/disposability.md new file mode 100644 index 000000000..4725ef581 --- /dev/null +++ b/content/nl/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/nl/intro.md b/content/nl/intro.md new file mode 100644 index 000000000..249ff67f6 --- /dev/null +++ b/content/nl/intro.md @@ -0,0 +1,12 @@ +Introductie +============ + +In het moderne tijdperk wordt software vaak geleverd als een dienst: *web apps* genaamd, of *software-as-a-service*. De twelve-factor app is een methodologie voor het bouwen van *software-as-a-service* die: + +* Gebruik maakt van **delcaratieve** formaten voor geautomatiseerde installatie, om tijd en kosten te minimaliseren voor nieuwe ontwikkelaars die zich bij het project aansluiten; +* Een **clean contract** hebben met het onderliggende besturingssysteem, dat **maximale portabiliteit** aanbiedt tussen uitvoeringsomgevingen; +* Geschikt zijn voor **implementatie** op moderne **cloud platforms**, met als gevolg de nood aan servers en systeembeheer overbodig te maken; +* **Minimaliseren van verschillen** tussen ontwikkeling en productie, waardoor **continuous deployment** mogelijk is voor maximale wendbaarheid; +* En kan **opgeschaald** worden zonder significante wijzigingen in tooling, architectuur of ontwikkelingspraktijken. + +De twelve-factor methodologie kan worden toegepast op apps geschreven in elke programmeertaal, en die gebruik maken van elke combinatie van backing services (databases, queue, memory cache, etc). \ No newline at end of file diff --git a/content/nl/logs.md b/content/nl/logs.md new file mode 100644 index 000000000..22e3404e7 --- /dev/null +++ b/content/nl/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/nl/port-binding.md b/content/nl/port-binding.md new file mode 100644 index 000000000..b12de8b15 --- /dev/null +++ b/content/nl/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/nl/processes.md b/content/nl/processes.md new file mode 100644 index 000000000..f63957def --- /dev/null +++ b/content/nl/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/nl/toc.md b/content/nl/toc.md new file mode 100644 index 000000000..d8fbe2c5e --- /dev/null +++ b/content/nl/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/nl/who.md b/content/nl/who.md new file mode 100644 index 000000000..49eb40fd5 --- /dev/null +++ b/content/nl/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 43752374a6e0aacc48a31d5089f3d201e780e737 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Fri, 21 Jan 2022 21:46:18 +0100 Subject: [PATCH 02/17] translated background --- content/nl/background.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/content/nl/background.md b/content/nl/background.md index 9be3f1677..00ff6588c 100644 --- a/content/nl/background.md +++ b/content/nl/background.md @@ -1,9 +1,8 @@ -Background +Achtergrond ========== -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. +De medewerkers aan dit document zijn direct betrokken geweest bij de ontwikkeling en implementatie van honderden apps, en zijn indirect getuige geweest van de ontwikkeling, werking en schaling van honderdduizenden apps via ons werk op het 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*. +Dit document verzamelt al onze ervaringen en observaties over een grote verscheidenheid van software-as-a-service apps in het wild. Het is een verzameling van ideale praktijken voor app-ontwikkeling, met bijzondere aandacht voor de dynamiek van de organische groei van een app in de tijd, de dynamiek van de samenwerking tussen ontwikkelaars die werken aan de codebase van de app, en het vermijden van de kosten van software-erosie. +Onze motivatie is om het bewustzijn te vergroten van een aantal systematische problemen die we hebben gezien in de moderne applicatie-ontwikkeling, om een gedeelde woordenschat te bieden voor het bespreken van deze problemen, en om een set van brede conceptuele oplossingen aan te bieden voor die problemen met bijbehorende terminologie. De indeling is geïnspireerd op Martin Fowler's boeken *Patterns of Enterprise Application Architecture* en *Refactoring*. \ No newline at end of file From f410923a407e4abb447854db44ec6bebb0d7214c Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Fri, 21 Jan 2022 21:47:27 +0100 Subject: [PATCH 03/17] Translated who --- content/nl/who.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/nl/who.md b/content/nl/who.md index 49eb40fd5..248e62051 100644 --- a/content/nl/who.md +++ b/content/nl/who.md @@ -1,4 +1,4 @@ -Who should read this document? +Wie zou dit document moeten lezen? ============================== -Any developer building applications which run as a service. Ops engineers who deploy or manage such applications. +Elke ontwikkelaar die applicaties bouwt die draaien als een service. Ops ingenieurs die dergelijke toepassingen uitrollen of beheren. \ No newline at end of file From 97eeb09b4251b33208bfc37ffde6b08275b57bd8 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Fri, 21 Jan 2022 22:02:50 +0100 Subject: [PATCH 04/17] Translated codebase --- content/nl/codebase.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/content/nl/codebase.md b/content/nl/codebase.md index 234ad6725..c7feb98f6 100644 --- a/content/nl/codebase.md +++ b/content/nl/codebase.md @@ -1,18 +1,17 @@ ## I. Codebase -### One codebase tracked in revision control, many deploys +### Eén codebasis bijgehouden in versiebeheer, veel uitrollen -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*. +Een twelve-factor app wordt altijd bijgehouden in een versiebeheersysteem, zoals [Git](http://git-scm.com/), [Mercurial](https://www.mercurial-scm.org/), of [Subversion](http://subversion.apache.org/). Een database voor het bijhouden van revisies staat bekend als een *code repository*, vaak afgekort tot *code repo* of gewoon *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). +Een *codebasis* is een enkele repo (in een gecentraliseerd revisiebeheersysteem zoals Subversion), of een set van repo's die een root commit delen (in een gedecentraliseerd revisiebeheersysteem zoals Git) -![One codebase maps to many deploys](/images/codebase-deploys.png) +![Eén codebase gaat samen met vele uitrollen](/images/codebase-deploys.png) -There is always a one-to-one correlation between the codebase and the app: +Er is altijd een één-op-één correlatie tussen de codebase en de 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). +* Als er meerdere codebasissen zijn, is het geen app -- het is een gedistribueerd systeem. Elk onderdeel in een gedistribueerd systeem is een app, en elk kan individueel conform zijn met twelve-factor principes. +* Meerdere apps die dezelfde code delen is een overtreding van de twelve-factor principes. De oplossing hier is om gedeelde code te herwerken in software-libraries die kunnen worden opgenomen in de [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. +Er is slecht één codebase per app, maar er zullen veel uitrollen van de app zijn. Een *uitrol* is een draaiende instantie van de app. Dit is typisch voor een productie omgeving, en een of meer staging omgevingen. Daarnaast heeft elke ontwikkelaar een kopie van de app draaien in hun lokale ontwikkelomgeving, die ook gekwalificeert zijn als een uitrol. +De codebasis is dezelfde over alle uitrollen, hoewel verschillende versies actief kunnen zijn in elke uitrol. Bijvoorbeeld, een ontwikkelaar heeft een aantal commits die nog niet zijn uitgerold naar staging; staging heeft een aantal commits die nog niet zijn uitgerold naar productie. Maar ze delen allemaal dezelfde codebasis, waardoor ze identificeerbaar zijn als verschillende uitrollen van dezelfde app. \ No newline at end of file From bf28ee2bd19498c83cb5b46abcfe2fd7a00e28e1 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 20:32:25 +0100 Subject: [PATCH 05/17] Translated dependencies --- content/nl/dependencies.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/nl/dependencies.md b/content/nl/dependencies.md index d53fd4cd8..66abba56d 100644 --- a/content/nl/dependencies.md +++ b/content/nl/dependencies.md @@ -1,12 +1,12 @@ -## II. Dependencies -### Explicitly declare and isolate dependencies +## II. Afhankelijkheden +### Verklaar en isoleer afhankelijkheden expliciet -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"). +De meeste programmeertalen bieden een packaging systeem voor het distribueren van ondersteunende bibliotheken aan, zoals [CPAN](http://www.cpan.org/) voor Perl of [Rubygems](http://rubygems.org/) voor Ruby. Libraries die via een packaging systeem worden geïnstalleerd, kunnen systeembreed worden geïnstalleerd (bekend als "site packages") of worden opgenomen in de map die de app bevat (bekend als "vendoring" of "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. +**Een 12-factor app vertrouwt nooit op het impliciete bestaan van systeembrede libraries.** Het declareert alle afhankelijkheden, volledig en exact, via een *dependency declaration* manifest. Bovendien gebruikt het een *dependency isolation* tool tijdens de uitvoering om te verzekeren dat er geen impliciete afhankelijkheden naar binnen lekken vanuit het omringende systeem. De volledige en expliciete afhankelijkheidsspecificatie wordt uniform toegepast op zowel productie als ontwikkeling. -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. +Bijvoorbeeld, [Bundler](https://bundler.io/) voor Ruby biedt het `Gemfile` manifest formaat voor dependency declaratie aan en `bundle exec` voor dependency isolatie. In Python zijn er twee aparte gereedschappen voor deze stappen -- [Pip](http://www.pip-installer.org/en/latest/) wordt gebruikt voor declaratie en [Virtualenv](http://www.virtualenv.org/en/latest/) voor isolatie. Zelfs C heeft [Autoconf](http://www.gnu.org/s/autoconf/) voor dependency declaratie, en static linking kan voor dependency isolatie zorgen. Ongeacht de toolchain, dependency declaratie en isolatie moeten altijd samen gebruikt worden -- alleen het een of het ander is niet voldoende om aan de twaalf-factor te voldoen. -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`. +Een voordeel van expliciete dependency declaratie is dat het de setup vereenvoudigt voor ontwikkelaars die nieuw zijn voor de app. De nieuwe ontwikkelaar kan de codebase van de app uitchecken op zijn ontwikkelmachine, waarbij hij alleen de runtime van de taal en de dependency manager als vereisten hoeft te installeren. Ze kunnen alles instellen wat nodig is om de code van de app te draaien met een deterministisch *build-commando*. Bijvoorbeeld, het build commando voor Ruby/Bundler is `bundle install`, terwijl het voor Clojure/[Leiningen](https://github.com/technomancy/leiningen#readme) `lein deps` is. -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. +12-factor apps vertrouwen ook niet op het impliciete bestaan van systeemtools. Voorbeelden hiervan zijn het uitzetten naar ImageMagick of `curl`. Hoewel deze hulpprogramma's op veel of zelfs de meeste systemen bestaan, is er geen garantie dat ze op alle systemen bestaan waarop de app in de toekomst kan draaien, of dat de versie die op een toekomstig systeem wordt gevonden compatibel zal zijn met de app. Als de app moet uitwijken naar een systeemhulpprogramma, moet dat programma in de app worden opgenomen. \ No newline at end of file From 5d080f765f9931acb52c549b168a0d886542b83a Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 20:42:28 +0100 Subject: [PATCH 06/17] Config vertaald --- content/nl/config.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/content/nl/config.md b/content/nl/config.md index 0bc603b82..7488f0603 100644 --- a/content/nl/config.md +++ b/content/nl/config.md @@ -1,22 +1,22 @@ -## III. Config -### Store config in the environment +## III. Configuratie +### Config opslaan in de omgeving -An app's *config* is everything that is likely to vary between [deploys](./codebase) (staging, production, developer environments, etc). This includes: +De *config* van een app is alles wat waarschijnlijk varieert tussen [deploys](./codebase) (staging, productie, ontwikkelomgevingen, etc). Dit omvat: -* 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 +* Resource handles naar de database, Memcached, en andere [backing-services](./backing-services) +* Credentials naar externe diensten zoals Amazon S3 of Twitter +* Per-deploy waarden zoals de canonieke hostnaam voor de 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. +Apps slaan soms config op als constanten in de code. Dit is een schending van de 12-factors, die **strikte scheiding van config en code** vereist. Config varieert aanzienlijk tussen deploys, code niet. -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. +Een lakmoesproef voor het feit of een app alle configuratie correct uit de code heeft gehaald, is of de codebase op elk moment open source kan worden gemaakt, zonder de credentials te compromitteren. -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. +Merk op dat deze definitie van "config" **niet** interne applicatie config omvat, zoals `config/routes.rb` in Rails, of hoe [code modules zijn verbonden](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) in [Spring](http://spring.io/). Dit type van configuratie varieert niet tussen deploys, en wordt dus best in de code gedaan. -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. +Een andere benadering van config is het gebruik van config bestanden die niet ingecheckt worden in revisie controle, zoals `config/database.yml` in Rails. Dit is een enorme verbetering ten opzichte van het gebruik van constanten die in de code repo worden ingecheckt, maar heeft nog steeds zwakke punten: het is gemakkelijk om per ongeluk een config bestand in de repo in te checken; er is een neiging voor config bestanden om verspreid te zijn over verschillende plaatsen en verschillende formaten, wat het moeilijk maakt om alle config op één plaats te zien en te beheren. Verder hebben deze formaten de neiging programmeertaal- of framework-specifiek te zijn. -**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. +**De 12-factor app slaat de configuratie op in *environment variables*** (vaak afgekort tot *env vars* of *env*). Env vars zijn gemakkelijk te veranderen tussen deploys zonder code te veranderen; in tegenstelling tot config files, is er weinig kans dat ze per ongeluk in de code repo ingecheckt worden; en in tegenstelling tot custom config files, of andere config mechanismen zoals Java System Properties, zijn ze een programmeertaal- en OS-agnostische standaard. -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. +Een ander aspect van config management is groeperen. Soms groeperen apps hun config in benoemde groepen (vaak "omgevingen" genaamd), genoemd naar specifieke deploys, zoals de `development`, `test`, en `production` omgevingen in Rails. Deze methode schaalt niet netjes: als meer deploys van de app worden gemaakt, zijn nieuwe omgevingsnamen nodig, zoals `staging` of `qa`. Als het project verder groeit, kunnen ontwikkelaars hun eigen speciale omgevingen toevoegen, zoals `joes-staging`, wat resulteert in een combinatorische explosie van config die het beheren van deploys van de app erg broos maakt. -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 een 12-factor app, zijn env vars granulaire controls, elk volledig orthogonaal aan andere env vars. Ze worden nooit gegroepeerd als "omgevingen", maar worden in plaats daarvan onafhankelijk beheerd voor elke implementatie. Dit is een model dat soepel opschaalt naarmate de app zich op natuurlijke wijze uitbreidt naar meer implementaties gedurende zijn levensduur. \ No newline at end of file From 48f924e054cb203d90854cc569613ac7b3c95658 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 20:48:05 +0100 Subject: [PATCH 07/17] Translated backing services --- content/nl/backing-services.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/content/nl/backing-services.md b/content/nl/backing-services.md index c8f59945e..5d36f330f 100644 --- a/content/nl/backing-services.md +++ b/content/nl/backing-services.md @@ -1,14 +1,12 @@ -## IV. Backing services -### Treat backing services as attached resources +## IV. Backing-diensten +### Behandel backing services als bijgevoegde bronnen -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/)). +Een *backing service* is een service die de app via het netwerk gebruikt als onderdeel van zijn normale werking. Voorbeelden zijn datastores (zoals [MySQL](http://dev.mysql.com/) of [CouchDB](http://couchdb.apache.org/)), messaging/queueing systemen (zoals [RabbitMQ](http://www.rabbitmq.com/) of [Beanstalkd](https://beanstalkd.github.io)), SMTP diensten voor uitgaande email (zoals [Postfix](http://www.postfix.org/)), en caching systemen (zoals [Memcached](http://memcached.org/)). -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)). +Backing services zoals de database worden traditioneel beheerd door dezelfde systeembeheerders die de runtime van de app implementeren. Naast deze lokaal beheerde diensten, kan de app ook diensten hebben die door derden worden geleverd en beheerd. Voorbeelden zijn SMTP-diensten (zoals [Postmark](http://postmarkapp.com/)), metriek-verzamelende diensten (zoals [New Relic](http://newrelic.com/) of [Loggly](http://www.loggly.com/)), binaire asset-diensten (zoals [Amazon S3](http://aws.amazon.com/s3/)), en zelfs API-toegankelijke consumentendiensten (zoals [Twitter](http://dev.twitter.com/), [Google Maps](https://developers.google.com/maps/), of [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. +**De code voor een 12-factor app maakt geen onderscheid tussen lokale diensten en diensten van derden.** Voor de app zijn beide verbonden resources, toegankelijk via een URL of andere locator/credentials opgeslagen in de [config](./config). Een [deploy](./codebase) van de 12-factoren app zou in staat moeten zijn om een lokale MySQL database te verwisselen met een die wordt beheerd door een derde partij (zoals [Amazon RDS](http://aws.amazon.com/rds/)) zonder enige wijzigingen aan de code van de app. Op dezelfde manier zou een lokale SMTP-server kunnen worden vervangen door een SMTP-service van een derde partij (zoals Postmark) zonder codewijzigingen. In beide gevallen hoeft alleen de resource handle in de config veranderd te worden. -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. +Elke afzonderlijke backing service is een *resource*. Bijvoorbeeld, een MySQL database is een bron; twee MySQL databases (gebruikt voor sharding op de applicatielaag) kwalificeren als twee verschillende bronnen. De 12-factor app behandelt deze databases als *attached resources*, wat aangeeft dat ze losgekoppeld zijn aan de deploy waaraan ze gekoppeld zijn. -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. +Resources kunnen naar believen aan deploys worden toegevoegd of ervan worden losgekoppeld. Bijvoorbeeld, als de database van de app zich niet goed werkt vanwege een hardwareprobleem, kan de app-beheerder een nieuwe databaseserver opstarten die is hersteld vanaf een recente back-up. De huidige productiedatabase kan worden losgekoppeld en de nieuwe database aangekoppeld -- allemaal zonder enige codewijziging. \ No newline at end of file From bdff0e23a827444f8d44172208e930f0eb8837a1 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 20:49:20 +0100 Subject: [PATCH 08/17] Added the image back --- content/nl/backing-services.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/nl/backing-services.md b/content/nl/backing-services.md index 5d36f330f..dfd147850 100644 --- a/content/nl/backing-services.md +++ b/content/nl/backing-services.md @@ -9,4 +9,6 @@ Backing services zoals de database worden traditioneel beheerd door dezelfde sys Elke afzonderlijke backing service is een *resource*. Bijvoorbeeld, een MySQL database is een bron; twee MySQL databases (gebruikt voor sharding op de applicatielaag) kwalificeren als twee verschillende bronnen. De 12-factor app behandelt deze databases als *attached resources*, wat aangeeft dat ze losgekoppeld zijn aan de deploy waaraan ze gekoppeld zijn. +A production deploy attached to four backing services. + Resources kunnen naar believen aan deploys worden toegevoegd of ervan worden losgekoppeld. Bijvoorbeeld, als de database van de app zich niet goed werkt vanwege een hardwareprobleem, kan de app-beheerder een nieuwe databaseserver opstarten die is hersteld vanaf een recente back-up. De huidige productiedatabase kan worden losgekoppeld en de nieuwe database aangekoppeld -- allemaal zonder enige codewijziging. \ No newline at end of file From 17a50e4195b58fdb944c87811299976cf86bbea2 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 20:57:39 +0100 Subject: [PATCH 09/17] Translated build-release-run --- content/nl/build-release-run.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/content/nl/build-release-run.md b/content/nl/build-release-run.md index 83525c1ec..e7d7dd1a4 100644 --- a/content/nl/build-release-run.md +++ b/content/nl/build-release-run.md @@ -1,19 +1,18 @@ ## V. Build, release, run -### Strictly separate build and run stages +### Strikt gescheiden houden van build en run stadia -A [codebase](./codebase) is transformed into a (non-development) deploy through three stages: +Een [codebase](./codebase) wordt getransformeerd in een (niet-ontwikkel) deploy door drie stadia: -* 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. +* De *build stage* is een transformatie die een code repo omzet in een uitvoerbare bundel, bekend als een *build*. Met behulp van een versie van de code op een commit gespecificeerd door het deployment proces, haalt de build fase vendors [dependencies](./dependencies) op en compileert binaries en assets. +* De *release stage* neemt de geproduceerde build van de build stage en combineert het met de huidige [config](./config) van de deploy. De resulterende *release* bevat zowel de build als de config en is klaar voor onmiddellijke uitvoering in de uitvoeringsomgeving. +* De *run fase* (ook bekend als "runtime") draait de app in de executie omgeving, door het starten van een set van de app's [processen](./processes) tegen een geselecteerde release. -![Code becomes a build, which is combined with config to create a release.](/images/release.png) +![Code wordt een build, die gecombineerd wordt met config om een release te maken.](/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. +**De 12-factor app maakt gebruik van een strikte scheiding tussen de build, release en run stadia.** Het is bijvoorbeeld onmogelijk om wijzigingen aan te brengen in de code tijdens runtime, aangezien er geen manier is om die wijzigingen terug te propageren naar het build stadium. -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 tools bieden meestal release management tools, met name de mogelijkheid om terug te gaan naar een vorige release. Bijvoorbeeld, de [Capistrano](https://github.com/capistrano/capistrano/wiki) deployment tool slaat releases op in een subdirectory genaamd `releases`, waar de huidige release een symlink is naar de huidige release directory. Het `rollback` commando maakt het makkelijk om snel terug te gaan naar een vorige 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. +Elke release moet altijd een unieke release ID hebben, zoals een tijdstempel van de release (zoals `2011-04-06-20:32:17`) of een oplopend nummer (zoals `v100`). Releases zijn een append-only grootboek en een release kan niet worden gemuteerd als deze eenmaal is aangemaakt. Elke verandering moet een nieuwe release aanmaken. +Builds worden geïnitieerd door de ontwikkelaars van de app wanneer nieuwe code wordt uitgerold. Runtime uitvoering, daarentegen, kan automatisch gebeuren in gevallen zoals een server reboot, of een gecrasht proces dat opnieuw wordt gestart door de procesmanager. Daarom moet de run-fase beperkt worden tot zo weinig mogelijk bewegende delen, omdat problemen die een app verhinderen te draaien midden in de nacht kunnen gebeuren als er geen ontwikkelaars bij de hand zijn. De build fase kan complexer zijn, omdat fouten altijd op de voorgrond staan voor een ontwikkelaar die de deploy aanstuurt. \ No newline at end of file From 59856b8771c2e8e8dff860119974791597fcb956 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 21:06:01 +0100 Subject: [PATCH 10/17] Processes translated --- content/nl/processes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/nl/processes.md b/content/nl/processes.md index f63957def..dfc4d3aa0 100644 --- a/content/nl/processes.md +++ b/content/nl/processes.md @@ -1,14 +1,14 @@ -## VI. Processes -### Execute the app as one or more stateless processes +## VI. Processen +### De app als één of meer stateloze processen uitvoeren -The app is executed in the execution environment as one or more *processes*. +De app wordt in de uitvoeringsomgeving uitgevoerd als een of meer *processen*. -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 het eenvoudigste geval is de code een stand-alone script, de uitvoeringsomgeving is de lokale laptop van een ontwikkelaar met een geïnstalleerde runtime, en het proces wordt gestart via de commandoregel (bijvoorbeeld `python my_script.py`). Aan de andere kant van het spectrum kan een productie-implementatie van een geavanceerde app gebruik maken van vele [procestypes, geïnstantieerd in nul of meer lopende processen](./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. +**12-factor processen zijn stateless en [delen-niets](http://en.wikipedia.org/wiki/Shared_nothing_architecture).** Alle gegevens die moeten blijven bestaan, moeten worden opgeslagen in een stateful [backing service](./backing-services), meestal een 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. +De geheugenruimte of het bestandssysteem van het proces kan worden gebruikt als een korte, eenmalige transactie cache. Bijvoorbeeld het downloaden van een groot bestand, het bewerken ervan, en het opslaan van de resultaten van de operatie in de database. De 12-factor app gaat er nooit van uit dat iets wat in de cache of op de schijf zit, beschikbaar zal zijn voor een toekomstig verzoek of een toekomstige taak -- met veel processen van elk type die draaien, is de kans groot dat een toekomstig verzoek door een ander proces zal worden uitgevoerd. Zelfs als er maar één proces draait, zal een herstart (veroorzaakt door het implementeren van code, het wijzigen van de configuratie, of de uitvoeringsomgeving die het proces naar een andere fysieke locatie verplaatst) meestal alle lokale state wissen (bv. geheugen en bestandssysteem). -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 zoals [django-assetpackager](http://code.google.com/p/django-assetpackager/) gebruiken het bestandssysteem als een cache voor gecompileerde assets. Een 12-factor app doet dit compileren het liefst tijdens de [build stage](/build-release-run). Asset packagers zoals [Jammit](http://documentcloud.github.com/jammit/) en de [Rails asset pipeline](http://ryanbigg.com/guides/asset_pipeline.html) kunnen worden geconfigureerd om assets te packagen tijdens de 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/). +Sommige websystemen vertrouwen op ["sticky sessions"](http://en.wikipedia.org/wiki/Load_balancing_%28computing%29#Persistence) -- dat is het cachen van gebruikerssessiegegevens in het geheugen van het proces van de app en verwachten dat toekomstige verzoeken van dezelfde bezoeker naar hetzelfde proces worden gerouteerd. Sticky sessies zijn een schending van de 12-factor en mogen nooit worden gebruikt of op worden vertrouwd. Session state data is een goede kandidaat voor een datastore die time-expiration biedt, zoals [Memcached](http://memcached.org/) of [Redis](http://redis.io/). From c7f7f07a0e528d59afb94494560e0eba1712d7e5 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 21:18:56 +0100 Subject: [PATCH 11/17] Translated port-binding --- content/nl/port-binding.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/nl/port-binding.md b/content/nl/port-binding.md index b12de8b15..2470741b1 100644 --- a/content/nl/port-binding.md +++ b/content/nl/port-binding.md @@ -1,14 +1,14 @@ -## VII. Port binding -### Export services via port binding +## VII. Poortbinding +### Exporteer diensten via poort 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/). +Web apps worden soms uitgevoerd binnen een webserver container. PHP apps kunnen bijvoorbeeld draaien als een module binnen [Apache HTTPD](http://httpd.apache.org/), of Java apps kunnen draaien binnen [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. +**De 12-factor app is volledig op zichzelf staand** en is niet afhankelijk van runtime injectie van een webserver in de uitvoeringsomgeving om een web-facing service te creëren. De web app **exporteert HTTP als een service door te binden aan een poort**, en te luisteren naar verzoeken die binnenkomen op die poort. -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. +In een lokale ontwikkelomgeving bezoekt de ontwikkelaar een service URL zoals `http://localhost:5000/` om toegang te krijgen tot de service die door zijn app wordt geëxporteerd. Bij de implementatie zorgt een routering laag voor het routeren van verzoeken van een publieke hostnaam naar de poort-gebonden web processen. -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. +Dit wordt typisch geïmplementeerd door gebruik te maken van [dependency declaration](./dependencies) om een webserver library toe te voegen aan de app, zoals [Tornado](http://www.tornadoweb.org/) voor Python, [Thin](http://code.macournoyer.com/thin/) voor Ruby, of [Jetty](http://www.eclipse.org/jetty/) voor Java en andere JVM-gebaseerde talen. Dit gebeurt volledig in *gebruikersruimte*, dat wil zeggen, binnen de code van de app. Het contract met de uitvoeringsomgeving is het binden aan een poort om verzoeken te serveren. -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 is niet de enige dienst die kan worden geëxporteerd door poortbinding. Bijna elke soort server software kan worden uitgevoerd via een proces dat zich bindt aan een poort en wacht op inkomende verzoeken. Voorbeelden zijn [ejabberd](http://www.ejabberd.im/) (die [XMPP](http://xmpp.org/) aanspreekt), en [Redis](http://redis.io/) (die het [Redis protocol](http://redis.io/topics/protocol) aanspreekt). -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. +Merk ook op dat de port-binding aanpak betekent dat een app de [backing service](./backing-services) voor een andere app kan worden, door de URL naar de backing app als een resource handle in de [config](./config) voor de consumerende app op te geven. \ No newline at end of file From 00c14decf7ee3a2de145d6b8e4253d90213b6016 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sat, 22 Jan 2022 21:49:31 +0100 Subject: [PATCH 12/17] Translated concurrency --- content/nl/concurrency.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/nl/concurrency.md b/content/nl/concurrency.md index 9e7426fcf..a6c72698a 100644 --- a/content/nl/concurrency.md +++ b/content/nl/concurrency.md @@ -1,14 +1,14 @@ -## VIII. Concurrency -### Scale out via the process model +## VIII. Concurrentie +### Schaalvergroting via het procesmodel -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. +Elk computerprogramma, eenmaal uitgevoerd, wordt vertegenwoordigd door een of meer processen. Web apps hebben een verscheidenheid aan procesuitvoeringsvormen aangenomen. PHP-processen bijvoorbeeld draaien als kindprocessen van Apache, die op verzoek worden opgestart naar gelang de hoeveelheid verzoeken. Java processen hebben de tegenovergestelde aanpak, waarbij de JVM één groot uberproces levert dat een groot blok systeembronnen (CPU en geheugen) reserveert bij het opstarten, met concurrency die intern beheerd wordt via threads. In beide gevallen is (zijn) het (de) lopende proces(sen) slechts minimaal zichtbaar voor de ontwikkelaars van de app. -![Scale is expressed as running processes, workload diversity is expressed as process types.](/images/process-types.png) +![Schaal wordt uitgedrukt als lopende processen, workload diversiteit wordt uitgedrukt als procestypes.](/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. +**In de 12-factor app zijn processen een eerste klas burger.** Processen in de 12-factor app zijn sterk afgeleid van [het unix procesmodel voor het draaien van service daemons](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Met behulp van dit model kan de ontwikkelaar zijn app ontwerpen om verschillende werkbelastingen aan te kunnen door elk type werk toe te wijzen aan een *procestype*. HTTP-verzoeken kunnen bijvoorbeeld worden afgehandeld door een webproces, en langlopende achtergrondtaken door een werkproces. -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. +Dit sluit niet uit dat individuele processen hun eigen interne multiplexing afhandelen, via threads in de runtime VM, of het async/evented model dat te vinden is in tools als [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](http://twistedmatrix.com/trac/), of [Node.js](http://nodejs.org/). Maar een individuele VM kan maar zo groot worden (verticale schaal), dus de applicatie moet ook in staat zijn om meerdere processen te overspannen die draaien op meerdere fysieke 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*. +Het procesmodel blinkt pas echt uit wanneer het tijd is om uit te schalen. De [niets delende, horizontaal partitioneerbare aard van 12-factor app processen] (./processes) betekent dat het toevoegen van meer concurrency een eenvoudige en betrouwbare operatie is. De reeks van procestypes en het aantal processen van elk type staat bekend als de *procesformatie*. -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. +12-factor app processen [moeten nooit daemoniseren](http://dustin.github.com/2010/02/28/running-processes.html) of PID-bestanden schrijven. Vertrouw in plaats daarvan op de procesmanager van het besturingssysteem (zoals [systemd](https://www.freedesktop.org/wiki/Software/systemd/), een gedistribueerde procesmanager op een cloud-platform, of een tool zoals [Foreman](http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) in ontwikkeling) om [uitvoerstromen](./logs) te beheren, te reageren op gecrashte processen, en door de gebruiker geïnitieerde herstarts en shutdowns af te handelen. \ No newline at end of file From 2011c22229094f4e727fed6e41c82cab0d1303ea Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sun, 23 Jan 2022 20:58:28 +0100 Subject: [PATCH 13/17] translated disposability --- content/nl/disposability.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/content/nl/disposability.md b/content/nl/disposability.md index 4725ef581..e63233e6f 100644 --- a/content/nl/disposability.md +++ b/content/nl/disposability.md @@ -1,14 +1,12 @@ -## IX. Disposability -### Maximize robustness with fast startup and graceful shutdown +## IX. Wegwerpbaarheid +### Maximaliseer robuustheid met snel opstarten en elegant afsluiten -**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. +**De 12-factor app's [processen](./processen) zijn *wegwerpbaar*, wat betekent dat ze kunnen worden gestart of gestopt op elk moment.** Dit vergemakkelijkt snel elastisch schalen, snel implementeren van [code](./codebase) of [config](./config) veranderingen, en robuustheid van productie 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. +Processen moeten streven naar **minimale opstarttijd**. In het ideale geval heeft een proces een paar seconden nodig vanaf het moment dat het launch commando wordt uitgevoerd totdat het proces opgestart is en klaar om verzoeken of opdrachten te ontvangen. Een korte opstarttijd zorgt voor meer wendbaarheid voor het [release](./build-release-run) proces en het opschalen; en het bevordert de robuustheid, omdat het procesbeheerder processen gemakkelijker kan verplaatsen naar nieuwe fysieke machines wanneer dat gerechtvaardigd is. -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). +Processen **sluiten elegant af wanneer ze een [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM)** signaal ontvangen van de procesbeheerder. Voor een webproces wordt "graceful shutdown" bereikt door te stoppen met luisteren op de servicepoort (en daarbij nieuwe verzoeken te weigeren), alle lopende verzoeken te laten afwerken, en dan af te sluiten. Impliciet in dit model is dat HTTP-verzoeken kort zijn (niet meer dan een paar seconden), of in het geval van long polling, de cliënt moet probleemloos proberen opnieuw verbinding te maken wanneer de verbinding wordt verbroken. +Voor een worker proces, wordt graceful shutdown bereikt door de huidige job terug te sturen naar de work queue. Bijvoorbeeld, op [RabbitMQ](http://www.rabbitmq.com/) kan de worker een [`NACK`](http://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack) sturen; op [Beanstalkd](https://beanstalkd.github.io), wordt de taak automatisch teruggegeven aan de wachtrij wanneer een worker de verbinding verbreekt. Lock-gebaseerde systemen zoals [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) moeten er zeker van zijn dat ze hun lock op het taakrecord vrijgeven. Impliciet in dit model is dat alle jobs [reentrant](http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29) zijn, wat typisch wordt bereikt door de resultaten in een transactie te verpakken, of door de operatie [idempotent](http://en.wikipedia.org/wiki/Idempotence) te maken. +Processen moeten ook **robuust zijn tegen plotse dood**, in het geval van een storing in de onderliggende hardware. Hoewel dit veel minder vaak voorkomt dan een "graceful shutdown" met `SIGTERM`, kan het nog steeds gebeuren. Een aanbevolen aanpak is het gebruik van een robuust queueing backend, zoals Beanstalkd, dat jobs teruggeeft aan de queue wanneer clients de verbinding verbreken of time-out gaan. Hoe dan ook, een 12-factor app is ontworpen om onverwachte, niet-gracieuze beëindigingen aan te kunnen. [Crash-only ontwerp](http://lwn.net/Articles/191059/) brengt dit concept naar zijn [logische conclusie](http://docs.couchdb.org/en/latest/intro/overview.html). \ No newline at end of file From 9f0190e8357df02c70ff7071e40e215bc2bc40d7 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sun, 23 Jan 2022 21:13:00 +0100 Subject: [PATCH 14/17] Translated dev-prod-parity --- content/nl/dev-prod-parity.md | 60 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/content/nl/dev-prod-parity.md b/content/nl/dev-prod-parity.md index e771d163c..97f16b7bc 100644 --- a/content/nl/dev-prod-parity.md +++ b/content/nl/dev-prod-parity.md @@ -1,49 +1,49 @@ ## X. Dev/prod parity -### Keep development, staging, and production as similar as possible +### Hou ontwikkeling, staging, en productie zo gelijk mogelijk -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: +Historisch gezien zijn er aanzienlijke verschillen geweest tussen ontwikkeling (een ontwikkelaar die live bewerkingen uitvoert op een lokale [deploy](./codebase) van de app) en productie (een draaiende deploy van de app die toegankelijk is voor eindgebruikers). Deze verschillen manifesteren zich op drie gebieden: -* **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. +* **De tijdskloof**: Een ontwikkelaar kan werken aan code die er dagen, weken of zelfs maanden over doet om in productie te gaan. +* **De personeelskloof**: Ontwikkelaars schrijven code, ops ingenieurs implementeren het. +* **De tools gap**: Ontwikkelaars gebruiken misschien een stack als Nginx, SQLite en OS X, terwijl de productie Apache, MySQL en Linux gebruikt. -**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: +**De 12-factor app is ontworpen voor [continue implementatie](http://avc.com/2011/02/continuous-deployment/) door de kloof tussen ontwikkeling en productie klein te houden.** Kijkend naar de drie hierboven beschreven kloven: -* 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. +* Maak de tijdskloof klein: een ontwikkelaar kan code schrijven en deze uren of zelfs slechts minuten later laten implementeren. +* Maak de kloof tussen personeel klein: ontwikkelaars die code hebben geschreven zijn nauw betrokken bij het implementeren van de code en kijken naar het gedrag ervan in productie. +* Maak de tools gap klein: zorg dat ontwikkeling en productie zo veel mogelijk op elkaar lijken. -Summarizing the above into a table: +Vat het bovenstaande samen in een tabel: - - + + - - - + + + - - - + + + - - - + + + -
Traditional appTwelve-factor appTraditionele app12-factor app
Time between deploysWeeksHoursTijd tussen deploysWekenUren
Code authors vs code deployersDifferent peopleSame peopleCode-schrijvers vs. code-implementeerdersVerschillende mensenZelfde mensen
Dev vs production environmentsDivergentAs similar as possibleDev vs productie-omgevingenVerschillendZo gelijk mogelijk
+ -[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), zoals de app's database, wachtrijsysteem, of cache, is een gebied waar dev/prod pariteit belangrijk is. Veel talen bieden bibliotheken aan die de toegang tot de backing service vereenvoudigen, inclusief *adapters* naar verschillende soorten services. Enkele voorbeelden staan in de tabel hieronder. - + @@ -63,14 +63,14 @@ Summarizing the above into a table: - + -
TypeLanguageTaal Library Adapters
Cache Ruby/Rails ActiveSupport::CacheMemory, filesystem, MemcachedGeheugen, bestandssysteem, 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. +Ontwikkelaars vinden het soms erg aantrekkelijk om een lichtgewicht backing service te gebruiken in hun lokale omgevingen, terwijl een serieuzere en robuustere backing service zal worden gebruikt in productie. Bijvoorbeeld, het gebruik van SQLite lokaal en PostgreSQL in productie; of lokaal procesgeheugen voor caching in ontwikkeling en Memcached in productie. -**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. +**De 12-factor ontwikkelaar weerstaat de drang om verschillende backing services te gebruiken tussen ontwikkeling en productie**, zelfs wanneer adapters theoretisch alle verschillen in backing services wegnemen. Verschillen tussen backing services betekenen dat kleine incompatibiliteiten opduiken, waardoor code die werkte en tests doorstond in ontwikkeling of staging, faalt in productie. Dit soort fouten creëert wrijving die continue implementatie ontmoedigt. De kosten van deze wrijving en de daaropvolgende afremming van continuous deployment zijn extreem hoog als je ze over de levensduur van een applicatie bij elkaar optelt. -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. +Lichtgewicht lokale diensten zijn minder aantrekkelijk dan ze ooit waren. Moderne backing services zoals Memcached, PostgreSQL, en RabbitMQ zijn niet moeilijk te installeren en te draaien dankzij moderne packaging systemen, zoals [Homebrew](http://mxcl.github.com/homebrew/) en [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Als alternatief stellen declaratieve provisioning tools zoals [Chef](http://www.opscode.com/chef/) en [Puppet](http://docs.puppetlabs.com/) in combinatie met lichtgewicht virtuele omgevingen zoals [Docker](https://www.docker.com/) en [Vagrant](http://vagrantup.com/) ontwikkelaars in staat om lokale omgevingen te draaien die productieomgevingen dicht benaderen. De moeite van installatie en gebruik van deze systemen zijn laag vergeleken met het voordeel van dev/prod pariteit en continue 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. +Adapters voor verschillende backing services zijn nog steeds nuttig, omdat ze het porten naar nieuwe backing services relatief pijnloos maken. Maar alle deploys van de app (ontwikkelomgevingen, staging, productie) zouden hetzelfde type en dezelfde versie van elk van de backing services moeten gebruiken. \ No newline at end of file From fa48dc49e1c67e75e2004e0f6f7ec6f65c4bf119 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sun, 23 Jan 2022 21:23:08 +0100 Subject: [PATCH 15/17] Translated logs --- content/nl/logs.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/nl/logs.md b/content/nl/logs.md index 22e3404e7..e3be5ecbb 100644 --- a/content/nl/logs.md +++ b/content/nl/logs.md @@ -1,16 +1,16 @@ ## XI. Logs -### Treat logs as event streams +### Behandel logs als 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* geven inzicht in het gedrag van een draaiende app. In server-gebaseerde omgevingen worden ze gewoonlijk naar een bestand op schijf geschreven (een "logfile"); maar dit is slechts een uitvoerformaat. -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 zijn de [stream](https://adam.herokuapp.com/past/2011/4/1/logs_are_streams_not_files/) van geaggregeerde, tijdsgeordende gebeurtenissen verzameld uit de uitvoerstromen van alle draaiende processen en backing services. Logs in hun ruwe vorm zijn typisch een tekstformaat met één gebeurtenis per lijn (hoewel backtraces van uitzonderingen meerdere lijnen kunnen beslaan). Logs hebben geen vast begin of einde, maar stromen continu door zolang de app actief is. -**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. +**Een 12-factor app houdt zich nooit bezig met het routeren of opslaan van zijn uitvoerstroom.** Hij moet niet proberen te schrijven naar logfiles of deze te beheren. In plaats daarvan schrijft elk draaiend proces zijn event stream, ongebufferd, naar `stdout`. Tijdens lokale ontwikkeling, zal de ontwikkelaar deze stroom op de voorgrond van zijn terminal bekijken om het gedrag van de app te observeren. -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. +In staging of productie implementaties, zal de stream van elk proces worden opgevangen door de executie omgeving, samengevoegd met alle andere streams van de app, en gerouteerd worden naar een of meer eindbestemmingen om te bekijken en op lange termijn te archiveren. Deze archiveringsbestemmingen zijn niet zichtbaar voor of configureerbaar door de app, en worden in plaats daarvan volledig beheerd door de executie-omgeving. Open-source logrouters (zoals [Logplex](https://github.com/heroku/logplex) en [Fluentd](https://github.com/fluent/fluentd)) zijn beschikbaar voor dit doel. -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: +De event stream voor een app kan worden gerouteerd naar een bestand, of worden bekeken via realtime tail in een terminal. Het belangrijkste is dat de stroom kan worden verzonden naar een logindexerings- en analysesysteem zoals [Splunk](http://www.splunk.com/), of een datawarehousing systeem voor algemene doeleinden zoals [Hadoop/Hive](http://hive.apache.org/). Deze systemen bieden een grote kracht en flexibiliteit voor het introspecteren van het gedrag van een app in de tijd, inclusief: -* 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). +* Het vinden van specifieke gebeurtenissen in het verleden. +* Grafieken op grote schaal van trends (zoals verzoeken per minuut). +* Actieve alarmering volgens door de gebruiker gedefinieerde heuristiek (zoals een waarschuwing wanneer het aantal fouten per minuut een bepaalde drempel overschrijdt). \ No newline at end of file From 40c37a63a35fe56f65785d073fe38e28dd8d53d5 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sun, 23 Jan 2022 21:32:53 +0100 Subject: [PATCH 16/17] Translated admin-processes + cleanup --- content/nl/admin-processes.md | 18 +++++++-------- content/nl/dependencies.md | 2 +- content/nl/dev-prod-parity.md | 2 +- content/nl/intro.md | 2 +- content/nl/port-binding.md | 2 +- content/nl/toc.md | 42 +++++++++++++++++------------------ 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/content/nl/admin-processes.md b/content/nl/admin-processes.md index 870a56096..374bd169f 100644 --- a/content/nl/admin-processes.md +++ b/content/nl/admin-processes.md @@ -1,14 +1,14 @@ -## XII. Admin processes -### Run admin/management tasks as one-off processes +## XII. Admin-processen +### Voer admin/beheertaken uit als eenmalige processen -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: +De [proces formatie](./concurrency) is de reeks van processen die gebruikt worden om de gewone zaken van de app te doen (zoals het afhandelen van web verzoeken) terwijl het draait. Los daarvan zullen ontwikkelaars vaak eenmalige administratieve of onderhoudstaken voor de app willen doen, zoals: -* 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`). +* Het uitvoeren van database migraties (bijv. `manage.py migrate` in Django, `rake db:migrate` in Rails). +* Het uitvoeren van een console (ook bekend als een [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) shell) om willekeurige code uit te voeren of de modellen van de app te inspecteren tegen de live database. De meeste talen bieden een REPL door het uitvoeren van de interpreter zonder argumenten (bijv. `python` of `perl`) of in sommige gevallen hebben een apart commando (bijv. `irb` voor Ruby, `rails console` voor Rails). +* Het draaien van eenmalige scripts die gecommit zijn in de repo van de app (bijv. `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. +Eenmalige admin processen moeten worden uitgevoerd in een identieke omgeving als de reguliere [langlopende processen](./processes) van de app. Ze draaien tegen een [release](./build-release-run), met dezelfde [codebase](./codebase) en [config](./config) als elk proces dat tegen die release draait. De beheercode moet samen met de applicatiecode worden geleverd om synchronisatieproblemen te voorkomen. -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. +Dezelfde [dependency isolation](./dependencies) technieken moeten gebruikt worden op alle procestypes. Bijvoorbeeld, als het Ruby web proces het commando `bundle exec thin start` gebruikt, dan zou een database migratie `bundle exec rake db:migrate` moeten gebruiken. Op dezelfde manier zou een Python programma dat Virtualenv gebruikt de vendored `bin/python` moeten gebruiken voor het draaien van zowel de Tornado webserver als alle `manage.py` admin processen. -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 heeft een sterke voorkeur voor talen die een REPL shell uit de doos bieden, en die het gemakkelijk maken om eenmalige scripts te draaien. In een lokale implementatie roepen ontwikkelaars eenmalige admin processen aan door een direct shell commando in de checkout directory van de app. Bij een productie-implementatie kunnen ontwikkelaars ssh gebruiken of een ander mechanisme om commando's op afstand uit te voeren, zoals voorzien door de uitvoeringsomgeving van die implementatie, om zo'n proces uit te voeren. \ No newline at end of file diff --git a/content/nl/dependencies.md b/content/nl/dependencies.md index 66abba56d..57ae64551 100644 --- a/content/nl/dependencies.md +++ b/content/nl/dependencies.md @@ -1,5 +1,5 @@ ## II. Afhankelijkheden -### Verklaar en isoleer afhankelijkheden expliciet +### Expliciet afhankelijkheden declareren en isoleren De meeste programmeertalen bieden een packaging systeem voor het distribueren van ondersteunende bibliotheken aan, zoals [CPAN](http://www.cpan.org/) voor Perl of [Rubygems](http://rubygems.org/) voor Ruby. Libraries die via een packaging systeem worden geïnstalleerd, kunnen systeembreed worden geïnstalleerd (bekend als "site packages") of worden opgenomen in de map die de app bevat (bekend als "vendoring" of "bundling"). diff --git a/content/nl/dev-prod-parity.md b/content/nl/dev-prod-parity.md index 97f16b7bc..b8c4d5633 100644 --- a/content/nl/dev-prod-parity.md +++ b/content/nl/dev-prod-parity.md @@ -1,4 +1,4 @@ -## X. Dev/prod parity +## X. Dev/prod pariteit ### Hou ontwikkeling, staging, en productie zo gelijk mogelijk Historisch gezien zijn er aanzienlijke verschillen geweest tussen ontwikkeling (een ontwikkelaar die live bewerkingen uitvoert op een lokale [deploy](./codebase) van de app) en productie (een draaiende deploy van de app die toegankelijk is voor eindgebruikers). Deze verschillen manifesteren zich op drie gebieden: diff --git a/content/nl/intro.md b/content/nl/intro.md index 249ff67f6..5610186b8 100644 --- a/content/nl/intro.md +++ b/content/nl/intro.md @@ -9,4 +9,4 @@ In het moderne tijdperk wordt software vaak geleverd als een dienst: *web apps* * **Minimaliseren van verschillen** tussen ontwikkeling en productie, waardoor **continuous deployment** mogelijk is voor maximale wendbaarheid; * En kan **opgeschaald** worden zonder significante wijzigingen in tooling, architectuur of ontwikkelingspraktijken. -De twelve-factor methodologie kan worden toegepast op apps geschreven in elke programmeertaal, en die gebruik maken van elke combinatie van backing services (databases, queue, memory cache, etc). \ No newline at end of file +De 12-factor methodologie kan worden toegepast op apps geschreven in elke programmeertaal, en die gebruik maken van elke combinatie van backing services (databases, queue, memory cache, etc). \ No newline at end of file diff --git a/content/nl/port-binding.md b/content/nl/port-binding.md index 2470741b1..c579139d3 100644 --- a/content/nl/port-binding.md +++ b/content/nl/port-binding.md @@ -1,4 +1,4 @@ -## VII. Poortbinding +## VII. Poort-binding ### Exporteer diensten via poort binding Web apps worden soms uitgevoerd binnen een webserver container. PHP apps kunnen bijvoorbeeld draaien als een module binnen [Apache HTTPD](http://httpd.apache.org/), of Java apps kunnen draaien binnen [Tomcat](http://tomcat.apache.org/). diff --git a/content/nl/toc.md b/content/nl/toc.md index d8fbe2c5e..8ca46af7e 100644 --- a/content/nl/toc.md +++ b/content/nl/toc.md @@ -1,38 +1,38 @@ -The Twelve Factors +De Twaalf Factoren ================== ## [I. Codebase](./codebase) -### One codebase tracked in revision control, many deploys +### Eén codebasis bijgehouden in versiebeheer, veel uitrollen -## [II. Dependencies](./dependencies) -### Explicitly declare and isolate dependencies +## [II. Afhankelijkheden](./dependencies) +### Expliciet afhankelijkheden declareren en isoleren -## [III. Config](./config) -### Store config in the environment +## [III. Configuratie](./config) +### Config opslaan in de omgeving -## [IV. Backing services](./backing-services) -### Treat backing services as attached resources +## [IV. Backing-services](./backing-services) +### Behandel backing services als bijgevoegde bronnen ## [V. Build, release, run](./build-release-run) -### Strictly separate build and run stages +### Strikt gescheiden houden van build en run stadia -## [VI. Processes](./processes) -### Execute the app as one or more stateless processes +## [VI. Processen](./processes) +### De app als één of meer stateloze processen uitvoeren -## [VII. Port binding](./port-binding) -### Export services via port binding +## [VII. Poort-binding](./port-binding) +### Exporteer diensten via poort binding ## [VIII. Concurrency](./concurrency) -### Scale out via the process model +### Schaalvergroting via het procesmodel -## [IX. Disposability](./disposability) -### Maximize robustness with fast startup and graceful shutdown +## [IX. Wegwerpbaarheid](./disposability) +### Maximaliseer robuustheid met snel opstarten en elegant afsluiten -## [X. Dev/prod parity](./dev-prod-parity) -### Keep development, staging, and production as similar as possible +## [X. Dev/prod-pariteit](./dev-prod-parity) +### Hou ontwikkeling, staging, en productie zo gelijk mogelijk ## [XI. Logs](./logs) -### Treat logs as event streams +### Behandel logs als event streams -## [XII. Admin processes](./admin-processes) -### Run admin/management tasks as one-off processes +## [XII. Admin-processen](./admin-processes) +### Voer admin/beheertaken uit als eenmalige processen From da1d14e38b88c7c1de9eaf73d224203c351df3d7 Mon Sep 17 00:00:00 2001 From: Tom Stroobants Date: Sun, 23 Jan 2022 21:37:01 +0100 Subject: [PATCH 17/17] Editted locales --- locales/nl.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/nl.yml diff --git a/locales/nl.yml b/locales/nl.yml new file mode 100644 index 000000000..7ed2cb270 --- /dev/null +++ b/locales/nl.yml @@ -0,0 +1,7 @@ +en: + # Name of language listed in locales menu + language: Nederlands (nl) + + # A text to make known that the article is a translation not an original. + # Empty for English, original. + translation: "Deze tekst is een vertaling"