Content Management that can withstand the plundering hoards

Upgrades

Use this procedure for an administrator-managed deployment. Run commands from repository root after selecting the intended cluster context. Start with a verified backup and record existing image references, Website manifests, installed CRD/RBAC and active release IDs. Kubernetes workload rollback alone does not restore a changed schema or writable data.

Upgrade procedure

  1. Review the release notes and settings reference, and test the target version on an isolated restored site. Check legacy authentication, admission defaults, ingress fields and automatic Ipseity behaviour described below.
  2. Update the canonical/portable CRD and RBAC copies in the deployment source. For Orbit, synchronize its separate copies too; the script below handles the CRD only, so review RBAC separately.
  3. Apply the new CRD and required RBAC before rolling the controller. For the portable install, use kubectl apply -f deploy/01-crd.yaml and kubectl apply -f deploy/02-operator-rbac.yaml with reviewed manifests.
  4. Set the controller image and its --frontend-image/--cms-image arguments to the intended compatible versions, then deploy the updated operator manifest. These settings affect existing Websites managed by that operator. Reusing the same image string does not force pod recreation just because it was repushed.
  5. Check kubectl rollout status deployment/viking-cms-controller -n viking-cms, Website conditions/generation, site Deployment rollouts, CMS sign-in/readiness, public responses and the running Server/build versions. The CMS uses Recreate, so expect an editing interruption; frontend uses rolling updates.
  6. Reapply intended Website fields that an older schema pruned. Confirm stored fields with kubectl get website NAME -n NAMESPACE -o yaml. Do a controlled save/preview/publish and a retained-release rollback on a test site before considering the upgrade verified.

If verification fails, inspect component logs/conditions before more mutation. Roll back image references only if the old binary is compatible with current schema/data. Otherwise follow the prepared matched-volume/configuration restore procedure. Do not delete the CRD or PVCs as an upgrade troubleshooting step.

Data-preservation requirements

Upgrades must preserve:

Operator upgrades

Upgrade the operator image in deploy/03-operator.yaml (or the Orbit Deploy image mapping) and roll the Deployment. Reconciliation is idempotent: applying the new operator re-reconciles existing Website resources against their declared state without destructive changes to workloads or storage.

CRD schema evolution

Review compatibility and migration instructions before applying an updated CRD.

cms.authentication is a flattened reference: it must contain a secretRef with a non-empty name when supplied. Omitted CMS hostnames now default to cms.<domain> and omitted authentication can use automatic Ipseity integration. Upgrading to the flattened schema (from the older oauth2/basic mechanism nodes) rejects Website objects with an empty authentication: {} and any object still using authentication.oauth2 / authentication.basic at the API level. Existing Website objects must be migrated to cms.authentication.secretRef.name (and the referenced Secret converted to the new key format — see Authentication) before applying the new CRD. Similarly, frontend.replicas has no schema default in the CRD — the operator defaults a nil value to 2; an explicit 0 is scale-to-zero, so a previously-defaulted 2 remains 2.

When upgrading from older implementations, check these compatibility changes:

Use the portable deploy/01-crd.yaml from the target release alongside compatible controller, CMS and frontend images.

Ingress TLS and cert-manager options

Upgrading the controller image alone does not update the CRD installed by Orbit Deploy. The Orbit deployment repository has its own copy at default/01-crd.yaml; it must include spec.ingress.tls, issuer and cluster_issuer. An older schema prunes these unknown fields before storing the Website, so the operator sees default TLS and no issuer selection.

Before deploying a schema change, synchronise and review the local Orbit copy:

scripts/sync-orbit-crd.sh /path/to/orbit-deployments/viking-cms
scripts/sync-orbit-crd.sh --check /path/to/orbit-deployments/viking-cms

The script defaults to this checkout's orbit-deployments link. It only edits the local CRD manifest; committing and deploying remain separate actions.

Deploy the corrected CRD through Orbit Deploy before reapplying affected Website specifications. Fields already pruned from stored Websites cannot be recovered by upgrading the schema; restore the intended values from the original Website manifest. For example, plain HTTP uses:

spec:
  ingress:
    className: tak-os
    tls: false

TLS with a cluster-scoped certificate issuer instead uses:

spec:
  ingress:
    className: tak-os
    tls: true
    cluster_issuer: letsencrypt-prod

For a namespaced Issuer, use issuer instead of cluster_issuer. These are Website fields, not controller command-line flags. After updating the Website, check its stored spec.ingress and both generated Ingresses; the operator reconciles TLS and issuer changes without an operator restart. The CMS itself still requires HTTPS for its production OAuth2 configuration; turning off ingress TLS does not change its authentication or secure-cookie settings.

Data retention

PVC objects are retained when a Website is deleted; they must be removed manually. This is separate from the PV/storage class reclaim policy: deleting a PVC can still delete its actual backing volume. Rollback history and releases subject to retention are not a replacement for storage backups — snapshot the PVCs before major upgrades.

Automatic Ipseity provisioning

Apply the new CRD and RBAC before rolling out the controller. This adds spec.description and spec.cms.enabled, relaxes authentication/hostname admission rules for automatic provisioning, and grants namespace label patches and writes to retained Ipseity ConfigMaps and owned authentication Secrets. Both the portable and Orbit CRD/RBAC copies must be updated. No changes to existing explicit authentication references are required. Review Websites with no CMS configuration: when Ipseity is discovered these now receive an authenticated CMS unless spec.cms.enabled: false is set. See Ipseity authentication for discovery, initial administrator, namespace isolation, and retained identity records.

Verify the installed schema

Confirm that the installed CRD matches the reviewed release manifest before changing Website settings. After applying it, inspect the stored Website with kubectl get website NAME -n NAMESPACE -o yaml and compare the fields you set. Follow the troubleshooting steps if expected fields are absent, then reapply the original Website manifest once the corrected schema is installed.