Deploy an update
Most deploys are one git commit. ArgoCD sees the change, applies it, the pods roll. No buttons pressed, no SSH, no kubectl apply.
The three shapes of "an update"
Nearly every change falls into one of these:
1. Bumping an image version (most common)
Example: a dev team shipped 4.99.11.0-wecare and you want to deploy it.
# Edit the image tag in the relevant manifest
$EDITOR manifests_v1/app-constructs/ecommercen-clients/wecare/adveshop4/base/kustomization.yamlFind the images: section:
images:
- name: ecommercen/adveshop4-php_fpm
newTag: 4.99.10.0-wecare # ← change this
- name: ecommercen/adveshop4-php_cli
newTag: 4.99.10.0-wecareBump to the new tag, save, then:
git add -p # review diff line by line
git commit -m "[App: wecare] Bump image to 4.99.11.0-wecare"
git pushWithin ~1 minute ArgoCD picks up the push. The Deployment's spec.template.spec.containers[*].image changes. Kubernetes' Deployment controller rolls pods one-by-one (maxSurge: 50%, maxUnavailable: 0 → always at least the old count running until new ones are Ready).
2. Changing a config setting
Example: wecare needs pm.max_children raised from 50 to 75.
$EDITOR manifests_v1/app-constructs/ecommercen-clients/wecare/adveshop4/base/app.yaml
# find the `app-web-fpm-www-cm` ConfigMap, edit the valueCommit + push. ArgoCD applies the new ConfigMap. Stakater Reloader notices the ConfigMap changed and triggers a rolling restart of the Deployment that mounts it. No manual pod action needed.
3. Upgrading an upstream component (ArgoCD, Longhorn, etc)
We have a scripted workflow for this:
python3 scripts/check-updates.py # see what's outdated
python3 scripts/do-updates.py --dry-run # preview
python3 scripts/do-updates.py # apply all safe updates + commit
git push origin mainThe scripts read scripts/apps.yaml (single source of truth for versions). They know which updates are safe-auto (patch bumps), which need a human (major bumps, skip_major: true), and which are manual-only (e.g., operators that require migration steps).
See Tracked apps for the list.
How to tell it landed
Three signals, in increasing confidence order:
1. ArgoCD status
argocd app get app-wecare-adveshop4-prod
# or click the app in the web UILook for:
Sync Status: SyncedHealth Status: Healthy(Progressing while rolling out, which is fine)
2. Pod age / image
kubectl -n ecommercen-clients-wecare \
get pods -l app.kubernetes.io/name=app-web -o wideNew pods should have a recent AGE and the new image. If any pod is still on the old image after a few minutes, the rollout got stuck — see Check app status.
3. Live behaviour
Hit the site, watch Grafana. For wecare, open the Operations dashboard — the P95 latency shouldn't spike, 5xx rate should stay near 0 through the rollout.
Rolling back
The standard answer is not kubectl rollout undo. That works but gets reverted by ArgoCD within a minute because it doesn't match the repo.
The right answer: git revert the commit, push. Same flow as a deploy, just backwards.
git log --oneline | head -5 # find the commit to undo
git revert <commit-sha>
git pushArgoCD syncs the revert; pods roll back to the previous image. Full audit trail in git.
When things get ambitious
| Change | Shape | Risk |
|---|---|---|
| Image tag bump (patch version) | Simple commit | Low — rolling update, easy revert |
| Image tag bump (major version) | Simple commit but test staging first | Medium — may require DB migration |
| New env var | Commit + Reloader restart | Low |
| KEDA scaling threshold | Commit, next scale event picks it up | Low |
| New Ingress hostname | Commit + Cloudflare DNS record | Medium — DNS propagation |
| New client onboarding | See Add a client | Medium — many moving parts |
| MariaDB major version | Operator recovery + db-manager agent | High — test on staging first |
| Kubernetes version bump | Terraform-driven node replacement + staged rollout | High — maintenance window |
When in doubt
Delegate to the relevant Claude agent — they know the patterns and the safety rails:
- Image bumps / routine: just go.
- App updates via scripts/apps.yaml: the update-checker agent (or
do-updates.py+ read the output). - Client-scoped changes: the gitops-commit-pusher + argocd-manager agents for a sanity-checked flow.
- Anything touching DB / Redis state: the db-manager agent first, always.
Further reading
- GitOps & ArgoCD
- Check app status if the deploy looks stuck
- Incident response if the deploy broke something