Deployment
Components, compositions, extensions, environments — all of it is declaration. Deployment is the act of turning those declarations into running processes.
§What a process needs
A Toa process needs very little: a language runtime, the application’s sources, and network access to the infrastructure it connects to, such as a broker, a database, and a cache.
Nothing in the runtime depends on a particular platform for running processes. An application can be started by a process manager, in containers, or by hand, and it behaves the same. This is a design constraint of the runtime, and it is what keeps the application the same thing on a developer’s machine and in a cluster.
§The supplied tooling
A team usually wants more than a process: images, rollouts, and replicas managed for it. For those who run on Kubernetes, the runtime supplies opinionated tooling that derives a complete deployment from the Context.
From one declaration it produces:
- a container image for each composition, and for each extension service that is not part of one;
- a description of the workloads to run: how many replicas of each, with what resources, exposed at which addresses;
- the wiring between them: the settings each process needs to find the infrastructure and to know the rest of the application.
A single command builds, publishes, and applies all of it for a named environment.
Using this tooling is the application’s choice. It is a consumer of the declarations, not a requirement of them.
§Derived, not written
No deployment descriptor is written by hand. There are no per-service build files and no manifests of workloads to keep in agreement with the code. The Context already states which components run together, how many replicas there are, and what they connect to, and the deployment follows from it.
An application with thirty components is therefore not thirty deployment configurations. It is one declaration and whatever it implies.
§Images follow content
An image is identified by the content it was built from: the runtime’s version and the versions of its member components. Two consequences are useful in practice.
What did not change is not redeployed. A release that changes one component produces a new image for the composition containing it. The other compositions keep their images, and their processes are left running.
An image carries no environment. The same sources deployed to staging and to production are the same image. What differs is supplied when the process starts. What was tested is what is released.
§Secrets
Secrets are never part of the declaration or of an image. The Context refers to them by name, and their values are provided to the environment separately, once, by whoever is entitled to know them.
Before deploying, the tooling checks that every secret the deployment refers to has been provided, and refuses to proceed otherwise. A missing credential is found at deployment, not when a process first needs it.
§Migrations
State outlives releases, and a new release sometimes needs the stored state to change: a new index, or a field given a default. A component carries such changes with it as migrations.
A migration is applied once per database, before the component serves. When several replicas start at once, one applies it and the others wait.
A migration runs while the previous release may still be serving, so it follows the compatibility rule described in Contracts: the old release must be able to live with the result, or the deployment is stopped first.
§The single-process form
At the compact end of the range, the whole application — every component and every extension service — can be built as one image and run as one workload.
This is a deployment form, not a different application. It suits small installations, previews, and early stages of a product. Moving from it to separate compositions later changes the Context, and nothing in the components.
§What deployment does not decide
Deployment places processes. It does not affect what the application means. The same operations run, the same events are published, and the same guarantees hold, provided the infrastructure supports them. That invariance is the purpose of separating logical from physical architecture, and it is why deployment can be left to tooling.