Skip to content

Type to search pages.

View .md

Runtimes

A runtime is where an environment’s containers actually run. Everything above it, the manifest, the golden, the masking, the sidecar, the fidelity report, is the same whichever one is chosen.

runtime:
provider: local # or kubernetes
Runtime An environment is Detail
local A network on the local Docker daemon, one container per service, plus a port forwarder per web service The local runtime
kubernetes A namespace, with a Deployment and a Service per service and an Ingress per web service The Kubernetes runtime

Both are MIT and both are in the engine. Running one is not an enterprise feature. Running SEVERAL from one control plane, and placing an environment on the right one, is the multi_runtime licensed feature, because deciding which pool an environment belongs in is a question only an organization has: residency, an isolated pool for regulated repositories, a pool with more memory. See multiple runtimes.

Three capabilities, and each of them exists because the honest answer is sometimes no.

Capability local kubernetes
Reachable from the machine that ran af yes only with a domain to publish under
Logs yes yes
Can attach a database container from the local daemon yes no

Reachability is not a formality. The Kubernetes runtime declares it only when a domain is configured, because without one there is no Ingress and no address a caller could reach, and declaring otherwise would mean af up printing a URL that resolves to nothing.

Attaching a local database is the one that decides your database provider. A database container on the machine that ran af is not reachable from a cluster, so on Kubernetes the database has to be one the environment can already reach: neon, supabase, dblab or pgurl pointed at a server the cluster can route to. A runtime that declared this true when it was not would make the engine attach a branch no pod can connect to.

Whichever runtime is chosen, an environment reaches nothing it was not given. The egress policy, the sidecar that terminates TLS with a certificate the environment already trusts, and the network rules that make the sidecar the only way out are all built by the runtime. A runtime that cannot enforce that is not a runtime this engine will ship, whatever else it can do. See egress.

Implement provider.Runtime and run the suite:

func TestMyRuntime(t *testing.T) {
conformance.RunRuntime(t, factory, conformance.RuntimeOptions{})
}

The runtime suite ships with a deliberately BROKEN fake and a self test that proves the suite fails against it, one behaviour at a time. That is the standard every extension point here is held to, and it is not a formality: a conformance suite nobody has proved can fail is a suite that proves nothing, and a declared behaviour means nothing until somebody has watched it say no.

A behaviour a runtime cannot support is skipped EXPLICITLY, naming the missing capability. A silent skip is how an implementation ends up claiming conformance it does not have, and the skip line is what a reviewer reads.

local and kubernetes are reserved names. A registration under one of them is refused at validation rather than accepted and then never consulted, because the built in runtimes are looked up first.