A plain Deployment rollout is all-or-nothing and blind: it shifts every user to the new version on a fixed schedule and never checks whether the new version is actually healthy. Progressive delivery fixes both: it sends the new version to a slice of traffic first, promotes it only if the metrics stay good, and rolls back automatically if they do not. Argo Rollouts is the common tool. ## Why a Deployment rollout is not enough A Deployment's rolling update replaces pods a few at a time, but every replaced pod serves live traffic immediately, and the rollout marches on by the clock. If the new version is broken, the rollout keeps going and every user hits it. There is no "try it on 10% first" and no "stop if error rate climbs." A canary is exactly those two missing sentences. ## Install Argo Rollouts and replace the Deployment ```console $ kubectl create namespace argo-rollouts $ kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml ``` A `Rollout` is a drop-in replacement for a `Deployment`: same pod template you already have, plus a `strategy` that describes how to shift traffic. It is an ordinary manifest, so you version and sync it from Git with [Argo CD](/docs/hetzner/apalla/workloads/delivery/deploy-apps-from-git-argo-cd) exactly as you would the Deployment it replaces. ```yaml title="rollout.yaml" apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: web spec: replicas: 4 selector: matchLabels: {app: web} template: # ... the same pod template a Deployment would have ... strategy: canary: steps: - setWeight: 10 # 10% of traffic to the new version - pause: {duration: 5m} - setWeight: 50 - pause: {} # pause indefinitely for a manual promote - setWeight: 100 ``` ## Canary or blue-green Same object, two ways to fill in the `strategy`, for two different fears: - **Canary** shifts traffic gradually (10%, 50%, 100%), so a bad version reaches few users before it is caught. Use it by default. - **Blue-green** runs the new version alongside the old at full size, then flips all traffic at once after you verify it. Use it when you cannot mix versions at all, a schema change being the usual reason, and pay for it in double the pods during the switch. ## Promote on metrics, roll back on failure The point of a canary is to let the numbers decide, not a person watching a dashboard at midnight. An `AnalysisTemplate` queries error rate and latency from the [Prometheus you already run](/docs/hetzner/apalla/observability/metrics/set-up-prometheus) between steps, and gates the rollout on the answer. Stay under the threshold and the weight climbs. Breach it and Argo Rollouts aborts and shifts every request back to the stable version on its own: ```mermaid stateDiagram-v2 [*] --> Canary10 : new version deployed Canary10 --> Analysis : setWeight 10% Analysis --> Canary50 : metrics pass Canary50 --> Pause : setWeight 50% Pause --> Full : promote Full --> [*] : stable Analysis --> Abort : metrics breach Abort --> Stable : all traffic back to old version Stable --> [*] ``` That turns a rollback from a 2 a.m. page into something that already happened. ## Verify Watch a real release move through the steps: ```console $ kubectl argo rollouts get rollout web --watch ``` Push a change and the weight climbs, pausing at each analysis gate. To see the escape edge fire, point the analysis at a metric you can break, then ship a version that breaks it: the weight stops climbing, the failed analysis is named, and traffic slides back to the stable version while you read the output. That is the safety net working, not failing.