Upgrading
helm upgrade edisyl \ oci://944311261080.dkr.ecr.us-east-1.amazonaws.com/edisyl-charts/edisyl-helm \ --version <new-chart-version> \ -n edisyl \ -f edisyl.values.yaml \ -f secrets.local.yaml \ -f auth-keys.local.yaml \ --wait --wait-for-jobs \ --timeout 20mPin --version, pass the same -f files as the install (with
edisyl.overrides.yaml after edisyl.values.yaml if you have one), and keep
the long timeout, exactly as on installing. This is
the command for every upgrade, including one that only changes
deploymentIdp.
--wait behaves differently here than on a first install. The migration runs
as a pre-upgrade hook, so it completes before the deployments are updated —
there is no ordering deadlock to avoid. With --wait-for-jobs added, Helm also
waits for the edisyl-idp-reconcile Job that registers your identity provider,
so a failed registration fails the upgrade instead of passing silently — see
Authentication.
--atomic is still worth avoiding: a rollback reverts the manifests while
leaving the migrated database as it is, which is the mismatch described below.
Before you upgrade
Section titled “Before you upgrade”Read the changelog for what changed in the platform between your current release and the target.
Update your image tags to match the chart version. Chart version and image tags move together; the version matrix publishes the tag set for each release, with a values block ready to copy. A new chart with old images is not a combination we test.
Take a database backup. Upgrades run migrations, and migrations are not reversible by re-installing the older chart.
What happens
Section titled “What happens”The migration hook runs to completion first, then the deployments roll. Expect a short window where old pods are still serving against an already-migrated database, so keep migrations backward-compatible with the release you are leaving — or accept a brief outage.
The LLM gateway runs a single replica, so every upgrade that touches it has a short window in which inference fails — see Known limitations.
Upgrading from 0.36 or earlier
Section titled “Upgrading from 0.36 or earlier”Charts 0.38.0 to 0.52.0 changed what a values file must say. A values file that installed 0.36.0 is refused by a current chart several times over, and each refusal names the key to change. Work through this section before the upgrade rather than one refusal at a time.
Values that moved or went away
Section titled “Values that moved or went away”Each old path left in place fails the render, except the dropped groups at the
end, which render Secrets nothing reads. Under external-secrets, apply the
same move to a group’s keys and remoteKeys as to its data.
| Old path | New path | Since |
|---|---|---|
| — | deploymentIdp.metadataUrl or deploymentIdp.metadataXml, and deploymentIdp.domains — required; see Authentication |
0.38.0 |
config.staffSsoProviderId |
Remove. The API trusts the provider the IdP Job records | 0.40.0 |
secrets.managed.edisyl-cloudflare.data.CLOUDFLARE_R2_ACCESS_KEY_ID, CLOUDFLARE_R2_SECRET_ACCESS_KEY |
secrets.managed.edisyl-object-storage.data.OBJECT_STORAGE_ACCESS_KEY_ID, OBJECT_STORAGE_SECRET_ACCESS_KEY |
0.42.0 |
OBJECT_STORAGE_PROVIDER: r2 |
config.objectStorageProvider: s3compatible and config.objectStorageUrl: https://<account-id>.r2.cloudflarestorage.com |
0.42.0 |
secrets.managed.edisyl-object-storage.data.OBJECT_STORAGE_PROVIDER |
config.objectStorageProvider |
0.46.0 |
…edisyl-object-storage.data.OBJECT_STORAGE_BUCKET |
config.objectStorageBucket — always required |
0.46.0 |
…edisyl-object-storage.data.OBJECT_STORAGE_REGION |
config.objectStorageRegion |
0.46.0 |
…edisyl-object-storage.data.OBJECT_STORAGE_PUBLIC_URL |
config.objectStoragePublicUrl |
0.46.0 |
…edisyl-object-storage.data.OBJECT_STORAGE_FORCE_PATH_STYLE |
config.objectStorageForcePathStyle |
0.46.0 |
…edisyl-object-storage.data.OBJECT_STORAGE_ENDPOINT |
config.objectStorageUrl |
0.46.0 |
secrets.managed.edisyl-redis.data.REDIS_URL |
Remove | 0.46.0 |
…edisyl-redis.data.REDIS_HOST, REDIS_PORT, REDIS_USER, REDIS_TLS |
config.redisHost, config.redisPort, config.redisUser, config.redisTls |
0.46.0 |
secrets.managed.edisyl-ses.data.SES_FROM_EMAIL |
config.emailFrom — required in every install |
0.46.0 |
secrets.managed.edisyl-sentry.data.SENTRY_DSN_API, _WORKER, _EDISYL |
config.sentryDsnApi, config.sentryDsnWorker, config.sentryDsnEdisyl |
0.46.0 |
secrets.managed.edisyl-github.data.GITHUB_APP_ID |
config.githubAppId |
0.46.0 |
secrets.managed.edisyl-database.data.DATABASE_POOL_SIZE |
config.databasePoolSize |
0.46.0 |
secrets.managed.edisyl-supabase, edisyl-realtime, edisyl-ses, edisyl-sentry |
Remove the whole group | 0.46.0 |
edisyl.authSource |
Remove. Auth is always the chart’s own service | 0.46.0 |
edisyl.auth.enabled: false |
Remove; it must be true, the default |
0.46.0 |
edisyl.auth.google, and GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID / _SECRET in edisyl-auth |
Remove. SAML is the only sign-in path | 0.46.0 |
secrets.managed.edisyl-llm-gateway.data.LLM_GATEWAY_URL |
Remove. Derived from bifrost.enabled or bifrost.external.url |
0.46.0 |
secrets.managed.edisyl-llm-gateway.data.LLM_GATEWAY_PROVIDER |
Remove | 0.47.0 |
| — | bifrost.database.source and its connection — required, since the gateway always runs |
0.47.0 |
config.portApi |
Remove. The API listens on edisyl.api.port |
0.49.0 |
secrets.managed.edisyl-rudderstack.data.RUDDERSTACK_DATA_PLANE_URL |
config.rudderstackUrl — required with config.rudderstackEnabled |
0.49.0 |
secrets.managed.edisyl-mono-api-key.data.MONO_API_KEY |
secrets.managed.edisyl-mono-api-key.data.MONO_API_KEYS |
0.49.0 |
secrets.managed.edisyl-auth-service-key, edisyl-provider-webhook, edisyl-snowflake, edisyl-resend, edisyl-integrations-social, edisyl-hubspot |
Remove the whole group. Nothing reads it | 0.42.0 |
App envFrom lists. If you override edisyl.<app>.envFrom.secrets, remove
every group you removed above from it — a list that still names
edisyl-supabase, edisyl-ses, edisyl-sentry or edisyl-realtime is
refused, because the pod would never start. Helm replaces a list wholesale, so
an override also misses groups added since, such as edisyl-typesafe; drop the
override if you can, or rebuild it from the current chart’s default.
Secrets and the store
Section titled “Secrets and the store”MONO_API_KEYS.MONO_API_KEYbecameMONO_API_KEYS, a comma-separated list the API accepts any entry of and every caller sends the first of. Underk8s-nativethe generated value carries over on its own. An external store needsMONO_API_KEYS, with the same value, before you upgrade. KeepMONO_API_KEYin the store until no environment can roll back below 0.49.0.- TypeSafe. From 0.50.0 the API mounts
edisyl-typesafe, and underexternal-secretsthe store must carryTYPESAFE_API_KEYandTYPESAFE_BASE_URL— or setsecrets.managed.edisyl-typesafe.keys: []to leave the group out. A missing key fails the ExternalSecret, and the API cannot start without it. - Auth. The store names for the auth keys are
AUTH_SELFHOSTED_ANON_KEYandAUTH_SELFHOSTED_ADMIN_TOKEN, alongsideGOTRUE_JWT_KEYS,GOTRUE_JWT_SECRETandGOTRUE_SAML_PRIVATE_KEY. An install moving off an external auth project also needs a database for the auth service. That project’s users and sessions do not move: everyone signs in again. Afterwards, revoke the old project’s service-role key.
The LLM gateway cutover
Section titled “The LLM gateway cutover”On 0.36.0 the bundled gateway was off by default and inference went wherever
edisyl-llm-gateway pointed. From 0.47.0 the bundled gateway is the only one
and every inference call goes to it — or to another deployment’s gateway named
in bifrost.external.url. There is no third option. Before upgrading:
- Decide where the gateway runs. Bundled (the default) needs a database —
bifrost.database.source: cnpgon the bundled cluster, orexisting-secretnaming a Secret with discrete connection keys; see Using your own infrastructure. A gateway you don’t run needsbifrost.enabled: false,bifrost.external.urland its credentials. - Configure its providers before traffic moves. A fresh gateway knows no
provider, so every inference call fails until one is added. To avoid an
outage, enable the gateway on your current chart first
(
bifrost.enabled: trueand its database), add the providers on Edisyl’s provider-settings page and prove they answer, and only then upgrade. On charts before 0.46.0 enabling it moves no traffic. - Replace the gateway key. See the note below.
After the upgrade
Section titled “After the upgrade”Helm leaves a key it no longer renders in the live Secret, so the moved keys
are still there after helm upgrade. The ConfigMap is read last and wins, so a
stale key never overrides a value it carries — but it still applies where the
ConfigMap leaves a blank optional key out. Remove the stale keys after
helm upgrade has finished, with k8s-native Secrets (under
external-secrets the operator rewrites each Secret from the store on its next
refresh):
strip() { # strip <secret> <key>... local s=$1; shift local jq_del; jq_del=$(printf 'del(.data["%s"]) | ' "$@"); jq_del=${jq_del% | } kubectl -n edisyl get secret "$s" -o json | jq "$jq_del" | kubectl -n edisyl replace -f -}strip edisyl-object-storage OBJECT_STORAGE_PROVIDER OBJECT_STORAGE_BUCKET \ OBJECT_STORAGE_REGION OBJECT_STORAGE_PUBLIC_URL OBJECT_STORAGE_ENDPOINT \ OBJECT_STORAGE_FORCE_PATH_STYLEstrip edisyl-redis REDIS_URL REDIS_HOST REDIS_PORT REDIS_USER REDIS_TLSstrip edisyl-github GITHUB_APP_IDstrip edisyl-llm-gateway LLM_GATEWAY_URLstrip edisyl-rudderstack RUDDERSTACK_DATA_PLANE_URLstrip edisyl-mono-api-key MONO_API_KEY # once api and worker read MONO_API_KEYSstrip edisyl-database DATABASE_POOL_SIZE # only with database.source: managedstrip edisyl-auth GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID GOTRUE_EXTERNAL_GOOGLE_SECRETkubectl -n edisyl rollout restart deploy/api deploy/worker deploy/edisylRemoving a key that is not there is a no-op, so each line is safe on an
install that never had it. The restart follows because envFrom snapshots the
environment at container start.
Do not delete these Secrets to get the same effect. edisyl-database is
mounted by the pre-upgrade migration hook under database.source: managed, and
Helm cannot re-create it until that hook has finished, so deleting it
deadlocks the next upgrade. Remove only the stale keys.
The upgrade also deletes the edisyl-supabase, edisyl-ses, edisyl-sentry
and edisyl-realtime Secrets while old pods still reference them. An old pod
that restarts before the rollout finishes cannot start until its replacement
is up.
Rolling back
Section titled “Rolling back”helm rollback edisyl <revision> -n edisylThis reverts manifests. It does not revert migrations. If the release you are leaving applied a schema change, the older application code may not run against the migrated database. Treat rollback as a way to recover from a bad configuration, not from a bad migration — for that, restore your backup.
Rollback does not delete an existing database cluster that both revisions
declare. It is helm uninstall that destroys it — see
Installing.
Keeping generated secrets stable
Section titled “Keeping generated secrets stable”If you let the chart generate secrets, they are generated once and reused by
looking up the existing Secret in the cluster. A plain helm upgrade against
a live cluster preserves them.
Rendering without cluster access does not. Under Argo CD, or anywhere the
manifests are produced by helm template, the lookup returns empty and every
generated value is regenerated — including ENCRYPTION_KEY, which orphans
data encrypted under the previous one, and BIFROST_ENCRYPTION_KEY, which
orphans every provider credential the gateway holds. Supply those values
explicitly instead; see
Configuration.
Was this page helpful?
Thanks for the feedback.
