feat(platform): the site's images name a version, and Flagger promotes the pair - #1316
Merged
Merged
Conversation
…s the pair The api and the frontend ran :latest and Keel rolled each on its own two-minute poll, so two services built from one commit reached production minutes apart and nothing in git said what was running. The overlay now names one version for both, in one place, and the keel.sh annotations come off those two Deployments. On top of that, each service becomes a Flagger blue/green canary whose confirm-promotion gate reads the sibling's phase, so a release promotes both or neither and a failed half parks the other. Flagger installs from its own apps-delivery Kustomization: everything depends on apps-core, so a controller only apps-stateless needs must not be able to stall cert-manager, Traefik and Vault. The tag is bumped by hand until the release pipeline writes a digest there, so cutting a release publishes images without deploying them. Applying this prunes the hand-written Services and Flagger recreates them only once its -primary Deployments are Ready, which costs about one api cold start; the runbook carries the suspend-merge-resume procedure.
17 tasks
ExtraToast
deleted the
worktree-platform+lockstep-api-frontend-release
branch
September 18, 2026 11:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1313. Closes #1294. Part of #1289.
The api and the frontend ran
:latest, and Keel polled that tag every two minutes and rolled each Deployment on its own schedule. Two services built from one commit reached production minutes apart, and nothing in git recorded which version was running. These are the first two slices of #1289: name a version, then promote the two services as one thing.What this achieves
One version is written once, for both images, in
apps/stateless/kustomization.yaml. The Deployments carry the image name without a tag, so there is exactly one place a version can be set and the two cannot drift apart.On top of that, each service is a Flagger blue/green canary. The two
confirm-promotiongates read the sibling canary's phase, so whichever finishes analysis first waits, and a failed half parks the other rather than shipping alone.How
The gate is a symmetric rendezvous rather than an ordering. Each canary's webhook passes when the sibling is neither
ProgressingnorFailed. Both goProgressing; the first to finish sees the other still progressing and blocks; when the second arrives it seesWaitingPromotionand passes; the first passes on its next 30s check. Promotions land within one interval. If one analysis fails, the other's gate seesFailedand holds indefinitely — confirm gates do not consume the failure threshold, so it waits rather than shipping half a release.Flagger installs from its own
apps-deliveryKustomization, not fromapps-core. Everything in the tree depends onapps-coreand it carrieswait: true, so a Flagger HelmRelease that failed to install there would stop cert-manager, Traefik and Vault reconciling in order to deploy a canary controller.apps-deliverydepends onapps-core, and onlyapps-statelessdepends on it.Flagger owns the apex Services and the replica counts, so the hand-written Services and
replicas: 1are gone from git — leavingreplicasin the manifest would make Flux reset it every two minutes against Flagger's scale-to-zero. The Flux health checks name the-primaryDeployments, which are what the Services point at.The frontend gained the probe set the api already had: a
startupProbe, and realperiodSeconds/timeoutSeconds/failureThresholdon readiness and liveness. Its/healthzdeliberately does not probe the api upstream, because an api outage must not also empty the frontend's endpoints.promoteinbuild.ymlnow moves:latestonly for the images Keel still watches.Not in scope
The digest pin and the pipeline that writes it are #1293, so the tag is bumped by hand until that lands and cutting a release publishes images without deploying them. The migration Job is #1297, canary metrics #1300, Keel's removal #1302.
This does not make the switchover atomic. Promotion copies the canary spec onto the
-primaryDeployment, which then rolls normally, so the two apex Services finish flipping seconds apart. One release of backward compatibility remains the contract; closing that window needs a version-selected Service, which Flagger's Kubernetes provider does not do.Worth a reviewer's attention
-primaryDeployments are Ready. Flux reconcilesmainwithin a minute, so this wants merging withapps-statelesssuspended — the runbook now carries that procedure.ReadWriteOncestorage volume. Anything later pointed atapi-canarymust be read-only.portDiscoveryis left off, so the api's management port 8081 stays pod-local exactly as today and the probes are unchanged.Verification
kubectl kustomizerendersapps/stateless,apps/delivery,apps/coreandclusters/productionclean, with both images resolving to the pinned tag.WaitingPromotionpasses,ProgressingandFailedboth block.Diff breakdown —
█added░removed, scaled to the largest row.