[{"data":1,"prerenderedAt":685},["ShallowReactive",2],{"navigation_docs":3,"-operate-backup-and-restore":136,"-operate-backup-and-restore-surround":680},[4,26,47,68,89,110,123],{"title":5,"path":6,"stem":7,"children":8,"page":25},"Getting Started","\u002Fgetting-started","1.getting-started",[9,13,17,21],{"title":10,"path":11,"stem":12},"What you are running","\u002Fgetting-started\u002Fwhat-you-are-running","1.getting-started\u002F1.what-you-are-running",{"title":14,"path":15,"stem":16},"Architecture","\u002Fgetting-started\u002Farchitecture","1.getting-started\u002F2.architecture",{"title":18,"path":19,"stem":20},"Prerequisites","\u002Fgetting-started\u002Fprerequisites","1.getting-started\u002F3.prerequisites",{"title":22,"path":23,"stem":24},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F4.quickstart",false,{"title":27,"path":28,"stem":29,"children":30,"page":25},"Install","\u002Finstall","2.install",[31,35,39,43],{"title":32,"path":33,"stem":34},"Install the chart","\u002Finstall\u002Finstall-the-chart","2.install\u002F1.install-the-chart",{"title":36,"path":37,"stem":38},"Activation","\u002Finstall\u002Factivation","2.install\u002F2.activation",{"title":40,"path":41,"stem":42},"DNS and TLS","\u002Finstall\u002Fdns-and-tls","2.install\u002F3.dns-and-tls",{"title":44,"path":45,"stem":46},"Verify your install","\u002Finstall\u002Fverify-your-install","2.install\u002F4.verify-your-install",{"title":48,"path":49,"stem":50,"children":51,"page":25},"Configure","\u002Fconfigure","3.configure",[52,56,60,64],{"title":53,"path":54,"stem":55},"Data services","\u002Fconfigure\u002Fdata-services","3.configure\u002F1.data-services",{"title":57,"path":58,"stem":59},"Secrets","\u002Fconfigure\u002Fsecrets","3.configure\u002F2.secrets",{"title":61,"path":62,"stem":63},"Registry and air-gapped installs","\u002Fconfigure\u002Fregistry-and-airgap","3.configure\u002F3.registry-and-airgap",{"title":65,"path":66,"stem":67},"Integrations","\u002Fconfigure\u002Fintegrations","3.configure\u002F4.integrations",{"title":69,"path":70,"stem":71,"children":72,"page":25},"Licensing","\u002Flicensing","4.licensing",[73,77,81,85],{"title":74,"path":75,"stem":76},"How licensing works","\u002Flicensing\u002Fhow-licensing-works","4.licensing\u002F1.how-licensing-works",{"title":78,"path":79,"stem":80},"Your key never leaves","\u002Flicensing\u002Fyour-key-never-leaves","4.licensing\u002F2.your-key-never-leaves",{"title":82,"path":83,"stem":84},"What phones home","\u002Flicensing\u002Fwhat-phones-home","4.licensing\u002F3.what-phones-home",{"title":86,"path":87,"stem":88},"Revoke and recover","\u002Flicensing\u002Frevoke-and-recover","4.licensing\u002F4.revoke-and-recover",{"title":90,"path":91,"stem":92,"children":93,"page":25},"Operate","\u002Foperate","5.operate",[94,98,102,106],{"title":95,"path":96,"stem":97},"Upgrade","\u002Foperate\u002Fupgrade","5.operate\u002F1.upgrade",{"title":99,"path":100,"stem":101},"Backup and restore","\u002Foperate\u002Fbackup-and-restore","5.operate\u002F2.backup-and-restore",{"title":103,"path":104,"stem":105},"Observability","\u002Foperate\u002Fobservability","5.operate\u002F3.observability",{"title":107,"path":108,"stem":109},"High availability","\u002Foperate\u002Fhigh-availability","5.operate\u002F4.high-availability",{"title":111,"path":112,"stem":113,"children":114,"page":25},"Troubleshooting","\u002Ftroubleshooting","6.troubleshooting",[115,119],{"title":116,"path":117,"stem":118},"Install failures","\u002Ftroubleshooting\u002Finstall-failures","6.troubleshooting\u002F1.install-failures",{"title":120,"path":121,"stem":122},"Licensing failures","\u002Ftroubleshooting\u002Flicensing-failures","6.troubleshooting\u002F2.licensing-failures",{"title":124,"path":125,"stem":126,"children":127,"page":25},"Reference","\u002Freference","9.reference",[128,132],{"title":129,"path":130,"stem":131},"Helm values","\u002Freference\u002Fhelm-values","9.reference\u002F1.helm-values",{"title":133,"path":134,"stem":135},"Environment variables","\u002Freference\u002Fenvironment","9.reference\u002F2.environment",{"id":137,"title":99,"body":138,"description":673,"extension":674,"links":675,"meta":676,"navigation":677,"path":100,"seo":678,"stem":101,"__hash__":679},"docs\u002F5.operate\u002F2.backup-and-restore.md",{"type":139,"value":140,"toc":668},"minimark",[141,145,154,159,178,261,268,271,318,321,324,363,374,378,392,507,524,530,533,537,540,543,557,628,631,638,664],[142,143,99],"h1",{"id":144},"backup-and-restore",[146,147,148,149,153],"p",{},"Two things in the namespace hold state you cannot rebuild from the chart: your database, and the platform Secret. Everything else is rendered by ",[150,151,152],"code",{},"helm install"," and can be recreated at any time.",[155,156,158],"h2",{"id":157},"the-platform-secret","The platform Secret",[146,160,161,162,165,166,169,170,173,174,177],{},"The chart names it ",[150,163,164],{},"\u003Crelease>-platform-env",", so for a release called ",[150,167,168],{},"my-mvno"," it is ",[150,171,172],{},"my-mvno-platform-env",". It carries the values the chart generated (",[150,175,176],{},"JWT_SECRET",", the age KEK, the Postgres and Redis passwords, the session password) and the six keys the license agent writes into it:",[179,180,181,194],"table",{},[182,183,184],"thead",{},[185,186,187,191],"tr",{},[188,189,190],"th",{},"Key",[188,192,193],{},"What it is",[195,196,197,208,218,228,238,251],"tbody",{},[185,198,199,205],{},[200,201,202],"td",{},[150,203,204],{},"SIGNING_SEED",[200,206,207],{},"The deployment's private signing key, generated inside your cluster and never sent anywhere",[185,209,210,215],{},[200,211,212],{},[150,213,214],{},"POP_SIGNING_SEED",[200,216,217],{},"The current proof-of-possession key, rotated on every renewal",[185,219,220,225],{},[200,221,222],{},[150,223,224],{},"PARENT_LEASE_TOKEN",[200,226,227],{},"The license the platform is currently serving on",[185,229,230,235],{},[200,231,232],{},[150,233,234],{},"PARENT_BASE_URL",[200,236,237],{},"The parent this deployment is pinned to",[185,239,240,245],{},[200,241,242],{},[150,243,244],{},"REQUIRE_PARENT_LEASE",[200,246,247,250],{},[150,248,249],{},"true"," once enrollment succeeds, which is what makes the API fail closed",[185,252,253,258],{},[200,254,255],{},[150,256,257],{},"ACTIVATION_CODE_CONSUMED",[200,259,260],{},"The activation code already spent, so it is never replayed",[146,262,263,264,267],{},"A deployment the Hub has revoked also carries ",[150,265,266],{},"LEASE_STATUS",", cleared again once it recovers.",[146,269,270],{},"Back it up:",[272,273,278],"pre",{"className":274,"code":275,"language":276,"meta":277,"style":277},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","kubectl -n my-mvno get secret my-mvno-platform-env -o yaml > my-mvno-platform-env.backup.yaml\n","bash","",[150,279,280],{"__ignoreMap":277},[281,282,285,289,293,296,299,302,305,308,311,315],"span",{"class":283,"line":284},"line",1,[281,286,288],{"class":287},"sBMFI","kubectl",[281,290,292],{"class":291},"sfazB"," -n",[281,294,295],{"class":291}," my-mvno",[281,297,298],{"class":291}," get",[281,300,301],{"class":291}," secret",[281,303,304],{"class":291}," my-mvno-platform-env",[281,306,307],{"class":291}," -o",[281,309,310],{"class":291}," yaml",[281,312,314],{"class":313},"sMK4o"," >",[281,316,317],{"class":291}," my-mvno-platform-env.backup.yaml\n",[146,319,320],{},"That file is as sensitive as the cluster itself. It contains the signing key, the database password and the JWT secret in base64, which is encoding, not encryption. Store it wherever you keep your other production keys, encrypted at rest.",[146,322,323],{},"Restoring it is a plain apply:",[272,325,327],{"className":274,"code":326,"language":276,"meta":277,"style":277},"kubectl -n my-mvno apply -f my-mvno-platform-env.backup.yaml\nkubectl -n my-mvno rollout restart deploy\u002Fmy-mvno-platform-license-agent\n",[150,328,329,345],{"__ignoreMap":277},[281,330,331,333,335,337,340,343],{"class":283,"line":284},[281,332,288],{"class":287},[281,334,292],{"class":291},[281,336,295],{"class":291},[281,338,339],{"class":291}," apply",[281,341,342],{"class":291}," -f",[281,344,317],{"class":291},[281,346,348,350,352,354,357,360],{"class":283,"line":347},2,[281,349,288],{"class":287},[281,351,292],{"class":291},[281,353,295],{"class":291},[281,355,356],{"class":291}," rollout",[281,358,359],{"class":291}," restart",[281,361,362],{"class":291}," deploy\u002Fmy-mvno-platform-license-agent\n",[146,364,365,366,369,370,373],{},"If you already run SOPS, sealed-secrets or the External Secrets Operator, point ",[150,367,368],{},"secrets.existingSecret"," at your own Secret and your existing backup process covers this automatically. One caveat: the license agent patches keys into that Secret on every renewal, so do not enable a sync policy that prunes keys your secret store did not create. See ",[371,372,57],"a",{"href":58},".",[155,375,377],{"id":376},"the-database","The database",[146,379,380,383,384,387,388,391],{},[150,381,382],{},"postgres.mode=operator"," is the default, which means CloudNativePG owns the Postgres ",[150,385,386],{},"Cluster",", and CNPG has real backup primitives instead of a shell script wrapping ",[150,389,390],{},"pg_dump",". Point it at object storage and let it take backups on a schedule:",[272,393,397],{"className":394,"code":395,"language":396,"meta":277,"style":277},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","apiVersion: postgresql.cnpg.io\u002Fv1\nkind: ScheduledBackup\nmetadata:\n  name: my-mvno-platform-postgres-daily\n  namespace: my-mvno\nspec:\n  schedule: \"0 3 * * *\"\n  backupOwnerReference: self\n  cluster:\n    name: my-mvno-platform-postgres\n","yaml",[150,398,399,411,421,430,441,452,460,477,488,496],{"__ignoreMap":277},[281,400,401,405,408],{"class":283,"line":284},[281,402,404],{"class":403},"swJcz","apiVersion",[281,406,407],{"class":313},":",[281,409,410],{"class":291}," postgresql.cnpg.io\u002Fv1\n",[281,412,413,416,418],{"class":283,"line":347},[281,414,415],{"class":403},"kind",[281,417,407],{"class":313},[281,419,420],{"class":291}," ScheduledBackup\n",[281,422,424,427],{"class":283,"line":423},3,[281,425,426],{"class":403},"metadata",[281,428,429],{"class":313},":\n",[281,431,433,436,438],{"class":283,"line":432},4,[281,434,435],{"class":403},"  name",[281,437,407],{"class":313},[281,439,440],{"class":291}," my-mvno-platform-postgres-daily\n",[281,442,444,447,449],{"class":283,"line":443},5,[281,445,446],{"class":403},"  namespace",[281,448,407],{"class":313},[281,450,451],{"class":291}," my-mvno\n",[281,453,455,458],{"class":283,"line":454},6,[281,456,457],{"class":403},"spec",[281,459,429],{"class":313},[281,461,463,466,468,471,474],{"class":283,"line":462},7,[281,464,465],{"class":403},"  schedule",[281,467,407],{"class":313},[281,469,470],{"class":313}," \"",[281,472,473],{"class":291},"0 3 * * *",[281,475,476],{"class":313},"\"\n",[281,478,480,483,485],{"class":283,"line":479},8,[281,481,482],{"class":403},"  backupOwnerReference",[281,484,407],{"class":313},[281,486,487],{"class":291}," self\n",[281,489,491,494],{"class":283,"line":490},9,[281,492,493],{"class":403},"  cluster",[281,495,429],{"class":313},[281,497,499,502,504],{"class":283,"line":498},10,[281,500,501],{"class":403},"    name",[281,503,407],{"class":313},[281,505,506],{"class":291}," my-mvno-platform-postgres\n",[146,508,509,510,512,513,516,517,520,521,523],{},"That assumes the ",[150,511,386],{}," already has a ",[150,514,515],{},"barmanObjectStore"," (or another CNPG-supported destination) configured, which is cluster-level object storage config you own and apply yourself; the chart does not set one for you. Once it is there, CNPG also gives you point-in-time recovery: restore to any point covered by your retention window, not just the moment of the last dump. A one-off backup outside the schedule is a ",[150,518,519],{},"Backup"," resource pointed at the same ",[150,522,386],{}," name.",[146,525,526,529],{},[150,527,528],{},"postgres.mode=external","? Backups belong to that managed Postgres and its own tooling (RDS snapshots, your provider's PITR, whatever it offers), not to this chart.",[146,531,532],{},"A database backup on its own is only half a backup. Take the platform Secret at the same time, because the two have to match: the database contains rows encrypted with keys that live in the Secret.",[155,534,536],{"id":535},"losing-the-secret","Losing the Secret",[146,538,539],{},"This is recoverable. It is not the end of your deployment, and you do not lose customer data.",[146,541,542],{},"The signing key and the current license are both gone, so the deployment can no longer prove it is who it says it is. The fix is to enroll again from scratch:",[544,545,546,550],"ol",{},[547,548,549],"li",{},"Mint a fresh activation code from the Hub console (or from your parent MVNE's console, if that is what you activate against).",[547,551,552,553,556],{},"Run ",[150,554,555],{},"helm upgrade"," with the new code. The chart regenerates the Secret, and the license agent generates a new signing key inside your cluster and enrolls with it.",[272,558,560],{"className":274,"code":559,"language":276,"meta":277,"style":277},"helm upgrade my-mvno oci:\u002F\u002Fghcr.io\u002Fsolvegio\u002Fcharts\u002Fplatform \\\n  --version \u003Cversion> --namespace my-mvno -f my-values.yaml \\\n  --set activation.code=\u003Cnew-code>\n",[150,561,562,579,608],{"__ignoreMap":277},[281,563,564,567,570,572,575],{"class":283,"line":284},[281,565,566],{"class":287},"helm",[281,568,569],{"class":291}," upgrade",[281,571,295],{"class":291},[281,573,574],{"class":291}," oci:\u002F\u002Fghcr.io\u002Fsolvegio\u002Fcharts\u002Fplatform",[281,576,578],{"class":577},"sTEyZ"," \\\n",[281,580,581,584,587,590,593,596,599,601,603,606],{"class":283,"line":347},[281,582,583],{"class":291},"  --version",[281,585,586],{"class":313}," \u003C",[281,588,589],{"class":291},"versio",[281,591,592],{"class":577},"n",[281,594,595],{"class":313},">",[281,597,598],{"class":291}," --namespace",[281,600,295],{"class":291},[281,602,342],{"class":291},[281,604,605],{"class":291}," my-values.yaml",[281,607,578],{"class":577},[281,609,610,613,616,619,622,625],{"class":283,"line":423},[281,611,612],{"class":291},"  --set",[281,614,615],{"class":291}," activation.code=",[281,617,618],{"class":313},"\u003C",[281,620,621],{"class":291},"new-cod",[281,623,624],{"class":577},"e",[281,626,627],{"class":313},">\n",[146,629,630],{},"Two things are worth knowing before you take that path.",[146,632,633,634,637],{},"The old code cannot be replayed. It was consumed and bound to the signing key you just lost, so an attempt to reuse it fails with ",[150,635,636],{},"enrollment: activation code already used by a different key",". Always mint a new one.",[146,639,640,641,643,644,647,648,651,652,655,656,659,660,663],{},"In operator mode, the CNPG ",[150,642,386],{}," will not accept a regenerated app-role password on its own. The chart hands CNPG that password once, through ",[150,645,646],{},"bootstrap.initdb.secret",", at cluster creation on an empty volume; it is not something CNPG re-reads later. If you keep the existing PersistentVolumeClaim and let the chart generate a brand-new password, the running database still expects the old one and the API will not connect. So restore the Secret from backup wherever you possibly can, and treat regeneration as the path of last resort. If you must regenerate against an existing volume, reset the password inside Postgres by hand (",[150,649,650],{},"ALTER ROLE ... WITH PASSWORD ...",") to match the new Secret. The ",[150,653,654],{},"supabase_auth_admin"," role is different: CNPG's ",[150,657,658],{},"managed.roles"," keeps that one's password reconciled against the ",[150,661,662],{},"\u003Crelease>-platform-pg-auth-role"," Secret on every change, so it picks up a regenerated password without manual intervention. In external mode, the running database was never touched by the chart in the first place, so nothing here applies; the password mismatch, if any, is between you and your managed provider.",[665,666,667],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":277,"searchDepth":284,"depth":347,"links":669},[670,671,672],{"id":157,"depth":347,"text":158},{"id":376,"depth":347,"text":377},{"id":535,"depth":347,"text":536},"Back up the database and the platform Secret, and know what to do if either one is gone.","md",null,{},true,{"title":99,"description":673},"5iwDiaW72ee9hIBimo1zCZoh6OsbrGpuvGC_-JNig-g",[681,683],{"title":95,"path":96,"stem":97,"description":682,"children":-1},"Bump the chart version, run helm upgrade, and check that the platform came back licensed and serving.",{"title":103,"path":104,"stem":105,"description":684,"children":-1},"The license agent's Prometheus metrics, and the one alert that tells you a licensed platform is about to stop serving.",1783967741116]