Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions docs/docs/deployment-self-hosting/upgrading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
sidebar_label: Upgrading
title: Upgrading and rolling back
sidebar_position: 4
---

This page explains how to upgrade a self-hosted Flagsmith deployment that was installed with the Flagsmith Helm chart,
and what to do if you need to go back. It is based on a test upgrade from chart 0.80.0 (Flagsmith 2.222.0) to chart
0.85.0 (Flagsmith 2.286.0) on a local [kind](https://kind.sigs.k8s.io/) cluster with default values.

An upgrade changes two things: the application and the database schema. Helm manages the first, but not the second. That
difference matters most when you need to roll back.

![The application and database at each stage of an upgrade, rollback and restore](../diagrams/upgrade-rollback-restore.svg)

## Before you upgrade

1. Read the release notes for every version between the one you run and the one you are moving to.
2. Note your current Helm revision, so you know what to roll back to:

```bash
helm history -n flagsmith flagsmith
```

3. Back up the database, check the backup can be read, and store a copy outside the cluster. The commands below show how
to do this for the PostgreSQL instance deployed by the chart.

### Back up the PostgreSQL instance deployed by the chart

:::info

These commands use the pod name `flagsmith-dev-postgresql-0`, the `postgres` user and the `POSTGRES_PASSWORD` and
`POSTGRES_DB` variables that were set in that pod during testing. Check them with
`kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- env`. If you use an external or managed database, use your
provider's snapshot or dump tools instead.

:::

```bash
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c \
'PGPASSWORD=$POSTGRES_PASSWORD pg_dump -U postgres -Fc -f /tmp/backup.dump $POSTGRES_DB'
Comment on lines +40 to +41

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Stability & Availability · Quick win

Supported by static analysis

Script executed:

rg -n 'postgresql|ephemeral-storage|emptyDir' charts deploy helm 2>/dev/null | head -120

Repository: Flagsmith/flagsmith

Length of output: 157


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
rg --files | rg -i '(^|/)(chart|charts|helm|values|postgresql)|Chart\.yaml'
rg -n -i -e 'postgresql' -e 'ephemeral.storage' -e 'emptyDir' -- docs/docs/deployment-self-hosting | sed -n '1,200p'

Repository: Flagsmith/flagsmith

Length of output: 34026


Web query:

Kubernetes documentation local ephemeral storage container writable layer eviction limits node disk pressure

Result:

Sources consulted:
- Local ephemeral storage | Kubernetes — https://kubernetes.io/docs/concepts/storage/ephemeral-storage/
- Node-pressure Eviction | Kubernetes — https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/
- Resource Management for Pods and Containers | Kubernetes — https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- Resource Management for Pods and Containers | Kubernetes — https://v1-35.docs.kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- Resource Management for Pods and Containers | Kubernetes — https://v1-36.docs.kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- …and 7 more

Script executed:

nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '1,120p;210,255p;575,595p;710,725p'
rg -n -i -e 'helm\.flagsmith' -e 'flagsmith-charts' -e 'github.com/flagsmith/.*helm' -e 'devPostgresql' -- docs .github | sed -n '1,160p'
git remote -v

Repository: Flagsmith/flagsmith

Length of output: 14658


Web query:

Flagsmith helm chart 0.85.0 dev-postgresql /tmp mount ephemeral storage statefulset github

Result:

Sources consulted:
- CVE-2026-15742: which Helm charts and container images are affected · StackRadar Chart Index — https://charts.stackradar.io/vulns/CVE-2026-15742
- Releases · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/releases
- flagsmith/docker-compose.pgpool.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.pgpool.yml
- charts/stable/postgresql/README.md at master · helm/charts · GitHub — https://github.com/helm/charts/blob/master/stable/postgresql/README.md
- Flagsmith Helm Chart | Datree — https://www.datree.io/helm-chart/flagsmith-flagsmith
- …and 49 more

Script executed:

set -o pipefail
for url in \
  https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/0.85.0/charts/flagsmith/values.yaml \
  https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/0.85.0/charts/flagsmith/templates/postgresql/statefulset.yaml \
  https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/0.85.0/charts/flagsmith/templates/postgresql.yaml \
  https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/main/charts/flagsmith/values.yaml \
  https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/main/charts/flagsmith/templates/postgresql/statefulset.yaml
do
  echo "===== $url ====="
  curl -fsSL "$url" || true
done

Repository: Flagsmith/flagsmith

Length of output: 28860


Script executed:

python3 - <<'PY'
import urllib.request, tarfile, io
for ver in ['0.80.0','0.85.0']:
    url=f'https://github.com/Flagsmith/flagsmith-charts/releases/download/flagsmith-{ver}/flagsmith-{ver}.tgz'
    print('ARCHIVE',url)
    try:
        data=urllib.request.urlopen(url,timeout=20).read()
        chart=tarfile.open(fileobj=io.BytesIO(data),mode='r:gz')
        names=chart.getnames()
        print('POSTGRES FILES',*[x for x in names if 'postgres' in x.lower()][:80],sep='\n')
        for m in chart.getmembers():
            if m.name in ['flagsmith/Chart.yaml','flagsmith/Chart.lock','flagsmith/values.yaml'] or ('postgresql' in m.name and (m.name.endswith('statefulset.yaml') or m.name.endswith('values.yaml'))):
                if m.isfile():
                    print('\nFILE',m.name)
                    for i,l in enumerate(chart.extractfile(m).read().decode().splitlines(),1):
                        if m.name.endswith('values.yaml'):
                            if any(x in l.lower() for x in ['postgresql','/tmp','resources','persistence','volume','ephemeral']):
                                print(f'{i}: {l}')
                        else:
                            print(f'{i}: {l}')
    except Exception as e:
        print(type(e).__name__,str(e))
PY

Repository: Flagsmith/flagsmith

Length of output: 42236


Stream the PostgreSQL dump outside the pod.

The command first writes /tmp/backup.dump inside the PostgreSQL container. A dump larger than the container's writable layer can fail with insufficient space, and node local-storage pressure can evict the pod. Stream pg_dump to the local machine, then update the validation and restore commands to use that local file.

```

Check the backup can be read. A number greater than zero means the file contains your tables:

```bash
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c 'pg_restore -l /tmp/backup.dump | grep -c TABLE'
Comment on lines +44 to +47

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Data Integrity & Integration · Heavy lift

Supported by static analysis

Script executed:

rg -n 'pg_restore|pg_dump|postgresql.*version|postgresql:' docs charts deploy helm 2>/dev/null | head -160

Repository: Flagsmith/flagsmith

Length of output: 2290


Script executed:

nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
rg -n -i -e 'postgres(ql)?[: /-]+(1[0-9]|version)' -e 'postgresql.image' -e 'pg_restore' -- docs docker-compose* .github 2>/dev/null

Repository: Flagsmith/flagsmith

Length of output: 21264


Web query:

PostgreSQL official documentation pg_restore --list table of contents archive data corruption restore verify backup

Result:

Sources consulted:
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/18/app-pgrestore.html
- PostgreSQL: Documentation: 18: pg_verifybackup — https://www.postgresql.org/docs/current/app-pgverifybackup.html
- PostgreSQL: Documentation: 18: Chapter 25. Backup and Restore — https://www.postgresql.org/docs/current/backup.html
- …and 16 more

Web query:

site:postgresql.org/docs/15/app-pgrestore.html pg_restore -l list table of contents archive restore

Result:

Sources consulted:
- PostgreSQL: Documentation: 15: pg_restore — https://www.postgresql.org/docs/15/app-pgrestore.html
- PostgreSQL 15.17 Documentation — https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf
- PostgreSQL 17.9 Documentation — https://www.postgresql.org/files/documentation/pdf/17/postgresql-17-A4.pdf
- PostgreSQL: Documentation: 17: pg_restore — https://www.postgresql.org/docs/17/app-pgrestore.html
- PostgreSQL: Documentation: 11: pg_restore — https://www.postgresql.org/docs/11/app-pgrestore.html
- …and 12 more

Verify the restore before deleting the database.

pg_restore -l lists archive entries but does not verify table data. A corrupt backup can pass this check, then fail after dropdb deletes the current database. Restore the backup into a separate database and verify its contents before deleting the current database.

```

Copy the backup out of the cluster:

```bash
kubectl cp flagsmith/flagsmith-dev-postgresql-0:/tmp/backup.dump ./backup.dump
```

## Upgrade with Helm

```bash
helm upgrade -n flagsmith flagsmith flagsmith/flagsmith --version <chart-version> -f values.yaml --wait --timeout 20m

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Functional Correctness · Quick win

Supported by static analysis

Script executed:

rg -n 'helm install|values.yaml' docs/docs/deployment-self-hosting | head -100

Repository: Flagsmith/flagsmith

Length of output: 4511


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
printf '\n--- upgrade page ---\n'
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,210p'
printf '\n--- installation instructions ---\n'
nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '1,62p'

Repository: Flagsmith/flagsmith

Length of output: 22450


Web query:

Helm upgrade --values missing file error open no such file official documentation source

Result:

Sources consulted:
- helm upgrade | Helm — https://helm.sh/docs/helm/helm_upgrade/
- os package - os - Go Packages — https://pkg.go.dev/os?GOOS=linux
- helm upgrade | Helm — https://docs.helm.sh/docs/helm/helm_upgrade/
- Relative filesystem schema references in `values.schema.json` broken · Issue #10481 · helm/helm · GitHub — GitHub issue 10481 in helm/helm (link omitted to avoid creating a cross-reference)
- Chart Development Tips and Tricks | Helm — https://helm.sh/docs/v2/developing_charts/charts_tips_and_tricks/
- …and 8 more

Remove the mandatory values file from the default upgrade command.

The basic installation uses chart defaults and creates no values.yaml. The documented command therefore fails for that installation unless the operator creates a file. Use --reuse-values, and document -f values.yaml only for installations that have a values file.

Suggested fix

--- "a/docs/docs/deployment-self-hosting/upgrading.md"
+++ "b/docs/docs/deployment-self-hosting/upgrading.md"
@@ -56,7 +56,7 @@
 ## Upgrade with Helm
 
 ```bash
-helm upgrade -n flagsmith flagsmith flagsmith/flagsmith --version <chart-version> -f values.yaml --wait --timeout 20m
+helm upgrade -n flagsmith flagsmith flagsmith/flagsmith --version <chart-version> --reuse-values --wait --timeout 20m
 ```
 
 Pass the same values file you installed with. Without `-f` or `--reuse-values`, Helm applies the chart defaults and
Committable suggestion

IMPORTANT
Review the replacement and indentation, then test before committing.

Suggested change
helm upgrade -n flagsmith flagsmith flagsmith/flagsmith --version <chart-version> -f values.yaml --wait --timeout 20m
helm upgrade -n flagsmith flagsmith flagsmith/flagsmith --version <chart-version> --reuse-values --wait --timeout 20m

Major · Functional Correctness · Quick win

Supported by static analysis

Script executed:

rg -n 'migrate-db|strategy:|maxSurge|maxUnavailable|code_references.0003|featureflagcodereferencesscan' . | head -180

Repository: Flagsmith/flagsmith

Length of output: 4299


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
printf '\n--- chart and migration paths ---\n'
rg --files | rg '(^|/)(charts?|helm)/|code_references/migrations/|code_references/(models|views|serializers|urls)'
printf '\n--- chart references ---\n'
rg -n -F -e 'flagsmith/flagsmith' -e 'flagsmith-charts' -e 'charts.flagsmith.com' -- docs/docs/deployment-self-hosting .github 2>/dev/null || test "$?" -eq 1
printf '\n--- migration ---\n'
nl -ba api/projects/code_references/migrations/0003_introduce_per_feature_scanned_references.py

Repository: Flagsmith/flagsmith

Length of output: 39833


Script executed:

printf '%s\n' '--- historical application tags ---'
git tag -l '*2.222.0*'
git show-ref --tags | grep -F '2.222.0' || test "$?" -eq 1
printf '%s\n' '--- chart index excerpt ---'
curl -fsSL --max-time 20 https://flagsmith.github.io/flagsmith-charts/index.yaml | grep -A 18 -B 8 'version: 0.85.0'
printf '%s\n' '--- chart repository tags ---'
git ls-remote --tags https://github.com/Flagsmith/flagsmith-charts.git '*0.85.0*' '*0.80.0*'
printf '%s\n' '--- legacy references in history ---'
git log --all --oneline -- api/projects/code_references/migrations/0003_introduce_per_feature_scanned_references.py | sed -n '1,25p'

Repository: Flagsmith/flagsmith

Length of output: 1529


Web query:

Kubernetes Deployment rolling update default maxUnavailable maxSurge pod readiness service endpoints init containers

Result:

Sources consulted:
- Init Containers | Kubernetes — https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
- Deployments | Kubernetes — https://kubernetes.io/docs/concepts/workloads/controllers/deployment/?source=post_page-----8431c984108c--------------------------------
- Pod Conditions | Kubernetes — https://kubernetes.io/docs/concepts/workloads/pods/pod-condition/
- Update a Deployment Without Downtime | Kubernetes — https://kubernetes.io/docs/tasks/run-application/update-deployment-rolling/
- Deployments | Kubernetes — https://kubernetes.io/docs/concepts/workloads/controllers/deployment/?source=post_page-----129a75b79d58--------------------------------
- …and 7 more

Script executed:

set -eu
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
curl -fsSL https://github.com/Flagsmith/flagsmith-charts/releases/download/flagsmith-0.85.0/flagsmith-0.85.0.tgz -o "$tmp/chart.tgz"
tar -xzf "$tmp/chart.tgz" -C "$tmp"
printf '%s\n' '--- chart files ---'
find "$tmp" -type f | sort
printf '%s\n' '--- deployment strategy, probes, init/job ---'
rg -n -C 5 -F -e 'strategy:' -e 'maxUnavailable' -e 'maxSurge' -e 'readinessProbe' -e 'migrate-db' -e 'migrateDb' "$tmp"
printf '%s\n' '--- chart deployment templates ---'
find "$tmp" -type f \( -name '*deployment*' -o -name '*values*' -o -name '*_helpers*' \) -print
printf '%s\n' '--- legacy application refs ---'
git remote -v
git ls-remote --tags https://github.com/Flagsmith/flagsmith.git 'v2.222.0' '2.222.0' '*2.222.0*'
printf '%s\n' '--- current code-reference consumers ---'
rg -n -C 4 -F 'FeatureFlagCodeReferencesScan' api frontend
printf '%s\n' '--- current features-list code ---'
rg -n -C 5 -e 'features.*list|FeatureViewSet|FeatureFlag' api/projects api/organisations | head -240

Repository: Flagsmith/flagsmith

Length of output: 40371


Script executed:

printf '%s\n' '--- exact refs from prior output ---'
rg -n -A 12 -B 3 -F -e '--- legacy application refs ---' -e 'deployment-api.yaml' -e '--- chart deployment templates ---' /tmp/coderabbit-shell-logs/shell-output-s1MI6T
printf '%s\n' '--- chart source at 0.85.0 ---'
for path in charts/flagsmith/templates/deployment-api.yaml charts/flagsmith/templates/service-api.yaml charts/flagsmith/values.yaml; do
  echo "=== flagsmith-charts/flagsmith-0.85.0/$path ==="
  case "$path" in
    *deployment-api.yaml) curl -fsSL "https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/flagsmith-0.85.0/$path" | nl -ba | sed -n '1,230p' ;;
    *service-api.yaml) curl -fsSL "https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/flagsmith-0.85.0/$path" | nl -ba | sed -n '1,130p' ;;
    *values.yaml) curl -fsSL "https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/flagsmith-0.85.0/$path" | nl -ba | sed -n '1,145p;785,810p' ;;
  esac
done
printf '%s\n' '--- tag raw API source probes ---'
for ref in v2.222.0 2.222.0; do
 echo "=== $ref ==="
 curl -sS -o /dev/null -w '%{http_code}\n' "https://raw.githubusercontent.com/Flagsmith/flagsmith/$ref/api/features/views.py"
done

Repository: Flagsmith/flagsmith

Length of output: 27169


Script executed:

set -eu
base=https://raw.githubusercontent.com/Flagsmith/flagsmith/v2.222.0
for path in api/features/views.py api/features/serializers.py api/projects/code_references/models.py api/projects/code_references/views.py api/projects/code_references/serializers.py api/projects/code_references/urls.py api/projects/urls.py; do
  echo "=== $path ==="
  curl -fsSL "$base/$path" | nl -ba | sed -n '1,280p'
done
printf '%s\n' '--- historical references ---'
git fetch --no-tags --depth=1 origin refs/tags/v2.222.0:refs/tags/v2.222.0
git grep -n -F 'FeatureFlagCodeReferencesScan' v2.222.0 -- api | sed -n '1,160p'

Repository: Flagsmith/flagsmith

Length of output: 16862


Script executed:

set -eu
log=/tmp/coderabbit-shell-logs/shell-output-ZXUewH
printf '%s\n' '--- historical views and serializer relevant lines ---'
rg -n -C 8 -i -e 'code_references' -e 'class FeatureViewSet' -e 'def get_queryset' -e 'def list\(' "$log"
printf '%s\n' '--- chart defaults init-container ---'
curl -fsSL --max-time 20 https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/flagsmith-0.85.0/charts/flagsmith/values.yaml | nl -ba | grep -C 8 -F 'enableMigrateDbInitContainer'
printf '%s\n' '--- old app services ---'
curl -fsSL --max-time 20 https://raw.githubusercontent.com/Flagsmith/flagsmith/v2.222.0/api/projects/code_references/services.py | nl -ba | sed -n '1,240p'
printf '%s\n' '--- health paths present in repository ---'
rg -n -F -e 'health/readiness/' -e 'Readiness' -e 'readiness' -- api/health* api/app api/core 2>/dev/null || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 20143


Quiesce the old API before applying incompatible migrations.

The default chart uses a rolling update, so an old ready API pod can serve requests while the new pod runs migrate. In Flagsmith 2.222.0, the features list queries FeatureFlagCodeReferencesScan, which migration 0003 deletes. Document a Recreate strategy or another quiescing procedure before this upgrade.

```

Pass the same values file you installed with. Without `-f` or `--reuse-values`, Helm applies the chart defaults and
discards values you set earlier. The test used default values only, so this behaviour was not tested here.
Comment on lines +59 to +63

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Functional Correctness · Quick win

Supported by static analysis

Script executed:

rg -n 'helm (install|upgrade)|--reuse-values|--set|values.yaml' docs | head -180

Repository: Flagsmith/flagsmith

Length of output: 5415


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,197p'
nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '1,145p;235,295p'
nl -ba docs/docs/deployment-self-hosting/hosting-guides/cloud-providers/google-cloud.md | sed -n '25,100p'
rg -n -F -e 'helm version' -e 'Helm 3' -e 'helm 3' -e 'helm.sh/helm' -- docs .github charts 2>/dev/null || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 30662


Web query:

Helm 3 helm upgrade --reuse-values -f new values reset previous release values official documentation

Result:

Sources consulted:
- Helm | Helm Upgrade — https://v3-1-0.helm.sh/docs/helm/helm_upgrade/
- helm/pkg/action/upgrade.go at main · helm/helm · GitHub — https://github.com/helm/helm/blob/main/pkg/action/upgrade.go
- helm upgrade | Helm — https://helm.sh/docs/v2/helm/helm_upgrade/
- helm upgrade | Helm — https://docs.helm.sh/docs/helm/helm_upgrade/
- helm upgrade | Helm — https://helm.sh/docs/helm/helm_upgrade/?trk=article-ssr-frontend-pulse_little-text-block
- …and 7 more

Script executed:

printf '%s\n' '--- Helm 3.17.3 upgrade value merging ---'
curl -fsSL --max-time 20 https://raw.githubusercontent.com/helm/helm/v3.17.3/pkg/action/upgrade.go | nl -ba | sed -n '/func (u \*Upgrade) reuseValues/,/^}/p'
printf '%s\n' '--- Chart tag references ---'
curl -fsSL --max-time 20 'https://api.github.com/repos/Flagsmith/flagsmith-charts/git/matching-refs/tags/flagsmith-0.85.0' 
printf '\n%s\n' '--- Chart 0.85.0 values and templates ---'
for p in values.yaml templates/task-processor/deployment.yaml templates/task-processor-deployment.yaml values.schema.json; do
  printf '\n--- %s ---\n' "$p"
  curl -fsSL --max-time 20 "https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/flagsmith-0.85.0/charts/flagsmith/$p" | nl -ba | grep -n -C 8 -E 'taskProcessor:|enabled:|taskProcessor.enabled|task-processor|taskProcessor' | sed -n '1,180p'
done

Repository: Flagsmith/flagsmith

Length of output: 12459


Web query:

site:helm.sh/docs/v3 helm upgrade without reuse values provided values file existing customized values ignored

Result:

Sources consulted:
- helm upgrade | Helm — https://helm.sh/docs/v3/helm/helm_upgrade/
- helm upgrade | Helm — https://helm.sh/docs/v2/helm/helm_upgrade/
- helm upgrade | Helm — https://docs.helm.sh/docs/v3/helm/helm_upgrade/
- helm upgrade | Helm — https://helm.sh/docs/helm/helm_upgrade/
- Helm | Helm Upgrade — https://v3-1-0.helm.sh/docs/helm/helm_upgrade/
- …and 7 more

Preserve all Helm value overrides during upgrades.

If the installation used additional -f files or --set, the documented command supplies only values.yaml. Helm then omits the other release overrides. Use every values file and command-line override again, or add --reuse-values, so settings such as databaseExternal and taskProcessor.enabled are not replaced by chart defaults.


`--wait` prints nothing until every pod is ready. Downloading images can take several minutes on a slow connection. In

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Functional Correctness · Quick win

Supported by static analysis

Script executed:

rg -n 'helm version|helm-version|helmVersion|maxUnavailable|replicaCount' . | head -120

Repository: Flagsmith/flagsmith

Length of output: 743


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
rg -n -i -e 'helm version' -e 'helm-version' -e 'helmfile' -e 'helm/flagsmith' -e 'flagsmith/flagsmith' -- .github docs/deployment docs/docs/deployment-self-hosting 2>/dev/null || test "$?" -eq 1
rg --files | rg '(^|/)(Chart\.yaml|values\.yaml|helm.*\.ya?ml)$'

Repository: Flagsmith/flagsmith

Length of output: 32361


Web query:

Helm v3 --wait deployment minimum ready replicas maxUnavailable readiness ready checker official docs source

Result:

Sources consulted:
- helm/pkg/kube/ready.go at dev-v3 · helm/helm · GitHub — https://github.com/helm/helm/blob/dev-v3/pkg/kube/ready.go
- Using Helm | Helm — https://docs.helm.sh/docs/intro/using_helm/
- helm/pkg/kube/ready_test.go at dev-v3 · helm/helm · GitHub — https://github.com/helm/helm/blob/dev-v3/pkg/kube/ready_test.go
- …and 20 more

Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
rg -n -i -e 'helm version' -e 'helm-version' -e 'helmfile' -e 'helm/flagsmith' -e 'flagsmith/flagsmith' -- .github docs/docs/deployment-self-hosting || test "$?" -eq 1
rg --files | rg '(^|/)(Chart\.yaml|values\.yaml|helm.*\.ya?ml)$' || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 32361


Document Helm’s minimum readiness threshold.

Helm --wait does not guarantee that every replica is ready. It accepts a Deployment when the minimum number of ready replicas is available, based on Desired - maxUnavailable. State this limitation so operators do not treat a partially ready rollout as fully healthy.

Suggested documentation fix

--- "a/docs/docs/deployment-self-hosting/upgrading.md"
+++ "b/docs/docs/deployment-self-hosting/upgrading.md"
@@ -62,7 +62,9 @@
 Pass the same values file you installed with. Without `-f` or `--reuse-values`, Helm applies the chart defaults and
 discards values you set earlier. The test used default values only, so this behaviour was not tested here.
 
-`--wait` prints nothing until every pod is ready. Downloading images can take several minutes on a slow connection. In
+`--wait` prints nothing until Helm's readiness checks succeed. For Deployments, Helm waits for the minimum number of
+ready replicas (`Desired - maxUnavailable`), not necessarily every replica. Check all replicas separately after the
+upgrade. Downloading images can take several minutes on a slow connection. In
 the test, a first install with a 10 minute timeout failed because the PostgreSQL image took more than five minutes to
 download, even though the pods were healthy shortly afterwards.
 
Committable suggestion

IMPORTANT
Review the replacement and indentation, then test before committing.

Suggested change
`--wait` prints nothing until every pod is ready. Downloading images can take several minutes on a slow connection. In
`--wait` prints nothing until Helm's readiness checks succeed. For Deployments, Helm waits for the minimum number of
ready replicas (`Desired - maxUnavailable`), not necessarily every replica. Check all replicas separately after the
upgrade. Downloading images can take several minutes on a slow connection. In

the test, a first install with a 10 minute timeout failed because the PostgreSQL image took more than five minutes to
download, even though the pods were healthy shortly afterwards.

## How migrations run

With the chart's default values, there is no migration Job. Database migrations run in an init container named
`migrate-db` in the API pod, and the API starts only after it finishes. To read its output, find the new API pod and
request the init container's logs:

```bash
kubectl -n flagsmith get pods
kubectl -n flagsmith logs <api-pod> -c migrate-db
```

A successful run lists each migration it applied. For example:

```text
Running migrations:
Applying code_references.0003_introduce_per_feature_scanned_references... OK
```

If the database is already up to date, the log says `No migrations to apply.`

The chart also has a `jobs.migrateDb` option that runs migrations as a Job. This page did not test it, so check the
chart values for your version.

:::warning

Init container logs exist only as long as the pod does. Once the API pod is replaced, the migration logs are gone. Read
them straight after the upgrade, or send pod logs to a log system.

:::

## Verify the upgrade

- `helm history -n flagsmith flagsmith` shows the new revision with the status `deployed`.
- `kubectl -n flagsmith get pods` shows the API pod as `Running` and ready.
- The dashboard shows the new version at the bottom of the left sidebar, and your projects and flags are still there.

## Rolling back

:::warning

`helm rollback` restores the previous chart revision, so the older application runs again. It does **not** undo database
migrations. If the upgrade changed the schema, the older application runs against a newer database and can fail.

:::

In the test, migration `code_references.0003` dropped the table `code_references_featureflagcodereferencesscan`. After
`helm rollback`, Flagsmith 2.222.0 failed on the features list with this error in the API log:

```text
django.db.utils.ProgrammingError: relation "code_references_featureflagcodereferencesscan" does not exist
```

Treat a rollback as a restore. These steps worked in the test:

1. Roll back the chart:

```bash
helm rollback flagsmith <revision> -n flagsmith --wait --timeout 20m
```

2. Stop the API, so nothing is connected to the database, and wait until no `flagsmith-api` pod is listed:

```bash
kubectl -n flagsmith scale deployment flagsmith-api --replicas=0
Comment on lines +129 to +132

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Data Integrity & Integration · Quick win

Supported by static analysis

Script executed:

rg -n 'taskProcessor|DATABASE_URL|DATABASE_HOST|migrateDb|postgresql' charts deploy helm 2>/dev/null | head -180

Repository: Flagsmith/flagsmith

Length of output: 157


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,220p'
printf '\nDeployment files:\n'
rg --files | rg -i '(helm|chart|kubernetes|docker.compose|self.host|celery|task.processor|postgres)' | sed -n '1,180p'
printf '\nWorkload references:\n'
rg -n -i -e 'task processor' -e 'task_processor' -e 'taskProcessor' -e 'migrateDb' -e 'helm.flagsmith.com' docs api docker-compose* 2>/dev/null | sed -n '1,200p'

Repository: Flagsmith/flagsmith

Length of output: 40379


Web query:

PostgreSQL official documentation pg_restore default continue after error exit-on-error archive restore existing database

Result:

Sources consulted:
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/current/app-pgrestore.html
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/18/app-pgrestore.html
- PostgreSQL: Documentation: 11: pg_restore — https://www.postgresql.org/docs/11/app-pgrestore.html
- PostgreSQL 15.17 Documentation — https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf
- PostgreSQL: Documentation: 10: pg_restore — https://www.postgresql.org/docs/10/app-pgrestore.html
- …and 13 more

Web query:

PostgreSQL official documentation DROP DATABASE fails other sessions connected force connections

Result:

Sources consulted:
- PostgreSQL: Documentation: 18: DROP DATABASE — https://www.postgresql.org/docs/current/sql-dropdatabase.html
- PostgreSQL 18.1 Documentation — https://www.postgresql.org/files/documentation/pdf/18/postgresql-18-US.pdf
- PostgreSQL: Documentation: 10: DROP DATABASE — https://www.postgresql.org/docs/10/sql-dropdatabase.html
- DROP DATABASE — https://www.postgresql.org/files/documentation/pdf/7.3/reference-7.3.2-A4.pdf
- PostgreSQL: Documentation: 18: dropdb — https://www.postgresql.org/docs/current/app-dropdb.html
- …and 13 more

Script executed:

nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '1,115p;300,340p;385,410p;550,570p'
nl -ba docs/docs/deployment-self-hosting/scaling-and-performance/asynchronous-task-processor.md | sed -n '1,220p'
nl -ba api/app/settings/common.py | sed -n '260,350p'
rg -n -F -e 'flagsmith-charts' -e 'postgresql.image' -e 'postgresql:' -- docs/docs/deployment-self-hosting .gitmodules 2>/dev/null | sed -n '1,120p'
rg --files api | rg 'task_processor|task.processor'
nl -ba docs/README.md | sed -n '1,140p'

Repository: Flagsmith/flagsmith

Length of output: 29544


Web query:

Flagsmith flagsmith-charts chart 0.80.0 0.85.0 PostgreSQL dependency version postgresql image taskProcessor enabled values

Result:

Sources consulted:
- Release flagsmith: v0.80.0 · Flagsmith/flagsmith-charts · GitHub — https://github.com/Flagsmith/flagsmith-charts/releases/tag/flagsmith-0.80.0
- https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/fe3cdf0/charts/flagsmith/Chart.yaml
- https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/fe3cdf0/charts/flagsmith/values.yaml
- GitHub - Flagsmith/flagsmith-charts: Helm Charts for Flagsmith. Feature flagging and remote config service. Host yourself or use our hosted version. · GitHub — https://github.com/Flagsmith/flagsmith-charts
- flagsmith/docker-compose.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.yml
- …and 34 more

Web query:

PostgreSQL 15 documentation dropdb DROP DATABASE other connections pg_restore exit on error default

Result:

Sources consulted:
- PostgreSQL: Documentation: 15: pg_restore — https://www.postgresql.org/docs/15/app-pgrestore.html
- PostgreSQL: Documentation: 15: DROP DATABASE — https://www.postgresql.org/docs/15/sql-dropdatabase.html
- PostgreSQL: Documentation: 15: 23.5. Destroying a Database — https://www.postgresql.org/docs/15/manage-ag-dropdb.html
- PostgreSQL: Documentation: 15: dropdb — https://www.postgresql.org/docs/15/app-dropdb.html
- …and 10 more

Stop every PostgreSQL client before dropping the database.

Scaling flagsmith-api to zero does not stop an enabled taskProcessor or migration workload. If dropdb fails, the next commands can still run because they are separate shell commands. createdb then fails, while pg_restore can continue against the existing database and leave a partial, mixed-version restore. Stop all database workloads and abort when the drop or create command fails.

kubectl -n flagsmith get pods
```

3. Delete the database and create an empty one. This destroys the current data, so only do it once you have a backup you
have checked:

```bash
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c 'PGPASSWORD=$POSTGRES_PASSWORD dropdb -U postgres $POSTGRES_DB'
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c 'PGPASSWORD=$POSTGRES_PASSWORD createdb -U postgres $POSTGRES_DB'
```

4. Restore the backup:

```bash
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c \
'PGPASSWORD=$POSTGRES_PASSWORD pg_restore -U postgres -d $POSTGRES_DB --no-owner /tmp/backup.dump'
Comment on lines +140 to +148

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Stability & Availability · Quick win

Supported by static analysis

Script executed:

rg -n 'backup.dump|pg_restore|postgresql' docs/docs/deployment-self-hosting charts 2>/dev/null | head -140

Repository: Flagsmith/flagsmith

Length of output: 5812


Script executed:

nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,210p'
git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md

Repository: Flagsmith/flagsmith

Length of output: 19701


Web query:

PostgreSQL official documentation pg_restore filename archive input file dropdb removes database

Result:

Sources consulted:
- PostgreSQL: Documentation: 18: DROP DATABASE — https://www.postgresql.org/docs/current/sql-dropdatabase.html
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/18/app-pgrestore.html
- PostgreSQL: Documentation: 18: 22.5. Destroying a Database — https://www.postgresql.org/docs/current/manage-ag-dropdb.html
- PostgreSQL: Documentation: 17: pg_restore — https://www.postgresql.org/docs/17/app-pgrestore.html
- pg_restore ## Name pg_restore — restore a Postgre — https://www.postgresql.org/files/documentation/pdf/7.4/postgresql-7.4.2-A4.pdf
- …and 12 more

Copy the backup back into the pod before deleting the database.

If the PostgreSQL pod has been replaced, /tmp/backup.dump may no longer exist. The documented commands then delete the database before pg_restore fails. Copy ./backup.dump into the pod and verify it before running dropdb.

Comment on lines +141 to +148

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Data Integrity & Integration · Quick win

Supported by static analysis

Script executed:

rg -n 'POSTGRES_USER|POSTGRESQL_USERNAME|DATABASE_USER|database.*owner|pg_restore' docs charts deploy helm 2>/dev/null | head -150

Repository: Flagsmith/flagsmith

Length of output: 811


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,210p'
rg -n -i -e 'database_url' -e 'postgresql.*user' -e 'postgres_user' -e 'database.*user' -e 'external.*postgres' -- docs api docker-compose* 2>/dev/null | head -200
rg --files | rg -i 'helm|chart|postgres|database' | head -120

Repository: Flagsmith/flagsmith

Length of output: 37415


Web query:

PostgreSQL documentation pg_restore --no-owner ACL privileges pg_dump custom archive database owner createdb default owner

Result:

Sources consulted:
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/current/app-pgrestore.html
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/18/app-pgrestore.html
- PostgreSQL: Documentation: 18: pg_dump — https://www.postgresql.org/docs/current/app-pgdump.html
- …and 16 more

Script executed:

nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '240,275p;455,475p;575,605p'
nl -ba api/app/settings/common.py | sed -n '190,215p;270,305p'
nl -ba docker-compose.pgpool.yml | sed -n '1,55p'
rg -n -F -- 'databaseExternal.username' . --glob '!docs/docs/deployment-self-hosting/upgrading.md'
rg -n -F -- 'DATABASE_URL' charts deploy helm infrastructure .github 2>/dev/null | head -120

Repository: Flagsmith/flagsmith

Length of output: 16302


Web query:

PostgreSQL 15 pg_restore --no-owner objects owned by user restore default privileges owner tables public no privileges documentation

Result:

Sources consulted:
- PostgreSQL: Documentation: 15: pg_restore — https://www.postgresql.org/docs/15/app-pgrestore.html
- PostgreSQL: Documentation: 15: ALTER DEFAULT PRIVILEGES — https://www.postgresql.org/docs/15/sql-alterdefaultprivileges.html
- PostgreSQL: Documentation: 15: 5.7. Privileges — https://www.postgresql.org/docs/15/ddl-priv.html
- PostgreSQL: Documentation: 15: 5.9. Schemas — https://www.postgresql.org/docs/15/ddl-schemas.html
- …and 42 more

Web query:

Flagsmith flagsmith-charts chart 0.85.0 devPostgresql postgresqlUsername database username PostgreSQL image version github

Result:

Sources consulted:
- https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/main/charts/flagsmith/values.yaml
- GitHub - Flagsmith/flagsmith-charts: Helm Charts for Flagsmith. Feature flagging and remote config service. Host yourself or use our hosted version. · GitHub — https://github.com/Flagsmith/flagsmith-charts
- Flagsmith · GitHub — https://github.com/flagsmith
- flagsmith/docker-compose.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.yml
- flagsmith/docker-compose.pgpool.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.pgpool.yml
- …and 25 more

Web query:

PostgreSQL 15 createdb default owner current user createdb --owner documentation

Result:

Sources consulted:
- PostgreSQL: Documentation: 15: createdb — https://www.postgresql.org/docs/15/app-createdb.html
- PostgreSQL: Documentation: 15: CREATE DATABASE — https://www.postgresql.org/docs/15/sql-createdatabase.html
- PostgreSQL: Documentation: 15: 23.2. Creating a Database — https://www.postgresql.org/docs/15/manage-ag-createdb.html
- PostgreSQL: Documentation: 18: CREATE DATABASE — https://www.postgresql.org/docs/current/sql-createdatabase.html
- PostgreSQL 15.17 Documentation — https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf
- …and 9 more

Web query:

Flagsmith flagsmith-charts 0.85.0 devPostgresql auth username DATABASE_URL template databaseExternal github

Result:

Sources consulted:
- GitHub - Flagsmith/flagsmith-charts: Helm Charts for Flagsmith. Feature flagging and remote config service. Host yourself or use our hosted version. · GitHub — https://github.com/Flagsmith/flagsmith-charts
- flagsmith 0.2.9 · flagsmith/flagsmith — https://artifacthub.io/packages/helm/flagsmith/flagsmith/0.2.9
- flagsmith/docker-compose.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.yml
- flagsmith/docker-compose.pgpool.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.pgpool.yml
- …and 25 more

Script executed:

nl -ba docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md | sed -n '200,245p'
git status --short

Repository: Flagsmith/flagsmith

Length of output: 1978


Preserve the application role during restore.

If the API uses a non-postgres role, --no-owner makes postgres own restored tables. PostgreSQL grants no table privileges to PUBLIC by default, so an application role that relied on ownership can no longer query them. Restore original ownership or grant the application role the required privileges before restarting the API.

Comment on lines +147 to +148

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Stability & Availability · Quick win

Supported by static analysis

Script executed:

rg -n 'pg_restore|restore.*database|exit-on-error' docs charts 2>/dev/null | head -120

Repository: Flagsmith/flagsmith

Length of output: 811


Script executed:

set -o pipefail
printf '%s\n' '--- document ---'
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,197p'
printf '%s\n' '--- full comparison ---'
git diff --no-ext-diff --unified=40 5051ac24bff70bfed8a428531be4816acef822ff -- docs/docs/deployment-self-hosting/upgrading.md
printf '%s\n' '--- PostgreSQL/chart references ---'
rg -n -i --glob '!docs/docs/deployment-self-hosting/upgrading.md' 'postgres(ql)?|pg_restore|readinessProbe|livenessProbe|flagsmith-api|deployment.*api' charts docs | head -240

Repository: Flagsmith/flagsmith

Length of output: 41437


Web query:

PostgreSQL pg_restore documentation exit status errors --exit-on-error continue after errors supported versions

Result:

Sources consulted:
- postgres/src/bin/pg_dump/pg_restore.c at master · postgres/postgres · GitHub — https://github.com/postgres/postgres/blob/master/src/bin/pg_dump/pg_restore.c
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/18/app-pgrestore.html
- PostgreSQL: Documentation: 8.0: pg_restore — https://www.postgresql.org/docs/8/app-pgrestore.html
- …and 33 more

Script executed:

printf '%s\n' '--- top-level directories and chart references ---'
ls
rg -n -F -e 'flagsmith/flagsmith-charts' -e 'postgres:15' -e 'healthcheck' -e 'health_check' -e 'health-check' -e 'readiness' -- api docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md docker-compose.yml 2>/dev/null | head -200
printf '%s\n' '--- git metadata ---'
git rev-parse HEAD
git submodule status

Repository: Flagsmith/flagsmith

Length of output: 7692


Web query:

site:postgresql.org/docs/15/app-pgrestore.html pg_restore exit-on-error default continue errors single transaction

Result:

Sources consulted:
- PostgreSQL 15.17 Documentation — https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf
- PostgreSQL: Documentation: 15: pg_restore — https://www.postgresql.org/docs/15/app-pgrestore.html
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/current/app-pgrestore.html
- PostgreSQL 15.17 Documentation — https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-A4.pdf
- PostgreSQL: Documentation: 18: pg_restore — https://www.postgresql.org/docs/current/app-pgrestore.html?trk=article-ssr-frontend-pulse_little-text-block
- …and 12 more

Web query:

Flagsmith helm chart 0.80.0 postgresql version devPostgresql image readiness probe api migrate-db health

Result:

Sources consulted:
- GitHub - Flagsmith/flagsmith-charts: Helm Charts for Flagsmith. Feature flagging and remote config service. Host yourself or use our hosted version. · GitHub — https://github.com/Flagsmith/flagsmith-charts
- flagsmith/docker-compose.yml at main · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.yml
- Releases · Flagsmith/flagsmith · GitHub — https://github.com/Flagsmith/flagsmith/releases
- GitHub - Flagsmith/flagsmith-common: Flagsmith's common library · GitHub — https://github.com/Flagsmith/flagsmith-common
- flagsmith 0.1.8 · flagsmith/flagsmith — https://artifacthub.io/packages/helm/flagsmith/flagsmith/0.1.8
- …and 30 more

Script executed:

printf '%s\n' '--- API health and readiness implementation ---'
rg -n -F -e 'health/readiness' -e 'health/liveness' -e 'healthcheck' -e 'HealthCheck' -e 'check_db' -e 'migrations' api/app api/flagsmith 2>/dev/null | head -240
printf '%s\n' '--- health-related complete files ---'
find api -type f \( -iname '*health*' -o -iname '*readiness*' \) -print

Repository: Flagsmith/flagsmith

Length of output: 638


Script executed:

printf '%s\n' '--- relevant settings ---'
nl -ba api/app/settings/common.py | sed -n '120,165p'
printf '%s\n' '--- API URL registration ---'
rg -n -i 'health|ready|live' api/app/urls.py api/app api/scripts docker --glob '*.py' --glob '*.sh' | head -120
printf '%s\n' '--- upstream chart tags ---'
git ls-remote --tags https://github.com/Flagsmith/flagsmith-charts.git '*0.80.0*' '*0.85.0*'

Repository: Flagsmith/flagsmith

Length of output: 3381


Web query:

github Flagsmith flagsmith-charts 0.80.0 charts flagsmith api deployment readinessProbe httpGet health PostgreSQL image tag

Result:

Sources consulted:
- GitHub - Flagsmith/flagsmith-charts: Helm Charts for Flagsmith. Feature flagging and remote config service. Host yourself or use our hosted version. · GitHub — https://github.com/Flagsmith/flagsmith-charts
- flagsmith 0.2.4 · flagsmith/flagsmith — https://artifacthub.io/packages/helm/flagsmith/flagsmith/0.2.4
- flagsmith 0.1.8 · flagsmith/flagsmith — https://artifacthub.io/packages/helm/flagsmith/flagsmith/0.1.8
- …and 41 more

Stop before restarting the API when the restore fails.

pg_restore continues after errors by default. It can leave an incomplete database before returning a failure. Add --single-transaction and instruct operators to inspect the exit status before scaling flagsmith-api up.

Suggested fix

-     'PGPASSWORD=$POSTGRES_PASSWORD pg_restore -U postgres -d $POSTGRES_DB --no-owner /tmp/backup.dump'
+     'PGPASSWORD=$POSTGRES_PASSWORD pg_restore -U postgres -d $POSTGRES_DB --no-owner --single-transaction /tmp/backup.dump'

Add a step that tells operators to investigate the output and repeat the restore if this command fails.

Committable suggestion

IMPORTANT
Review the replacement and indentation, then test before committing.

Suggested change
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c \
'PGPASSWORD=$POSTGRES_PASSWORD pg_restore -U postgres -d $POSTGRES_DB --no-owner /tmp/backup.dump'
kubectl -n flagsmith exec flagsmith-dev-postgresql-0 -- sh -c \
'PGPASSWORD=$POSTGRES_PASSWORD pg_restore -U postgres -d $POSTGRES_DB --no-owner --single-transaction /tmp/backup.dump'

```

5. Start the API and wait for it to become ready:

```bash
kubectl -n flagsmith scale deployment flagsmith-api --replicas=1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Stability & Availability · Quick win

Supported by static analysis

Script executed:

rg -n 'replicaCount|replicas:|autoscaling|HorizontalPodAutoscaler' charts deploy helm docs 2>/dev/null | head -150

Repository: Flagsmith/flagsmith

Length of output: 1035


Script executed:

set -o pipefail
printf '%s\n' '--- document ---'
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,197p'
printf '%s\n' '--- chart files ---'
rg --files charts deploy helm 2>/dev/null | head -200
printf '%s\n' '--- replica/autoscaling references ---'
rg -n -i -F --glob '!**/node_modules/**' -e 'replicaCount' -e 'replicas:' -e 'autoscaling' -e 'HorizontalPodAutoscaler' -e 'flagsmith-api' charts deploy helm 2>/dev/null || test "$?" -eq 1
printf '%s\n' '--- api chart references ---'
rg -n -i -F --glob '!**/node_modules/**' -e 'api:' -e 'api.replica' -e 'deployment' charts deploy helm 2>/dev/null | head -250 || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 10506


Script executed:

printf '%s\n' '--- top-level ---'
find . -maxdepth 2 -type d -print | sort | head -200
printf '%s\n' '--- tracked chart/deployment files ---'
git ls-tree -r --name-only HEAD | grep -Ei '(^|/)(chart|charts|helm|deploy|kubernetes|k8s|values|statefulset|deployment|argo|flux)' | head -300 || true
printf '%s\n' '--- all replica references ---'
rg -n -i -F --hidden --glob '!.git/**' --glob '!**/node_modules/**' -e 'replicaCount' -e 'replicas:' -e 'autoscaling' -e 'HorizontalPodAutoscaler' -e 'flagsmith-api' -e 'helm.sh' . | head -400 || true
printf '%s\n' '--- chart/version references ---'
rg -n -i -F --hidden --glob '!.git/**' --glob '!**/node_modules/**' -e 'flagsmith/flagsmith' -e 'chart 0.85' -e 'flagsmith-api' -e 'api.replica' -e 'replicaCount' . | head -400 || true

Repository: Flagsmith/flagsmith

Length of output: 41265


Script executed:

printf '%s\n' '--- API replica documentation ---'
rg -n -i -C 8 -F -e 'api.replicacount' -e 'api:' -e 'replicacount' docs/docs/deployment-self-hosting/hosting-guides/kubernetes-openshift.md docs/docs/deployment-self-hosting/scaling-and-performance/sizing-and-scaling.md
printf '%s\n' '--- source chart publication references ---'
rg -n -i -C 6 -F -e 'flagsmith-charts' -e 'helm chart' .github docs | head -250 || true

Repository: Flagsmith/flagsmith

Length of output: 41085


Web query:

Official Flagsmith flagsmith-charts Helm chart API replicaCount autoscaling configuration

Result:

Sources consulted:
- https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/main/charts/flagsmith/values.yaml
- https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/main/charts/flagsmith/templates/hpa-api.yaml
- Flagsmith Helm Charts | flagsmith-charts — https://flagsmith.github.io/flagsmith-charts/
- flagsmith 0.2.4 · flagsmith/flagsmith — https://artifacthub.io/packages/helm/flagsmith/flagsmith/0.2.4
- Flagsmith Docs — https://docs.flagsmith.com/
- …and 23 more

Restore the previous API replica count.

When api.replicacount is greater than one, this command leaves the deployment at one replica after the restore. The chart does not enable the API HPA by default. Record the current count before scaling down, then use it when starting the API.

Suggested fix

    ```bash
+   kubectl -n flagsmith get deployment flagsmith-api -o jsonpath='{.spec.replicas}' > /tmp/flagsmith-api-replicas
    kubectl -n flagsmith scale deployment flagsmith-api --replicas=0
    kubectl -n flagsmith get pods
    ```
...
-   kubectl -n flagsmith scale deployment flagsmith-api --replicas=1
+   kubectl -n flagsmith scale deployment flagsmith-api --replicas="$(cat /tmp/flagsmith-api-replicas)"
    kubectl -n flagsmith rollout status deployment flagsmith-api

kubectl -n flagsmith rollout status deployment flagsmith-api
```

Recreate the database rather than restoring over the existing one. Tables created by the newer version would otherwise
be left behind, and a later upgrade could fail when it tries to create them again.

:::warning

A restore returns the database to the moment of the backup. Anything saved since then is lost. In the test, a flag
created after the backup was gone after the restore.

:::

## Troubleshooting

| Symptom | Likely cause | What to do |
| ---------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Dashboard says you do not have permission after a rollback | The older application cannot read the newer schema | Check the API log for `ProgrammingError`. Restore the backup as described in **Rolling back**. |
| `helm install` or `helm upgrade` times out | Images are still downloading, or migrations are still running | Check `kubectl get pods` and `kubectl get events`. Retry with a longer `--timeout`. |
| No migration Job exists to read logs from | Migrations run in the `migrate-db` init container by default | Run `kubectl logs <api-pod> -c migrate-db` straight after the upgrade. |
| `kubectl logs <api-pod> -c migrate-db` returns `NotFound` | The API pod was replaced and its logs were removed | Upgrade again on a test copy and capture the logs immediately, or use a log system. |

The permissions message in the first row is misleading. The dashboard shows it whenever a request fails, and in the test
the real cause was the missing table above.

## Changes in chart 0.85.0

Chart 0.85.0 no longer deploys the bundled InfluxDB. The notes printed by `helm upgrade` list the alternatives:
configure an external InfluxDB with `influxdbExternal`, or store analytics in PostgreSQL with `UsePostgresForAnalytics`
(which requires `taskProcessor.enabled`). To move existing analytics data to PostgreSQL, enable
`jobs.migrateAnalyticsData`.
Comment on lines +182 to +185

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major · Data Integrity & Integration · Quick win

Supported by static analysis

Script executed:

rg -n 'migrateAnalyticsData|influxdbExternal|UsePostgresForAnalytics|influxdb' charts deploy helm docs 2>/dev/null | head -220

Repository: Flagsmith/flagsmith

Length of output: 13084


Script executed:

git diff 5051ac24bff70bfed8a428531be4816acef822ff a96256c2837e9069c4ba868965909c4d3515c74f -- docs/docs/deployment-self-hosting/upgrading.md
printf '\n--- guide ---\n'
nl -ba docs/docs/deployment-self-hosting/upgrading.md | sed -n '1,210p'
printf '\n--- roots and chart refs ---\n'
ls -a
rg -n -i -F -e 'migrateAnalyticsData' -e 'UsePostgresForAnalytics' -e 'flagsmith-charts' -e 'influxdbExternal' --glob '!docs/docs/deployment-self-hosting/upgrading.md' . || test "$?" -eq 1

Repository: Flagsmith/flagsmith

Length of output: 26419


Script executed:

printf '%s\n' '--- analytics references ---'
rg -n -i -e 'migrate.*analytics|analytics.*migrat|use_postgres_for_analytics|usepostgresforanalytics' api docs --glob '*.py' --glob '*.md' || test "$?" -eq 1
printf '%s\n' '--- chart releases and tags ---'
curl -fsSL --max-time 20 'https://api.github.com/repos/Flagsmith/flagsmith-charts/git/matching-refs/tags/' | python3 -c 'import json,sys; a=json.load(sys.stdin); print("\n".join(str(x) for x in a if "0.85.0" in x["ref"] or "0.80.0" in x["ref"]))'

Repository: Flagsmith/flagsmith

Length of output: 9386


Web query:

Helm chart hooks pre-upgrade post-upgrade hook sequence resources update official documentation

Result:

Sources consulted:
- Chart Hooks | Helm — https://helm.sh/docs/topics/charts_hooks/
- Chart Hooks | Helm — https://docs.helm.sh/docs/topics/charts_hooks/
- Hooks | Helm — https://docs.helm.sh/el/docs/v2/developing_charts/charts_hooks/
- Helm | — https://v2.helm.sh/docs/developing_charts/
- Chart Hooks | Helm — https://helm.sh/el/docs/topics/charts_hooks/
- …and 7 more

Script executed:

python3 - <<'PY'
import json, urllib.request
commit='a99c231d61dd89e1bc1924a4429619447b5e764f'
base='https://api.github.com/repos/Flagsmith/flagsmith-charts/git/trees/'+commit+'?recursive=1'
with urllib.request.urlopen(base, timeout=25) as f: tree=json.load(f)['tree']
for x in tree:
 p=x['path']
 if p.startswith('charts/flagsmith/') and ('migrat' in p.lower() or p.endswith(('Chart.yaml','values.yaml','NOTES.txt','_helpers.tpl'))):
  print(p)
PY
printf '\n--- migration implementation ---\n'
nl -ba api/app_analytics/management/commands/migrate_analytics.py
nl -ba api/app_analytics/migrate_to_pg.py
printf '\n--- analytics read branches ---\n'
nl -ba api/app_analytics/analytics_db_service.py | sed -n '1,115p;185,245p;265,325p'

Repository: Flagsmith/flagsmith

Length of output: 12253


Script executed:

python3 - <<'PY'
import json, urllib.request
for label, commit in [('0.85.0','a99c231d61dd89e1bc1924a4429619447b5e764f'), ('0.80.0','fe3cdf0237a96a02a81f26b82742ffa05fb20b66')]:
    print(f'--- {label} ---')
    for path in [
        'charts/flagsmith/values.yaml',
        'charts/flagsmith/templates/jobs-migrate-analytics-data.yaml',
        'charts/flagsmith/templates/jobs-migrate-db.yaml',
        'charts/flagsmith/templates/NOTES.txt',
        'charts/flagsmith/Chart.yaml',
    ]:
        url=f'https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/{commit}/{path}'
        try:
            text=urllib.request.urlopen(url, timeout=20).read().decode()
        except Exception as e:
            print(f'### {path}: {e}')
            continue
        print(f'### {path}')
        if path.endswith('values.yaml'):
            lines=text.splitlines()
            for i,line in enumerate(lines):
                if any(k.lower() in line.lower() for k in ('influx','migrateanalytics','taskprocessor','postgresforanalytics')):
                    for x in lines[max(0,i-3):min(len(lines),i+8)]:
                        print(x)
        else:
            print(text)
PY

Repository: Flagsmith/flagsmith

Length of output: 21303


Script executed:

python3 - <<'PY'
import urllib.request
for label, commit in [('0.85.0','a99c231d61dd89e1bc1924a4429619447b5e764f'), ('0.80.0','fe3cdf0237a96a02a81f26b82742ffa05fb20b66')]:
    for path in ['charts/flagsmith/templates/_api_environment.yaml','charts/flagsmith/templates/jobs-migrate-analytics-data.yaml','charts/flagsmith/Chart.yaml','charts/flagsmith/values.yaml']:
        url=f'https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/{commit}/{path}'
        print(f'\n### {label} {url}')
        try: lines=urllib.request.urlopen(url, timeout=20).read().decode().splitlines()
        except Exception as e:
            print(e); continue
        if path.endswith('values.yaml'):
            indices=set()
            for i,l in enumerate(lines):
                if any(k.lower() in l.lower() for k in ('influxdb2:', 'influxdbExternal:', 'UsePostgresForAnalytics:', 'migrateAnalyticsData:')):
                    indices.update(range(max(0,i-1),min(len(lines),i+14)))
        elif path.endswith('_api_environment.yaml'):
            indices=set()
            for i,l in enumerate(lines):
                if any(k.lower() in l.lower() for k in ('influx', 'postgresforanalytics')):
                    indices.update(range(max(0,i-4),min(len(lines),i+8)))
        else: indices=set(range(len(lines)))
        for i in sorted(indices): print(f'{i+1:4} {lines[i]}')
PY
printf '\n--- application version tags ---\n'
git tag -l '*2.286.0*'
printf '\n--- InfluxDB client and settings ---\n'
rg -n -F -e 'get_client' -e 'INFLUXDB_URL' -e 'INFLUXDB_TOKEN' -e 'INFLUXDB_ORG' -e 'INFLUXDB_BUCKET' -- api/app_analytics/influxdb_wrapper.py api/app/settings/common.py
nl -ba api/app_analytics/influxdb_wrapper.py | sed -n '1,125p'

Repository: Flagsmith/flagsmith

Length of output: 19391


Script executed:

python3 - <<'PY'
import urllib.request
root='https://raw.githubusercontent.com/Flagsmith/flagsmith/'
for ref in ('v2.286.0','2.286.0'):
    print('\n###',ref)
    for path in ('api/app_analytics/migrate_to_pg.py','api/app_analytics/management/commands/migrate_analytics.py','api/app_analytics/analytics_db_service.py','api/app/settings/common.py','api/app_analytics/influxdb_wrapper.py'):
        try:
            text=urllib.request.urlopen(root+ref+'/'+path,timeout=15).read().decode().splitlines()
        except Exception as e:
            print(path, e); continue
        print('---',path)
        if path.endswith('migrate_to_pg.py') or path.endswith('migrate_analytics.py'):
            indices=range(len(text))
        else:
            wanted=('USE_POSTGRES_FOR_ANALYTICS','get_feature_evaluation_data(', 'get_feature_evaluation_data_from_local_db(', 'def get_client(', 'INFLUXDB_TOKEN =','INFLUXDB_BUCKET =','INFLUXDB_URL =','INFLUXDB_ORG =')
            indices=sorted({j for i,l in enumerate(text) if any(w in l for w in wanted) for j in range(max(0,i-2),min(len(text),i+12))})
        for i in indices: print(f'{i+1:4} {text[i]}')
url='https://raw.githubusercontent.com/Flagsmith/flagsmith-charts/a99c231d61dd89e1bc1924a4429619447b5e764f/charts/flagsmith/templates/_api_environment.yaml'
print('\n### full chart 0.85.0 API env')
for i,l in enumerate(urllib.request.urlopen(url,timeout=15).read().decode().splitlines()): print(f'{i+1:4} {l}')
PY

Repository: Flagsmith/flagsmith

Length of output: 12076


Web query:

Helm 3 upgrade removes resources no longer present in new chart release Kubernetes official documentation

Result:

Sources consulted:
- Changes Since Helm 2 | Helm — https://docs.helm.sh/docs/v3/faq/changes_since_helm2/
- helm upgrade | Helm — https://docs.helm.sh/docs/v3/helm/helm_upgrade/
- Chart Development Tips and Tricks | Helm — https://helm.sh/docs/v3/howto/charts_tips_and_tricks/
- Using Helm | Helm — https://helm.sh/docs/intro/using_helm/
- helm/pkg/action/upgrade.go at main · helm/helm · GitHub — https://github.com/helm/helm/blob/main/pkg/action/upgrade.go
- …and 7 more

Script executed:

python3 - <<'PY'
import io, tarfile, urllib.request
url='https://helm.influxdata.com/influxdb2-2.1.1.tgz'
print('###',url)
try:
 data=urllib.request.urlopen(url,timeout=30).read()
 with tarfile.open(fileobj=io.BytesIO(data),mode='r:gz') as tar:
  for member in tar.getmembers():
   if member.name.endswith(('/templates/service.yaml','/templates/deployment.yaml','/templates/statefulset.yaml')):
    print('\n---',member.name)
    text=tar.extractfile(member).read().decode().splitlines()
    for i,l in enumerate(text): print(f'{i+1:4} {l}')
except Exception as e: print('FETCH ERROR',repr(e))
for path, needles in [
 ('pkg/kube/client.go', ('func (c *Client) Update(', 'original.Difference(target)', 'ResourcePolicyAnno', 'DeleteWithOptions')),
 ('pkg/action/upgrade.go', ('KubeClient.Update(', 'execHook(', 'WaitWithJobs(', 'Wait(')),
]:
 url='https://raw.githubusercontent.com/helm/helm/v3.18.0/'+path
 print('\n###',url)
 try: lines=urllib.request.urlopen(url,timeout=20).read().decode().splitlines()
 except Exception as e: print('FETCH ERROR',repr(e)); continue
 indices=set()
 for i,l in enumerate(lines):
  if any(n in l for n in needles):
   indices.update(range(max(0,i-5),min(len(lines),i+14)))
 for i in sorted(indices): print(f'{i+1:4} {lines[i]}')
PY

Repository: Flagsmith/flagsmith

Length of output: 6450


Document the required InfluxDB source before enabling analytics migration.

When UsePostgresForAnalytics.enabled is true, chart 0.85.0 gives the migration Job PostgreSQL settings but no INFLUXDB_* settings. Chart 0.85.0 also removes the bundled InfluxDB. Configure the old data in influxdbExternal, run the migration, then switch analytics reads to PostgreSQL.


These notes appear only in the terminal output, so check them if you upgrade through CI or a GitOps tool. This page did
not test what happens to existing analytics data.

## What was tested

- Upgrade, rollback and restore between chart 0.80.0 (Flagsmith 2.222.0) and chart 0.85.0 (Flagsmith 2.286.0).
- A local kind cluster, default values and the PostgreSQL instance deployed by the chart.
- A database containing one organisation, one project and a few flags.

Not tested: custom values, an external or managed database, the `jobs.migrateDb` Job, the analytics migration, other
version pairs, and downtime during the upgrade.
42 changes: 42 additions & 0 deletions docs/docs/diagrams/upgrade-rollback-restore.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading