FrankenPress is built from four independent repos that move at their
own cadence. Upgrades happen at three levels — runtime, mu-plugin,
site image — and one operations-side level: chart.
Component upgrade order
mu-plugin → runtime → your site image → charts
(release) (bake new (rebuild on top (helm upgrade
mu-plugin tag) of new runtime) with new tag)
Most upgrades skip steps. A typical example:
| Change | Upgrade path |
|---|
| WP plugin / theme bump | site image only — composer update, tag, deploy |
| WP core bump | site image — bump roots/wordpress constraint, tag, deploy |
| FrankenPHP / Souin / Caddy module bump | runtime → site image — bump FRANKENPHP_VERSION etc., tag runtime, rebuild site image, deploy |
| Cache invalidation logic change | mu-plugin → runtime → site image |
| Helm chart change (new value, RBAC, etc.) | charts only — helm upgrade --version <new> |
Site image upgrade
The most common case. In your site-template fork:
git tag v1.2.0
git push origin v1.2.0
CI builds and pushes ghcr.io/<your-org>/<your-site>:v1.2.0. Then in
the cluster:
helm upgrade mysite oci://ghcr.io/frankenpress/charts/site \
--namespace mysite \
--reuse-values \
--set image.tag=v1.2.0
The chart re-rolls the Deployment, draining old pods according to your
updateStrategy (default rolling update with maxSurge: 1,
maxUnavailable: 0).
The chart adds checksum/config and checksum/secret annotations
to the pod template. If you change a ConfigMap or Secret value
via helm upgrade, the pods will roll automatically — no manual
pod restart needed.
What the post-upgrade install Job does
Every helm upgrade (and the initial helm install) fires a
post-upgrade hook Job named <release>-site-install. The Job
runs two things, both idempotent:
wp core is-installed — short-circuits the install branch on every
upgrade after the first.
wp core update-db — applies any pending schema migrations from
the WP core version baked into the new image. No-op if already
current.
Admin credential reconciliation moved out of the install Job in chart
v0.4.0 to a Pod-lifecycle sync-admin-credentials initContainer —
self-driving on every Pod roll, not gated on helm upgrade. See
Admin credential rotation.
Watch a single upgrade’s Job complete:
kubectl --namespace <ns> get jobs --watch
The Job uses helm.sh/hook-delete-policy: hook-succeeded, so the
pod and Job object disappear after a successful run — read logs from
the install pod while it’s running (kubectl logs -f job/<release>-site-install), or check kubectl get events for
historical confirmation.
If the Job fails, the upgrade fails too — the new Deployment still
rolls (Helm hooks are non-blocking by default), but you’ll see a
loud error in helm upgrade output. Common cause: DB unreachable
from the install pod. The Job’s set -e script bails fast and
backoffLimit: 6 retries before failing the Job.
Chart upgrade
helm upgrade mysite oci://ghcr.io/frankenpress/charts/site \
--version 0.13.2 \
--namespace mysite \
--reuse-values
--reuse-values keeps your existing overrides (image tag, S3 bucket,
etc.). Without it you’d need to repeat every --set from the original
install.
Reading the release notes
Each repo publishes release notes on GitHub:
Breaking changes are flagged at the top of each release. Treat any
major version bump (e.g. 0.x → 1.0, 1.x → 2.0) as requiring a
read-through before upgrading.
Backups before major upgrades
For production:
- Database snapshot — your DB layer (RDS / MariaDB Operator backup CR / etc.) handles this. Verify the latest snapshot is recent before triggering the upgrade.
- No filesystem state to back up — the site image is immutable, uploads live in S3. There’s nothing local on the pod to lose.
- Image artefact is preserved — GHCR retains all image tags by default; a rollback is
helm upgrade --set image.tag=<previous-tag>.
Rollback
helm rollback mysite --namespace mysite
This reverts to the previous release revision. To rollback further:
helm history mysite --namespace mysite
helm rollback mysite <revision> --namespace mysite
Database schema changes don’t auto-rollback; if a release introduced a
WP DB migration that’s incompatible with the previous code, you need a
DB restore alongside the helm rollback. WP core upgrades and most
plugin upgrades are forward-compatible, but verify per release.