Upgrades¶
MEHO upgrades are a standard helm upgrade with two things worth
understanding before your first one: migrations run before the new
version rolls, and Helm 4's server-side apply can surface
field-ownership conflicts on clusters where someone once hand-patched
the Deployment.
What helm upgrade does¶
helm upgrade meho oci://ghcr.io/evoila/meho-chart \
--version <chart-version> -n meho -f values.yaml
- The pre-upgrade migration Job runs every pending database
migration first. If a migration fails, the release fails and the
old Pods keep serving — an unmigrated schema never meets a new
application version. Failed Jobs are retained for ten minutes for
kubectl logs. - Only after migrations succeed does the new Deployment roll.
Keep the image tag pinned and immutable (v<x.y.z> or
sha-<git-sha>) — :latest is never published, and :main is a
moving dev alias, not a deploy target.
Helm 4 field-ownership conflicts¶
Helm 4 applies upgrades via Kubernetes server-side apply, which
tracks who owns every field of every object. If an operator once
hand-patched the live Deployment (kubectl patch / kubectl edit)
with a field a newer chart now sets, the upgrade fails with:
Apply failed with 1 conflict: conflict with "kubectl-patch"
Pre-flight check — look for foreign field managers before upgrading:
kubectl get deploy meho -n meho -o yaml --show-managed-fields \
| grep 'manager:'
Any manager other than Helm's own, owning a field the chart renders, will conflict. The remedy is to hand those fields to the chart:
helm upgrade meho oci://ghcr.io/evoila/meho-chart \
--version <chart-version> -n meho -f values.yaml --force-conflicts
--force-conflicts overwrites the conflicting fields and transfers
ownership to Helm. (Observed in the field: --take-ownership is not
the right flag here — it adopts whole un-owned resources, not
individual fields, and does not clear a per-field conflict.)
Rollback¶
helm rollback meho is supported, with one asymmetry to know:
migrations are forward-only. A rollback reverts the application
version but not the schema — there is no automatic downgrade, so the
older application runs against the newer schema and relies on the
backend tolerating it. What "verified rollback" means precisely, and
the schema-check fallback when it cannot be, is specified in the
rollback acceptance contract.
Version-specific notes¶
Read these when your upgrade crosses the version in question:
| Crossing | What changes | Action |
|---|---|---|
| v0.15.0 | Vault secret references became tenant-scoped by default: schemeless refs resolve under secret/tenants/<tenant-id>/…. |
Migrate existing target secret_refs to the tenant-scoped layout, or temporarily hold the old behaviour with the VAULT_KV_TENANT_SCOPE_PREFIX="" env override (via extraEnv) until migrated. Guide: docs/codebase/connectors-vault-tenant-scope.md. Google Secret Manager deployments are unaffected. |
| v0.22.0 | First release to ship the backplane startup probe in the chart. | If you ever hand-patched a startupProbe onto the Deployment, this is the textbook field-ownership conflict above — pre-flight and use --force-conflicts. |
The authoritative, always-current version of this table lives in
docs/deploying.md;
release notes for each version are on the
releases page with the full
narrative in the
CHANGELOG.
Day-2 operations beyond upgrades¶
Backup/restore and observability guides land on this site with MEHO's disaster-recovery workstream. Until then: PostgreSQL is MEHO's durable application store and the thing to back up first (see the reference architecture); the Valkey activity feed is ephemeral by design.
A PostgreSQL restore alone does not rebuild a working deployment. The target credentials themselves live in Vault or Google Secret Manager, realm and client configuration lives in Keycloak, and your TLS Secrets and Helm values live in the cluster and in whatever you keep them under version control in. Each needs its own backup or reprovisioning path until the full guide lands.