Meguri Helm chart
Deploys the web/worker Deployment, Service, optional Ingress and PodDisruptionBudget, and runs a pre-install/pre-upgrade migrate Job that applies Cot migrations and the declarative instance configuration before the Deployment is updated. The chart contains no secrets and no Helm-managed database. Requires Kubernetes 1.29+ (native sidecars) and Helm 3.
What you provide
-
An image:
ultradesu/meguri:latestby default (build your own from the repositoryDockerfileand setimage.repository/image.tag; pin a tag for reproducible releases). -
A Secret in the release namespace, named by
secretName. All of its keys become environment variables:kubectl -n meguri create secret generic meguri-secrets \ --from-literal=DATABASE_URL='postgresql://USER:PERCENT_ENCODED_PASSWORD@HOST:5432/meguri' \ --from-literal=MEGURI_OIDC_CLIENT_SECRET='...'Per-tenant provider credentials (
MEGURI_JSM_<TENANT>_EMAIL/_TOKEN) go in the same Secret.extraSecretNameslists further Secrets injected the same way, for example one that holds onlyMEGURI_OIDC_CLIENT_SECRET. -
Your values. The two required ones are
publicUrl(the exact browser origin) andsecretName; everything about people and access lives underinstanceConfig.
Install and upgrade
helm upgrade --install meguri ./helm/meguri -n meguri --create-namespace -f my-values.yaml
kubectl -n meguri logs job/meguri-migrate-1 # what the sync did; revision number increments
instanceConfig is rendered verbatim into /etc/meguri/config.yaml (field reference:
deploy/instance-config.example.yaml, behavior: docs/deployment.md). The chart schema rejects
unknown fields and obviously invalid values at helm lint/install; the application validates it
again, and a rejected configuration fails the migrate Job, so the release stops before any pod
changes. A configuration change rolls the Deployment (checksum annotation) after the Job succeeded.
publicUrl: https://meguri.example.internal
secretName: meguri-secrets
image: {repository: ultradesu/meguri, tag: "1.4.0"}
instanceConfig:
auth: {password_login: false}
oidc:
issuer: https://sso.example.internal/realms/corp
client_id: meguri
instance_admin_groups: [/meguri/admins]
workspaces:
- key: payments
name: Payments
admin_groups: [/payments/leads]
member_groups: [/payments/team]
- key: customer-support
name: Customer Support
admin_groups: [/support/leads]
member_groups: [/support/team, /support/contractors]
Removing a workspace from workspaces disables it at the next release (data is kept; an
instance administrator can delete it permanently). Giving a new team access is one more list entry.
Break-glass administrator
Add instanceConfig.auth.bootstrap_admin.usernames: [rescue] and upgrade. The generated password is
printed in the migrate Job log (kubectl logs job/meguri-migrate-N) and rotates each UTC hour; anyone who can read
that log can sign in as an instance administrator, so remove the block as soon as SSO works again.
Finished Jobs are deleted after migrate.ttlSecondsAfterFinished (a day).
Notable values
| Value | Purpose |
|---|---|
replicaCount, resources, podDisruptionBudget |
Sizing and availability (publication is serialized by database leases, so replicas are safe). |
cloudSqlProxy.* |
Cloud SQL Auth Proxy native sidecar for the app and the Job; point DATABASE_URL at 127.0.0.1:5432. |
serviceAccount.create / .annotations |
Workload Identity account, created once at install (the pre-install hook needs it). Later annotation changes need kubectl annotate. |
ingress.* |
Host and TLS follow publicUrl. |
allowDisableAll |
Permit a release whose workspaces list is empty to disable every workspace. |
extraEnv, nodeSelector, tolerations, affinity, topologySpreadConstraints |
Usual scheduling and environment hooks. |
The demonstration mode is not available in the chart: it only runs on loopback.