diff --git a/.github/workflows/lint-test.yaml b/.github/workflows/lint-test.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c3028e0790f0af74fa16e316a06fd8d0ab57c325
--- /dev/null
+++ b/.github/workflows/lint-test.yaml
@@ -0,0 +1,45 @@
+name: Lint and Test Charts
+
+on: pull_request
+
+jobs:
+  lint-test:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+        with:
+          fetch-depth: 0
+
+      - name: Set up Helm
+        uses: azure/setup-helm@v3
+        with:
+          version: v3.12.1
+
+      - uses: actions/setup-python@v4
+        with:
+          python-version: "3.10"
+          check-latest: true
+
+      - name: Set up chart-testing
+        uses: helm/chart-testing-action@v2.6.0
+
+      - name: Run chart-testing (list-changed)
+        id: list-changed
+        run: |
+          changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
+          if [[ -n "$changed" ]]; then
+            echo "changed=true" >> "$GITHUB_OUTPUT"
+          fi
+
+      - name: Run chart-testing (lint)
+        if: steps.list-changed.outputs.changed == 'true'
+        run: ct lint --validate-maintainers=false --target-branch ${{ github.event.repository.default_branch }}
+
+      - name: Create kind cluster
+        if: steps.list-changed.outputs.changed == 'true'
+        uses: helm/kind-action@v1.8.0
+
+      - name: Run chart-testing (install)
+        if: steps.list-changed.outputs.changed == 'true'
+        run: ct install --target-branch ${{ github.event.repository.default_branch }}
diff --git a/charts/supabase/Chart.yaml b/charts/supabase/Chart.yaml
index caa158b25f3494b1627fe46594d6c238322cc542..d7b9a1fc9f54ac603cc518e7ae9bdee9b7c5eb9a 100644
--- a/charts/supabase/Chart.yaml
+++ b/charts/supabase/Chart.yaml
@@ -15,7 +15,7 @@ type: application
 # This is the chart version. This version number should be incremented each time you make changes
 # to the chart and its templates, including the app version.
 # Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.0.3
+version: 0.1.0
 
 # This is the version number of the application being deployed. This version number should be
 # incremented each time you make changes to the application. Versions are not expected to
@@ -23,3 +23,6 @@ version: 0.0.3
 # It is recommended to use it with quotes.
 # Not used because too difficult to follow correctly
 # appVersion: "1.16.0"
+
+# A URL to an SVG or PNG image to be used as an icon
+icon: https://avatars.githubusercontent.com/u/54469796?s=280&v=4
diff --git a/charts/supabase/README.md b/charts/supabase/README.md
index 8d2f9f08a710354ddc167c83b002781ff970867d..28c59665a35bb8a20cbb6055274c36719875d839 100644
--- a/charts/supabase/README.md
+++ b/charts/supabase/README.md
@@ -21,80 +21,56 @@ git clone https://github.com/supabase-community/supabase-kubernetes
 # Switch to charts directory
 cd supabase-kubernetes/charts/supabase/
 
-# Create JWT secret
-kubectl -n default create secret generic demo-supabase-jwt \
-  --from-literal=anonKey='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgInJvbGUiOiAiYW5vbiIsCiAgICAiaXNzIjogInN1cGFiYXNlIiwKICAgICJpYXQiOiAxNjc1NDAwNDAwLAogICAgImV4cCI6IDE4MzMxNjY4MDAKfQ.ztuiBzjaVoFHmoljUXWmnuDN6QU2WgJICeqwyzyZO88' \
-  --from-literal=serviceKey='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgInJvbGUiOiAic2VydmljZV9yb2xlIiwKICAgICJpc3MiOiAic3VwYWJhc2UiLAogICAgImlhdCI6IDE2NzU0MDA0MDAsCiAgICAiZXhwIjogMTgzMzE2NjgwMAp9.qNsmXzz4tG7eqJPh1Y58DbtIlJBauwpqx39UF-MwM8k' \
-  --from-literal=secret='abcdefghijklmnopqrstuvwxyz123456'
-
-# Create SMTP secret
-kubectl -n default create secret generic demo-supabase-smtp \
-  --from-literal=username='your-mail@example.com' \
-  --from-literal=password='example123456'
-
-# Create DB secret
-kubectl -n default create secret generic demo-supabase-db \
-  --from-literal=username='postgres' \
-  --from-literal=password='example123456' 
-
 # Install the chart
-helm -n default install demo -f values.example.yaml .
+helm install demo -f values.example.yaml .
 ```
 
 The first deployment can take some time to complete (especially auth service). You can view the status of the pods using:
 
 ```bash
-kubectl -n default get pod 
+kubectl get pod -l app.kubernetes.io/instance=demo
 
 NAME                                      READY   STATUS    RESTARTS      AGE
-demo-supabase-auth-78547c5c8d-chkbm       1/1     Running   2 (40s ago)   47s
-demo-supabase-db-5bc75fbf56-4cxcv         1/1     Running   0             47s
-demo-supabase-kong-8c666695f-5vzwt        1/1     Running   0             47s
-demo-supabase-meta-6779677c7-s77qq        1/1     Running   0             47s
-demo-supabase-realtime-6b55986d7d-csnr7   1/1     Running   0             47s
-demo-supabase-rest-5d864469d-bk5rv        1/1     Running   0             47s
-demo-supabase-storage-6c878dcbd4-zzzcv    1/1     Running   0             47s
+demo-supabase-analytics-xxxxxxxxxx-xxxxx  1/1     Running   0             47s
+demo-supabase-auth-xxxxxxxxxx-xxxxx       1/1     Running   0             47s
+demo-supabase-db-xxxxxxxxxx-xxxxx         1/1     Running   0             47s
+demo-supabase-functions-xxxxxxxxxx-xxxxx  1/1     Running   0             47s
+demo-supabase-imgproxy-xxxxxxxxxx-xxxxx   1/1     Running   0             47s
+demo-supabase-kong-xxxxxxxxxx-xxxxx       1/1     Running   0             47s
+demo-supabase-meta-xxxxxxxxxx-xxxxx       1/1     Running   0             47s
+demo-supabase-realtime-xxxxxxxxxx-xxxxx   1/1     Running   0             47s
+demo-supabase-rest-xxxxxxxxxx-xxxxx       1/1     Running   0             47s
+demo-supabase-storage-xxxxxxxxxx-xxxxx    1/1     Running   0             47s
 ```
 
-### Tunnel with Minikube
-
-When the installation will be complete you'll be able to create a tunnel using minikube:
+### Access with Minikube
 
+Assuming that you have enabled Minikube ingress addon, note down the Minikube IP address:
+```shell
+minikube ip
+```
+Then, add the IP into your `/etc/hosts` file:
 ```bash
-# First, enable the ingress addon in Minikube
-minikube addons enable ingress
-
-# Then enable the tunnel (will need sudo credentials because you are opening Port 80/443 on your local machine)
-minikube tunnel
+# This will redirect request for example.com to the minikube IP
+<minikube-ip> example.com
 ```
-
-If you just use the `value.example.yaml` file, you can access the API or the Studio App using the following endpoints:
-
-- <http://api.localhost>
-- <http://studio.localhost>
+Open http://example.com in your browser.
 
 ### Uninstall
 
 ```Bash
 # Uninstall Helm chart
-helm -n default uninstall demo 
+helm uninstall demo
 
-# Delete secrets
-kubectl -n default delete secret demo-supabase-db
-kubectl -n default delete secret demo-supabase-jwt
-kubectl -n default delete secret demo-supabase-smtp
+# Backup and/or remove any Persistent Volume Claims that have keep annotation
+kubectl delete pvc demo-supabase-storage-pvc
 ```
 
 ## Customize
 
 You should consider to adjust the following values in `values.yaml`:
 
-- `JWT_SECRET_NAME`: Reference to Kubernetes secret with JWT secret data `secret`, `anonKey` & `serviceKey`
-- `SMTP_SECRET_NAME`: Reference to Kubernetes secret with SMTP credentials `username` & `password`
-- `DB_SECRET_NAME`: Reference to Kubernetes secret with Postgres credentials `username` & `password`
 - `RELEASE_NAME`: Name used for helm release
-- `NAMESPACE`: Namespace used for the helm release
-- `API.EXAMPLE.COM` URL to Kong API
 - `STUDIO.EXAMPLE.COM` URL to Studio
 
 If you want to use mail, consider to adjust the following values in `values.yaml`:
@@ -109,17 +85,11 @@ If you want to use mail, consider to adjust the following values in `values.yaml
 We encourage you to use your own JWT keys by generating a new Kubernetes secret and reference it in `values.yaml`:
 
 ```yaml
+secret:
   jwt:
-    secretName: "JWT_SECRET_NAME"
-```
-
-The secret can be created with kubectl via command-line:
-
-```bash
-kubectl -n NAMESPACE create secret generic JWT_SECRET_NAME \
-  --from-literal=secret='JWT_TOKEN_AT_LEAST_32_CHARACTERS_LONG' \
-  --from-literal=anonKey='JWT_ANON_KEY' \
-  --from-literal=serviceKey='JWT_SERVICE_KEY'
+    anonKey: <new-anon-jwt>
+    serviceKey: <new-service-role-jwt>
+    secret: <jwt-secret>
 ```
 
 > 32 characters long secret can be generated with `openssl rand 64 | base64`
@@ -130,16 +100,10 @@ kubectl -n NAMESPACE create secret generic JWT_SECRET_NAME \
 Connection credentials for the SMTP mail server will also be provided via Kubernetes secret referenced in `values.yaml`:
 
 ```yaml
+secret:
   smtp:
-    secretName: "SMTP_SECRET_NAME"
-```
-
-The secret can be created with kubectl via command-line:
-
-```bash
-kubectl -n NAMESPACE create secret generic SMTP_SECRET_NAME \
-  --from-literal=username='SMTP_USER' \
-  --from-literal=password='SMTP_PASSWORD'
+    username: <your-smtp-username>
+    password: <your-smtp-password>
 ```
 
 ### DB Secret
@@ -147,19 +111,65 @@ kubectl -n NAMESPACE create secret generic SMTP_SECRET_NAME \
 DB credentials will also be stored in a Kubernetes secret and referenced in `values.yaml`:
 
 ```yaml
+secret:
   db:
-    secretName: "DB_SECRET_NAME"
+    username: <db-username>
+    password: <db-password>
+    database: <supabase-database-name>
 ```
 
 The secret can be created with kubectl via command-line:
 
-```bash
-kubectl -n NAMESPACE create secret generic DB_SECRET_NAME \
-  --from-literal=username='DB_USER' \
-  --from-literal=password='PW_USER'
+> If you depend on database providers like [StackGres](https://stackgres.io/), [Postgres Operator](https://github.com/zalando/postgres-operator) or self-hosted Postgres instance, fill in the secret above and modify any relevant Postgres attributes such as port or hostname (e.g. `PGPORT`, `DB_HOST`) for any relevant deployments. Refer to [values.yaml](values.yaml) for more details.
+
+### Dashboard secret
+
+By default, a username and password is required to access the Supabase Studio dashboard. Simply change them at:
+
+```yaml
+secret:
+  dashboard:
+    username: supabase
+    password: this_password_is_insecure_and_should_be_updated
 ```
 
-> If you depend on database providers like [StackGres](https://stackgres.io/) or [Postgres Operator](https://github.com/zalando/postgres-operator) you only need to reference the already existing secret in `values.yaml`.
+### Analytics secret
+
+A new logflare secret API key is required for securing communication between all of the Supabase services. To set the secret, generate a new 32 characters long secret similar to the step [above](#jwt-secret).
+
+```yaml
+secret:
+  analytics:
+    apiKey: your-super-secret-with-at-least-32-characters-long-logflare-key
+```
+
+### S3 secret
+
+Supabase storage supports the use of S3 object-storage. To enable S3 for Supabase storage:
+
+1. Set S3 key ID and access key:
+  ```yaml
+   secret:
+    s3:
+      keyId: your-s3-key-id
+      accessKey: your-s3-access-key
+  ```
+2. Set storage S3 environment variables:
+  ```yaml
+  storage:
+    environment:
+      # Set S3 endpoint if using external object-storage
+      # GLOBAL_S3_ENDPOINT: http://minio:9000
+      STORAGE_BACKEND: s3
+      GLOBAL_S3_PROTOCOL: http
+      GLOBAL_S3_FORCE_PATH_STYLE: true
+      AWS_DEFAULT_REGION: stub
+  ```
+3. (Optional) Enable internal minio deployment
+  ```yaml
+  minio:
+    enabled: true
+  ```
 
 ## How to use in Production
 
@@ -173,6 +183,48 @@ But here are the important points you have to think about:
 - Change the domain used in the ingresses endpoints.
 - Generate a new secure JWT Secret.
 
+### Migration
+
+Migration from local development is made easy by adding migration scripts at `db.config` field. This will apply all of the migration scripts during the database initialization. For example:
+
+```yaml
+db:
+  config:
+    20230101000000_profiles.sql: |
+      create table profiles (
+        id uuid references auth.users not null,
+        updated_at timestamp with time zone,
+        username text unique,
+        avatar_url text,
+        website text,
+
+        primary key (id),
+        unique(username),
+        constraint username_length check (char_length(username) >= 3)
+      );
+```
+
+To make copying scripts easier, use this handy bash script:
+
+```bash
+#!/bin/bash
+
+for file in $1/*; do
+  clipboard+="    $(basename $file): |\n"
+  clipboard+=$(cat $file | awk '{print "      "$0}')
+  clipboard+="\n"
+done
+
+echo -e "$clipboard"
+```
+
+and pipe it to your system clipboard handler:
+
+```shell
+# Using xclip as an example
+./script.sh supabase/migrations | xclip -sel clipboard
+```
+
 ## Troubleshooting
 
 ### Ingress Controller and Ingress Class
@@ -187,3 +239,36 @@ kong:
     annotations:
       nginx.ingress.kubernetes.io/rewrite-target: /
 ```
+
+### Testing suite
+
+Before creating a merge request, you can test the charts locally by using [helm/chart-testing](https://github.com/helm/chart-testing). If you have Docker and a Kubernetes environment to test with, simply run:
+
+```shell
+# Run chart-testing (lint)
+docker run -it \
+  --workdir=/data \
+  --volume $(pwd)/charts/supabase:/data \
+  quay.io/helmpack/chart-testing:v3.7.1 \
+  ct lint --validate-maintainers=false --chart-dirs . --charts .
+# Run chart-testing (install)
+docker run -it \
+  --network host \
+  --workdir=/data \
+  --volume ~/.kube/config:/root/.kube/config:ro \
+  --volume $(pwd)/charts/supabase:/data \
+  quay.io/helmpack/chart-testing:v3.7.1 \
+  ct install --chart-dirs . --charts .
+```
+
+### Version compatibility
+
+#### `0.0.x` to `0.1.x`
+
+* `supabase/postgres` is updated from `14.1` to `15.1`, which warrants backing up all your data before proceeding to update to the next major version.
+* Intialization scripts for `supabase/postgres` has been reworked and matched closely to the [Docker Compose](https://github.com/supabase/supabase/blob/master/docker/docker-compose.yml) version. Further tweaks to the scripts are needed to ensure backward-compatibility.
+* Migration scripts are now exposed at `db.config`, which will be mounted at `/docker-entrypoint-initdb.d/migrations/`. Simply copy your migration files from your local project's `supabase/migration` and populate the `db.config`.
+* Ingress are now limited to `kong` & `db` services. This is by design to limit entry to the stack through secure `kong` service.
+* `kong.yaml` has been modified to follow [Docker kong.yaml](https://github.com/supabase/supabase/blob/master/docker/volumes/api/kong.yml) template.
+* `supabase/storage` does not comes with pre-populated `/var/lib/storage`, therefore an `emptyDir` will be created if persistence is disabled. This might be incompatible with previous version if the persistent storage location is set to location other than specified above.
+* `supabase/vector` requires read access to the `/var/log/pods` directory. When run in a Kubernetes cluster this can be provided with a [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) volume.
diff --git a/charts/supabase/ci/example-values.yaml b/charts/supabase/ci/example-values.yaml
new file mode 120000
index 0000000000000000000000000000000000000000..6b4faa48f1210a948887dae9f51de1119167257b
--- /dev/null
+++ b/charts/supabase/ci/example-values.yaml
@@ -0,0 +1 @@
+../values.example.yaml
\ No newline at end of file
diff --git a/charts/supabase/templates/NOTES.txt b/charts/supabase/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f06631a85ed8215f9bdfd250dbdc71ce27b9159a
--- /dev/null
+++ b/charts/supabase/templates/NOTES.txt
@@ -0,0 +1,5 @@
+---
+Thank you for installing {{ .Chart.Name }}!
+{{ if .Values.kong.ingress.enabled }}
+Visit the Studio dashboard at http://{{ (index .Values.kong.ingress.hosts 0).host }}
+{{- end }}
diff --git a/charts/supabase/templates/analytics/_helpers.tpl b/charts/supabase/templates/analytics/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..d960a1d6a46616bd098a048f952728d227ea77ea
--- /dev/null
+++ b/charts/supabase/templates/analytics/_helpers.tpl
@@ -0,0 +1,43 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "supabase.analytics.name" -}}
+{{- default (print .Chart.Name "-analytics") .Values.analytics.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "supabase.analytics.fullname" -}}
+{{- if .Values.analytics.fullnameOverride }}
+{{- .Values.analytics.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default (print .Chart.Name "-analytics") .Values.analytics.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "supabase.analytics.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "supabase.analytics.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "supabase.analytics.serviceAccountName" -}}
+{{- if .Values.analytics.serviceAccount.create }}
+{{- default (include "supabase.analytics.fullname" .) .Values.analytics.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.analytics.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/analytics/deployment.yaml b/charts/supabase/templates/analytics/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3f11bb921c87fc41ee6a870db23ab0a74c14a81d
--- /dev/null
+++ b/charts/supabase/templates/analytics/deployment.yaml
@@ -0,0 +1,154 @@
+{{- if .Values.analytics.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "supabase.analytics.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  {{- if not .Values.analytics.autoscaling.enabled }}
+  replicas: {{ .Values.analytics.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "supabase.analytics.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.analytics.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "supabase.analytics.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.analytics.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "supabase.analytics.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.analytics.podSecurityContext | nindent 8 }}
+      initContainers:
+        - name: init-db
+          image: postgres:15-alpine
+          imagePullPolicy: IfNotPresent
+          env:
+            - name: DB_HOST
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . | quote }}
+              {{- else }}
+              value: {{ .Values.analytics.environment.DB_HOST | quote }}
+              {{- end }}
+            - name: DB_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: username
+            - name: DB_PORT
+              value: {{ .Values.analytics.environment.DB_PORT | quote }}
+          command: ["/bin/sh", "-c"]
+          args:
+            - |
+              until pg_isready -h $(DB_HOST) -p $(DB_PORT) -U $(DB_USER); do
+              echo "Waiting for database to start..."
+              sleep 2
+              done
+            - echo "Database is ready"
+      containers:
+        - name: {{ include "supabase.analytics.name" $ }}
+          securityContext:
+            {{- toYaml .Values.analytics.securityContext | nindent 12 }}
+          image: "{{ .Values.analytics.image.repository }}:{{ .Values.analytics.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.analytics.image.pullPolicy }}
+          env:
+            {{- range $key, $value := .Values.analytics.environment }}
+            - name: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOSTNAME
+              value: {{ include "supabase.db.fullname" . }}
+            {{- end }}
+            - name: DB_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password
+            - name: DB_PASSWORD_ENC
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password_encoded
+            - name: DB_DATABASE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
+            - name: LOGFLARE_API_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.analytics" . }}
+                  key: apiKey
+            {{- if .Values.analytics.bigQuery.enabled }}
+            - name: GOOGLE_PROJECT_ID
+              value: {{ .Values.analytics.bigQuery.projectId | quote }}
+            - name: GOOGLE_PROJECT_NUMBER
+              value: {{ .Values.analytics.bigQuery.projectNumber | quote }}
+            {{- else }}
+            - name: POSTGRES_BACKEND_URL
+              value: $(DB_DRIVER)://$(DB_USERNAME):$(DB_PASSWORD_ENC)@$(DB_HOSTNAME):$(DB_PORT)/$(DB_DATABASE)
+            - name: POSTGRES_BACKEND_SCHEMA
+              value: $(DB_SCHEMA)
+            - name: LOGFLARE_FEATURE_FLAG_OVERRIDE
+              value: $(FEATURE_FLAG_OVERRIDE)
+            {{- end }}
+          {{- with .Values.analytics.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.analytics.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          ports:
+            - containerPort: {{ .Values.analytics.service.port }}
+              protocol: TCP
+          {{- if or (.Values.analytics.bigQuery.enabled) (.Values.analytics.volumes) }}
+          volumeMounts:
+            {{- with .Values.analytics.volumeMounts }}
+              {{- toYaml . | nindent 12 }}
+            {{- end }}
+            {{- if .Values.analytics.bigQuery.enabled }}
+            - mountPath: /opt/app/rel/logflare/bin/gcloud.json
+              name: gcloud-credentials
+              subPath: gcloud.json
+            {{- end }}
+          {{- end }}
+          {{- with .Values.analytics.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+      {{- if or (.Values.analytics.bigQuery.enabled) (.Values.analytics.volumes) }}
+      volumes:
+        {{- with .Values.analytics.volumes }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+        {{- if .Values.analytics.bigQuery.enabled }}
+        - name: gcloud-credentials
+          secret:
+            secretName: {{ include "supabase.analytics.fullname" . }}-gcloud
+        {{- end }}
+      {{- end }}
+      {{- with .Values.analytics.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.analytics.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.analytics.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/analytics/gcloud.secret.yaml b/charts/supabase/templates/analytics/gcloud.secret.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..71a645ada0caad1232329188ad21e6b0af966f0d
--- /dev/null
+++ b/charts/supabase/templates/analytics/gcloud.secret.yaml
@@ -0,0 +1,11 @@
+{{- if .Values.analytics.bigQuery.enabled }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.analytics.fullname" . }}-gcloud
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+  gcloud.json: {{ .Values.analytics.bigQuery.gcloudJson | b64enc }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/analytics/service.yaml b/charts/supabase/templates/analytics/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d8f43cb1227f88ab4ab62d8f66c22efea5f72b32
--- /dev/null
+++ b/charts/supabase/templates/analytics/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.analytics.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "supabase.analytics.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.analytics.service.type }}
+  ports:
+    - port: {{ .Values.analytics.service.port }}
+      targetPort: 4000
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "supabase.analytics.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/analytics/serviceaccount.yaml b/charts/supabase/templates/analytics/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73c72f20469804eae75586e5f58e2f713715b46f
--- /dev/null
+++ b/charts/supabase/templates/analytics/serviceaccount.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.analytics.enabled -}}
+{{- if .Values.analytics.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "supabase.analytics.serviceAccountName" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.analytics.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/auth/config.yaml b/charts/supabase/templates/auth/config.yaml
deleted file mode 100644
index 3b0ec639326dd7fbec06274de21d5814045e89f2..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/auth/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.auth.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.auth.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.auth.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/auth/deployment.yaml b/charts/supabase/templates/auth/deployment.yaml
index 947e78126a1361546f9766d943a0c0debd9c0da8..b2ee0b42cbdc4f5522135fa946f4b4567b41b4a2 100644
--- a/charts/supabase/templates/auth/deployment.yaml
+++ b/charts/supabase/templates/auth/deployment.yaml
@@ -34,14 +34,18 @@ spec:
           imagePullPolicy: IfNotPresent
           env:
             - name: DB_HOST
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . | quote }}
+              {{- else }}
               value: {{ .Values.auth.environment.DB_HOST | quote }}
-            - name: DB_PORT
-              value: {{ .Values.auth.environment.DB_PORT | quote }}
+              {{- end }}
             - name: DB_USER
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: username
+            - name: DB_PORT
+              value: {{ .Values.auth.environment.DB_PORT | quote }}
           command: ["/bin/sh", "-c"]
           args:
             - |
@@ -59,40 +63,54 @@ spec:
           env:
             {{- range $key, $value := .Values.auth.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.auth.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOST
+              value: {{ include "supabase.db.fullname" . }}
             {{- end }}
-            - name: DB_USER
-              valueFrom:
-                secretKeyRef:
-                  name: {{ .Values.db.secretName }}
-                  key: username
             - name: DB_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: DB_PASSWORD_ENC
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password_encoded
+            - name: DB_NAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
             - name: GOTRUE_DB_DATABASE_URL
-              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?search_path=auth&sslmode=$(DB_SSL)
+              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD_ENC)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?search_path=auth&sslmode=$(DB_SSL)
             - name: GOTRUE_DB_DRIVER
               value: $(DB_DRIVER)
             - name: GOTRUE_JWT_SECRET
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: secret
             - name: GOTRUE_SMTP_USER
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.smtp.secretName }}
+                  name: {{ include "supabase.secret.smtp" . }}
                   key: username
             - name: GOTRUE_SMTP_PASS
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.smtp.secretName }}
+                  name: {{ include "supabase.secret.smtp" . }}
                   key: password
+          {{- with .Values.auth.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.auth.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 9999
diff --git a/charts/supabase/templates/auth/ingress.yaml b/charts/supabase/templates/auth/ingress.yaml
deleted file mode 100644
index 799e9928dc7e35bdacd79b8ca5048f9af1a1478c..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/auth/ingress.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-{{- if .Values.auth.ingress.enabled -}}
-{{- $fullName := include "supabase.auth.fullname" . -}}
-{{- $svcPort := .Values.auth.service.port -}}
-{{- if and .Values.auth.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.auth.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.auth.ingress.annotations "kubernetes.io/ingress.class" .Values.auth.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.auth.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.auth.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.auth.ingress.className }}
-  {{- end }}
-  {{- if .Values.auth.ingress.tls }}
-  tls:
-    {{- range .Values.auth.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.auth.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/db/deployment.yaml b/charts/supabase/templates/db/deployment.yaml
index c9c3c943c157a045abf987914041aad74b4110fe..13da44b807f5c35314274becbf64be08ca137a30 100644
--- a/charts/supabase/templates/db/deployment.yaml
+++ b/charts/supabase/templates/db/deployment.yaml
@@ -28,6 +28,30 @@ spec:
       serviceAccountName: {{ include "supabase.db.serviceAccountName" . }}
       securityContext:
         {{- toYaml .Values.db.podSecurityContext | nindent 8 }}
+      initContainers:
+        - name: init-db
+          image: "{{ .Values.db.image.repository }}:{{ .Values.db.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: IfNotPresent
+          command: ["/bin/sh", "-c"]
+          args:
+            - |
+              echo "Copying init scripts into existing image script directory..."
+              cp -r /docker-entrypoint-initdb.d/* /initdb.d/
+              cp /custom-init-scripts/98-webhooks.sql /initdb.d/init-scripts/
+              cp /custom-init-scripts/99-roles.sql /initdb.d/init-scripts/
+              cp /custom-init-scripts/99-logs.sql /initdb.d/migrations/
+              cp /custom-init-scripts/99-realtime.sql /initdb.d/migrations/
+
+              echo "Copying user-defined migration scripts..."
+              cp /custom-migrations/* /initdb.d/migrations/ || echo "Skip migrations"
+              echo "Initialization scripts are ready"
+          volumeMounts:
+            - mountPath: /custom-init-scripts
+              name: custom-init-scripts
+            - mountPath: /custom-migrations
+              name: custom-migrations
+            - mountPath: /initdb.d
+              name: initdb-scripts-data
       containers:
         - name: {{ include "supabase.db.name" $ }}
           securityContext:
@@ -37,33 +61,53 @@ spec:
           env:
             {{- range $key, $value := .Values.db.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.db.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
             {{- end }}
             - name: POSTGRES_USER
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: username
+            - name: PGPASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password
             - name: POSTGRES_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: PGDATABASE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
+            - name: POSTGRES_DB
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
+          {{- with .Values.db.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.db.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 9999
               protocol: TCP
           volumeMounts:
-            - mountPath: /docker-entrypoint-initdb.d/
-              name: custom-init-scripts
+            - mountPath: /docker-entrypoint-initdb.d
+              name: initdb-scripts-data
             {{- with .Values.db.volumeMounts }}
               {{- toYaml . | nindent 12 }}
             {{- end }}
             {{- if .Values.db.persistence.enabled }}
-            - mountPath: {{ .Values.db.storage.mountPath }}
+            - mountPath: /var/lib/postgresql/data
               name: postgres-volume
             {{- end }}
           {{- with .Values.db.resources }}
@@ -71,9 +115,15 @@ spec:
             {{- toYaml . | nindent 12 }}
           {{- end }}
       volumes:
+        - name: initdb-scripts-data
+          emptyDir:
+            medium: ""
         - name: custom-init-scripts
           configMap:
             name: {{ include "supabase.db.fullname" . }}-initdb
+        - name: custom-migrations
+          configMap:
+            name: {{ include "supabase.db.fullname" . }}-migrations
         {{- with .Values.db.volumes }}
           {{- toYaml . | nindent 8 }}
         {{- end }}
diff --git a/charts/supabase/templates/db/ingress.yaml b/charts/supabase/templates/db/ingress.yaml
deleted file mode 100644
index 2d02bdd32e11a2bc37a67470691e6580d77b081f..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/db/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.db.enabled -}}
-{{- if .Values.db.ingress.enabled -}}
-{{- $fullName := include "supabase.db.fullname" . -}}
-{{- $svcPort := .Values.db.service.port -}}
-{{- if and .Values.db.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.db.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.db.ingress.annotations "kubernetes.io/ingress.class" .Values.db.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.db.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.db.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.db.ingress.className }}
-  {{- end }}
-  {{- if .Values.db.ingress.tls }}
-  tls:
-    {{- range .Values.db.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.db.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/db/initdb.config.yaml b/charts/supabase/templates/db/initdb.config.yaml
index 98ae0e4f2dc9f174306a61009b6180f8f361811c..25f61ad23fac72cd7b215433d5876a6f24efabd4 100644
--- a/charts/supabase/templates/db/initdb.config.yaml
+++ b/charts/supabase/templates/db/initdb.config.yaml
@@ -6,388 +6,238 @@ metadata:
   labels:
     {{- include "supabase.labels" . | nindent 4 }}
 data:
-  01-initial-schema.sql: |
-    -- Set up realtime
-    create schema if not exists realtime;
-    -- create publication supabase_realtime; -- defaults to empty publication
-    create publication supabase_realtime;
-    create schema if not exists _realtime;
-    create schema if not exists realtime;
-
-    -- Supabase super admin
-    create user supabase_admin;
-    alter user  supabase_admin with superuser createdb createrole replication bypassrls;
-
-    -- Extension namespacing
-    create schema if not exists extensions;
-    create extension if not exists "uuid-ossp"      with schema extensions;
-    create extension if not exists pgcrypto         with schema extensions;
-    create extension if not exists pgjwt            with schema extensions;
-
-    -- Set up auth roles for the developer
-    create role anon                nologin noinherit;
-    create role authenticated       nologin noinherit; -- "logged in" user: web_user, app_user, etc
-    create role service_role        nologin noinherit bypassrls; -- allow developers to create JWT's that bypass their policies
-
-    create user authenticator noinherit;
-    grant anon              to authenticator;
-    grant authenticated     to authenticator;
-    grant service_role      to authenticator;
-    grant supabase_admin    to authenticator;
-
-    grant usage                     on schema public to postgres, anon, authenticated, service_role;
-    alter default privileges in schema public grant all on tables to postgres, anon, authenticated, service_role;
-    alter default privileges in schema public grant all on functions to postgres, anon, authenticated, service_role;
-    alter default privileges in schema public grant all on sequences to postgres, anon, authenticated, service_role;
-
-    -- Allow Extensions to be used in the API
-    grant usage                     on schema extensions to postgres, anon, authenticated, service_role;
-
-    -- Set up namespacing
-    alter user supabase_admin SET search_path TO public, extensions; -- don't include the "auth" schema
-
-    -- These are required so that the users receive grants whenever "supabase_admin" creates tables/function
-    alter default privileges for user supabase_admin in schema public grant all
-        on sequences to postgres, anon, authenticated, service_role;
-    alter default privileges for user supabase_admin in schema public grant all
-        on tables to postgres, anon, authenticated, service_role;
-    alter default privileges for user supabase_admin in schema public grant all
-        on functions to postgres, anon, authenticated, service_role;
-
-    -- Set short statement/query timeouts for API roles
-    alter role anon set statement_timeout = '3s';
-    alter role authenticated set statement_timeout = '8s';
-  02-auth-schema.sql: |
-    CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_admin;
-
-    -- auth.users definition
-
-    CREATE TABLE auth.users (
-    instance_id uuid NULL,
-    id uuid NOT NULL UNIQUE,
-    aud varchar(255) NULL,
-    "role" varchar(255) NULL,
-    email varchar(255) NULL UNIQUE,
-    encrypted_password varchar(255) NULL,
-    confirmed_at timestamptz NULL,
-    invited_at timestamptz NULL,
-    confirmation_token varchar(255) NULL,
-    confirmation_sent_at timestamptz NULL,
-    recovery_token varchar(255) NULL,
-    recovery_sent_at timestamptz NULL,
-    email_change_token varchar(255) NULL,
-    email_change varchar(255) NULL,
-    email_change_sent_at timestamptz NULL,
-    last_sign_in_at timestamptz NULL,
-    raw_app_meta_data jsonb NULL,
-    raw_user_meta_data jsonb NULL,
-    is_super_admin bool NULL,
-    created_at timestamptz NULL,
-    updated_at timestamptz NULL,
-    CONSTRAINT users_pkey PRIMARY KEY (id)
-    );
-    CREATE INDEX users_instance_id_email_idx ON auth.users USING btree (instance_id, email);
-    CREATE INDEX users_instance_id_idx ON auth.users USING btree (instance_id);
-    comment on table auth.users is 'Auth: Stores user login data within a secure schema.';
-
-    -- auth.refresh_tokens definition
-
-    CREATE TABLE auth.refresh_tokens (
-    instance_id uuid NULL,
-    id bigserial NOT NULL,
-    "token" varchar(255) NULL,
-    user_id varchar(255) NULL,
-    revoked bool NULL,
-    created_at timestamptz NULL,
-    updated_at timestamptz NULL,
-    CONSTRAINT refresh_tokens_pkey PRIMARY KEY (id)
-    );
-    CREATE INDEX refresh_tokens_instance_id_idx ON auth.refresh_tokens USING btree (instance_id);
-    CREATE INDEX refresh_tokens_instance_id_user_id_idx ON auth.refresh_tokens USING btree (instance_id, user_id);
-    CREATE INDEX refresh_tokens_token_idx ON auth.refresh_tokens USING btree (token);
-    comment on table auth.refresh_tokens is 'Auth: Store of tokens used to refresh JWT tokens once they expire.';
-
-    -- auth.instances definition
-
-    CREATE TABLE auth.instances (
-    id uuid NOT NULL,
-    uuid uuid NULL,
-    raw_base_config text NULL,
-    created_at timestamptz NULL,
-    updated_at timestamptz NULL,
-    CONSTRAINT instances_pkey PRIMARY KEY (id)
-    );
-    comment on table auth.instances is 'Auth: Manages users across multiple sites.';
-
-    -- auth.audit_log_entries definition
-
-    CREATE TABLE auth.audit_log_entries (
-    instance_id uuid NULL,
-    id uuid NOT NULL,
-    payload json NULL,
-    created_at timestamptz NULL,
-    CONSTRAINT audit_log_entries_pkey PRIMARY KEY (id)
-    );
-    CREATE INDEX audit_logs_instance_id_idx ON auth.audit_log_entries USING btree (instance_id);
-    comment on table auth.audit_log_entries is 'Auth: Audit trail for user actions.';
-
-    -- auth.schema_migrations definition
-
-    CREATE TABLE auth.schema_migrations (
-    "version" varchar(255) NOT NULL,
-    CONSTRAINT schema_migrations_pkey PRIMARY KEY ("version")
-    );
-    comment on table auth.schema_migrations is 'Auth: Manages updates to the auth system.';
-
-    INSERT INTO auth.schema_migrations (version)
-    VALUES  ('20171026211738'),
-            ('20171026211808'),
-            ('20171026211834'),
-            ('20180103212743'),
-            ('20180108183307'),
-            ('20180119214651'),
-            ('20180125194653');
-
-    create or replace function auth.uid() 
-    returns uuid 
-    language sql stable
-    as $$
-    select 
-        coalesce(
-        current_setting('request.jwt.claim.sub', true),
-        (current_setting('request.jwt.claims', true)::jsonb ->> 'sub')
-    )::uuid
-    $$;
-
-    create or replace function auth.role() 
-    returns text 
-    language sql stable
-    as $$
-    select 
-        coalesce(
-        current_setting('request.jwt.claim.role', true),
-        (current_setting('request.jwt.claims', true)::jsonb ->> 'role')
-    )::text
-    $$;
+  99-jwt.sql: |
+    \set jwt_secret `echo "$JWT_SECRET"`
+    \set jwt_exp `echo "$JWT_EXP"`
 
-    create or replace function auth.email() 
-    returns text 
-    language sql stable
-    as $$
-    select 
-        coalesce(
-        current_setting('request.jwt.claim.email', true),
-        (current_setting('request.jwt.claims', true)::jsonb ->> 'email')
-    )::text
-    $$;
+    ALTER DATABASE postgres SET "app.settings.jwt_secret" TO :jwt_secret;
+    ALTER DATABASE postgres SET "app.settings.jwt_exp" TO :jwt_exp;
+  99-logs.sql: |
+    \set pguser `echo "$POSTGRES_USER"`
 
-    -- usage on auth functions to API roles
-    GRANT USAGE ON SCHEMA auth TO anon, authenticated, service_role;
+    create schema if not exists _analytics;
+    alter schema _analytics owner to :pguser;
+  99-realtime.sql: |
+    \set pguser `echo "$POSTGRES_USER"`
 
-    -- Supabase super admin
-    CREATE USER supabase_auth_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION;
-    GRANT ALL PRIVILEGES ON SCHEMA auth TO supabase_auth_admin;
-    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA auth TO supabase_auth_admin;
-    GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA auth TO supabase_auth_admin;
-    ALTER USER supabase_auth_admin SET search_path = "auth";
-    ALTER table "auth".users OWNER TO supabase_auth_admin;
-    ALTER table "auth".refresh_tokens OWNER TO supabase_auth_admin;
-    ALTER table "auth".audit_log_entries OWNER TO supabase_auth_admin;
-    ALTER table "auth".instances OWNER TO supabase_auth_admin;
-    ALTER table "auth".schema_migrations OWNER TO supabase_auth_admin;
-
-    ALTER FUNCTION "auth"."uid" OWNER TO supabase_auth_admin;
-    ALTER FUNCTION "auth"."role" OWNER TO supabase_auth_admin;
-    ALTER FUNCTION "auth"."email" OWNER TO supabase_auth_admin;
-    GRANT EXECUTE ON FUNCTION "auth"."uid"() TO PUBLIC;
-    GRANT EXECUTE ON FUNCTION "auth"."role"() TO PUBLIC;
-    GRANT EXECUTE ON FUNCTION "auth"."email"() TO PUBLIC;
-
-  03-storage-schema.sql: |
-    CREATE SCHEMA IF NOT EXISTS storage AUTHORIZATION supabase_admin;
-
-    grant usage on schema storage to postgres, anon, authenticated, service_role;
-    alter default privileges in schema storage grant all on tables to postgres, anon, authenticated, service_role;
-    alter default privileges in schema storage grant all on functions to postgres, anon, authenticated, service_role;
-    alter default privileges in schema storage grant all on sequences to postgres, anon, authenticated, service_role;
-
-    CREATE TABLE "storage"."buckets" (
-        "id" text not NULL,
-        "name" text NOT NULL,
-        "owner" uuid,
-        "created_at" timestamptz DEFAULT now(),
-        "updated_at" timestamptz DEFAULT now(),
-        CONSTRAINT "buckets_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"),
-        PRIMARY KEY ("id")
-    );
-    CREATE UNIQUE INDEX "bname" ON "storage"."buckets" USING BTREE ("name");
-
-    CREATE TABLE "storage"."objects" (
-        "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(),
-        "bucket_id" text,
-        "name" text,
-        "owner" uuid,
-        "created_at" timestamptz DEFAULT now(),
-        "updated_at" timestamptz DEFAULT now(),
-        "last_accessed_at" timestamptz DEFAULT now(),
-        "metadata" jsonb,
-        CONSTRAINT "objects_bucketId_fkey" FOREIGN KEY ("bucket_id") REFERENCES "storage"."buckets"("id"),
-        CONSTRAINT "objects_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"),
-        PRIMARY KEY ("id")
-    );
-    CREATE UNIQUE INDEX "bucketid_objname" ON "storage"."objects" USING BTREE ("bucket_id","name");
-    CREATE INDEX name_prefix_search ON storage.objects(name text_pattern_ops);
-
-    ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;
-
-    CREATE FUNCTION storage.foldername(name text)
-    RETURNS text[]
-    LANGUAGE plpgsql
-    AS $function$
-    DECLARE
-    _parts text[];
-    BEGIN
-    select string_to_array(name, '/') into _parts;
-    return _parts[1:array_length(_parts,1)-1];
-    END
-    $function$;
-
-    CREATE FUNCTION storage.filename(name text)
-    RETURNS text
-    LANGUAGE plpgsql
-    AS $function$
-    DECLARE
-    _parts text[];
-    BEGIN
-    select string_to_array(name, '/') into _parts;
-    return _parts[array_length(_parts,1)];
-    END
-    $function$;
-
-    CREATE FUNCTION storage.extension(name text)
-    RETURNS text
-    LANGUAGE plpgsql
-    AS $function$
-    DECLARE
-    _parts text[];
-    _filename text;
-    BEGIN
-    select string_to_array(name, '/') into _parts;
-    select _parts[array_length(_parts,1)] into _filename;
-    -- @todo return the last part instead of 2
-    return split_part(_filename, '.', 2);
-    END
-    $function$;
-
-    CREATE FUNCTION storage.search(prefix text, bucketname text, limits int DEFAULT 100, levels int DEFAULT 1, offsets int DEFAULT 0)
-    RETURNS TABLE (
-        name text,
-        id uuid,
-        updated_at TIMESTAMPTZ,
-        created_at TIMESTAMPTZ,
-        last_accessed_at TIMESTAMPTZ,
-        metadata jsonb
-    )
-    LANGUAGE plpgsql
-    AS $function$
-    DECLARE
-    _bucketId text;
-    BEGIN
-        -- will be replaced by migrations when server starts
-        -- saving space for cloud-init
-    END
-    $function$;
-
-    -- create migrations table
-    -- https://github.com/ThomWright/postgres-migrations/blob/master/src/migrations/0_create-migrations-table.sql
-    -- we add this table here and not let it be auto-created so that the permissions are properly applied to it
-    CREATE TABLE IF NOT EXISTS storage.migrations (
-    id integer PRIMARY KEY,
-    name varchar(100) UNIQUE NOT NULL,
-    hash varchar(40) NOT NULL, -- sha1 hex encoded hash of the file name and contents, to ensure it hasn't been altered since applying the migration
-    executed_at timestamp DEFAULT current_timestamp
-    );
-
-    CREATE USER supabase_storage_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION;
-    GRANT ALL PRIVILEGES ON SCHEMA storage TO supabase_storage_admin;
-    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA storage TO supabase_storage_admin;
-    GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA storage TO supabase_storage_admin;
-    ALTER USER supabase_storage_admin SET search_path = "storage";
-    ALTER table "storage".objects owner to supabase_storage_admin;
-    ALTER table "storage".buckets owner to supabase_storage_admin;
-    ALTER table "storage".migrations OWNER TO supabase_storage_admin;
-    ALTER function "storage".foldername(text) owner to supabase_storage_admin;
-    ALTER function "storage".filename(text) owner to supabase_storage_admin;
-    ALTER function "storage".extension(text) owner to supabase_storage_admin;
-    ALTER function "storage".search(text,text,int,int,int) owner to supabase_storage_admin;
-
-  04-post-setup.sql: |
-    ALTER ROLE postgres SET search_path TO "\$user",public,extensions;
-    CREATE OR REPLACE FUNCTION extensions.notify_api_restart()
-    RETURNS event_trigger
-    LANGUAGE plpgsql
-    AS $$
-    BEGIN
-        NOTIFY ddl_command_end;
-    END;
-    $$;
-    CREATE EVENT TRIGGER api_restart ON ddl_command_end
-    EXECUTE PROCEDURE extensions.notify_api_restart();
-    COMMENT ON FUNCTION extensions.notify_api_restart IS 'Sends a notification to the API to restart. If your database schema has changed, this is required so that Supabase can rebuild the relationships.';
-
-    -- Trigger for pg_cron
-    CREATE OR REPLACE FUNCTION extensions.grant_pg_cron_access()
-    RETURNS event_trigger
-    LANGUAGE plpgsql
-    AS $$
-    DECLARE
-    schema_is_cron bool;
-    BEGIN
-    schema_is_cron = (
-        SELECT n.nspname = 'cron'
-        FROM pg_event_trigger_ddl_commands() AS ev
-        LEFT JOIN pg_catalog.pg_namespace AS n
-        ON ev.objid = n.oid
-    );
-
-    IF schema_is_cron
-    THEN
-        grant usage on schema cron to postgres with grant option;
-
-        alter default privileges in schema cron grant all on tables to postgres with grant option;
-        alter default privileges in schema cron grant all on functions to postgres with grant option;
-        alter default privileges in schema cron grant all on sequences to postgres with grant option;
-
-        alter default privileges for user supabase_admin in schema cron grant all
-            on sequences to postgres with grant option;
-        alter default privileges for user supabase_admin in schema cron grant all
-            on tables to postgres with grant option;
-        alter default privileges for user supabase_admin in schema cron grant all
-            on functions to postgres with grant option;
-
-        grant all privileges on all tables in schema cron to postgres with grant option; 
-
-    END IF;
-
-    END;
-    $$;
-    CREATE EVENT TRIGGER issue_pg_cron_access ON ddl_command_end WHEN TAG in ('CREATE SCHEMA')
-    EXECUTE PROCEDURE extensions.grant_pg_cron_access();
-    COMMENT ON FUNCTION extensions.grant_pg_cron_access IS 'Grants access to pg_cron';
-
-    -- Supabase dashboard user
-    CREATE ROLE dashboard_user NOSUPERUSER CREATEDB CREATEROLE REPLICATION;
-    GRANT ALL ON DATABASE postgres TO dashboard_user;
-    GRANT ALL ON SCHEMA auth TO dashboard_user;
-    GRANT ALL ON SCHEMA extensions TO dashboard_user;
-    GRANT ALL ON SCHEMA storage TO dashboard_user;
-    GRANT ALL ON ALL TABLES IN SCHEMA auth TO dashboard_user;
-    GRANT ALL ON ALL TABLES IN SCHEMA extensions TO dashboard_user;
-    -- GRANT ALL ON ALL TABLES IN SCHEMA storage TO dashboard_user;
-    GRANT ALL ON ALL SEQUENCES IN SCHEMA auth TO dashboard_user;
-    GRANT ALL ON ALL SEQUENCES IN SCHEMA storage TO dashboard_user;
-    GRANT ALL ON ALL SEQUENCES IN SCHEMA extensions TO dashboard_user;
-    GRANT ALL ON ALL ROUTINES IN SCHEMA auth TO dashboard_user;
-    GRANT ALL ON ALL ROUTINES IN SCHEMA storage TO dashboard_user;
-    GRANT ALL ON ALL ROUTINES IN SCHEMA extensions TO dashboard_user;
+    create schema if not exists _realtime;
+    alter schema _realtime owner to :pguser;
+  99-roles.sql: |
+    -- NOTE: change to your own passwords for production environments
+    \set pgpass `echo "$POSTGRES_PASSWORD"`
+
+    ALTER USER authenticator WITH PASSWORD :'pgpass';
+    ALTER USER pgbouncer WITH PASSWORD :'pgpass';
+    ALTER USER supabase_auth_admin WITH PASSWORD :'pgpass';
+    ALTER USER supabase_functions_admin WITH PASSWORD :'pgpass';
+    ALTER USER supabase_storage_admin WITH PASSWORD :'pgpass';
+  98-webhooks.sql: |
+    BEGIN;
+      -- Create pg_net extension
+      CREATE EXTENSION IF NOT EXISTS pg_net SCHEMA extensions;
+      -- Create supabase_functions schema
+      CREATE SCHEMA supabase_functions AUTHORIZATION supabase_admin;
+      GRANT USAGE ON SCHEMA supabase_functions TO postgres, anon, authenticated, service_role;
+      ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON TABLES TO postgres, anon, authenticated, service_role;
+      ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON FUNCTIONS TO postgres, anon, authenticated, service_role;
+      ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON SEQUENCES TO postgres, anon, authenticated, service_role;
+      -- supabase_functions.migrations definition
+      CREATE TABLE supabase_functions.migrations (
+        version text PRIMARY KEY,
+        inserted_at timestamptz NOT NULL DEFAULT NOW()
+      );
+      -- Initial supabase_functions migration
+      INSERT INTO supabase_functions.migrations (version) VALUES ('initial');
+      -- supabase_functions.hooks definition
+      CREATE TABLE supabase_functions.hooks (
+        id bigserial PRIMARY KEY,
+        hook_table_id integer NOT NULL,
+        hook_name text NOT NULL,
+        created_at timestamptz NOT NULL DEFAULT NOW(),
+        request_id bigint
+      );
+      CREATE INDEX supabase_functions_hooks_request_id_idx ON supabase_functions.hooks USING btree (request_id);
+      CREATE INDEX supabase_functions_hooks_h_table_id_h_name_idx ON supabase_functions.hooks USING btree (hook_table_id, hook_name);
+      COMMENT ON TABLE supabase_functions.hooks IS 'Supabase Functions Hooks: Audit trail for triggered hooks.';
+      CREATE FUNCTION supabase_functions.http_request()
+        RETURNS trigger
+        LANGUAGE plpgsql
+        AS $function$
+        DECLARE
+          request_id bigint;
+          payload jsonb;
+          url text := TG_ARGV[0]::text;
+          method text := TG_ARGV[1]::text;
+          headers jsonb DEFAULT '{}'::jsonb;
+          params jsonb DEFAULT '{}'::jsonb;
+          timeout_ms integer DEFAULT 1000;
+        BEGIN
+          IF url IS NULL OR url = 'null' THEN
+            RAISE EXCEPTION 'url argument is missing';
+          END IF;
+    
+          IF method IS NULL OR method = 'null' THEN
+            RAISE EXCEPTION 'method argument is missing';
+          END IF;
+    
+          IF TG_ARGV[2] IS NULL OR TG_ARGV[2] = 'null' THEN
+            headers = '{"Content-Type": "application/json"}'::jsonb;
+          ELSE
+            headers = TG_ARGV[2]::jsonb;
+          END IF;
+    
+          IF TG_ARGV[3] IS NULL OR TG_ARGV[3] = 'null' THEN
+            params = '{}'::jsonb;
+          ELSE
+            params = TG_ARGV[3]::jsonb;
+          END IF;
+    
+          IF TG_ARGV[4] IS NULL OR TG_ARGV[4] = 'null' THEN
+            timeout_ms = 1000;
+          ELSE
+            timeout_ms = TG_ARGV[4]::integer;
+          END IF;
+    
+          CASE
+            WHEN method = 'GET' THEN
+              SELECT http_get INTO request_id FROM net.http_get(
+                url,
+                params,
+                headers,
+                timeout_ms
+              );
+            WHEN method = 'POST' THEN
+              payload = jsonb_build_object(
+                'old_record', OLD,
+                'record', NEW,
+                'type', TG_OP,
+                'table', TG_TABLE_NAME,
+                'schema', TG_TABLE_SCHEMA
+              );
+    
+              SELECT http_post INTO request_id FROM net.http_post(
+                url,
+                payload,
+                params,
+                headers,
+                timeout_ms
+              );
+            ELSE
+              RAISE EXCEPTION 'method argument % is invalid', method;
+          END CASE;
+    
+          INSERT INTO supabase_functions.hooks
+            (hook_table_id, hook_name, request_id)
+          VALUES
+            (TG_RELID, TG_NAME, request_id);
+    
+          RETURN NEW;
+        END
+      $function$;
+      -- Supabase super admin
+      DO
+      $$
+      BEGIN
+        IF NOT EXISTS (
+          SELECT 1
+          FROM pg_roles
+          WHERE rolname = 'supabase_functions_admin'
+        )
+        THEN
+          CREATE USER supabase_functions_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION;
+        END IF;
+      END
+      $$;
+      GRANT ALL PRIVILEGES ON SCHEMA supabase_functions TO supabase_functions_admin;
+      GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA supabase_functions TO supabase_functions_admin;
+      GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA supabase_functions TO supabase_functions_admin;
+      ALTER USER supabase_functions_admin SET search_path = "supabase_functions";
+      ALTER table "supabase_functions".migrations OWNER TO supabase_functions_admin;
+      ALTER table "supabase_functions".hooks OWNER TO supabase_functions_admin;
+      ALTER function "supabase_functions".http_request() OWNER TO supabase_functions_admin;
+      GRANT supabase_functions_admin TO postgres;
+      -- Remove unused supabase_pg_net_admin role
+      DO
+      $$
+      BEGIN
+        IF EXISTS (
+          SELECT 1
+          FROM pg_roles
+          WHERE rolname = 'supabase_pg_net_admin'
+        )
+        THEN
+          REASSIGN OWNED BY supabase_pg_net_admin TO supabase_admin;
+          DROP OWNED BY supabase_pg_net_admin;
+          DROP ROLE supabase_pg_net_admin;
+        END IF;
+      END
+      $$;
+      -- pg_net grants when extension is already enabled
+      DO
+      $$
+      BEGIN
+        IF EXISTS (
+          SELECT 1
+          FROM pg_extension
+          WHERE extname = 'pg_net'
+        )
+        THEN
+          GRANT USAGE ON SCHEMA net TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+          ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER;
+          ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER;
+          ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net;
+          ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net;
+          REVOKE ALL ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC;
+          REVOKE ALL ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC;
+          GRANT EXECUTE ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+          GRANT EXECUTE ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+        END IF;
+      END
+      $$;
+      -- Event trigger for pg_net
+      CREATE OR REPLACE FUNCTION extensions.grant_pg_net_access()
+      RETURNS event_trigger
+      LANGUAGE plpgsql
+      AS $$
+      BEGIN
+        IF EXISTS (
+          SELECT 1
+          FROM pg_event_trigger_ddl_commands() AS ev
+          JOIN pg_extension AS ext
+          ON ev.objid = ext.oid
+          WHERE ext.extname = 'pg_net'
+        )
+        THEN
+          GRANT USAGE ON SCHEMA net TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+          ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER;
+          ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER;
+          ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net;
+          ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net;
+          REVOKE ALL ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC;
+          REVOKE ALL ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC;
+          GRANT EXECUTE ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+          GRANT EXECUTE ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role;
+        END IF;
+      END;
+      $$;
+      COMMENT ON FUNCTION extensions.grant_pg_net_access IS 'Grants access to pg_net';
+      DO
+      $$
+      BEGIN
+        IF NOT EXISTS (
+          SELECT 1
+          FROM pg_event_trigger
+          WHERE evtname = 'issue_pg_net_access'
+        ) THEN
+          CREATE EVENT TRIGGER issue_pg_net_access ON ddl_command_end WHEN TAG IN ('CREATE EXTENSION')
+          EXECUTE PROCEDURE extensions.grant_pg_net_access();
+        END IF;
+      END
+      $$;
+      INSERT INTO supabase_functions.migrations (version) VALUES ('20210809183423_update_grants');
+      ALTER function supabase_functions.http_request() SECURITY DEFINER;
+      ALTER function supabase_functions.http_request() SET search_path = supabase_functions;
+      REVOKE ALL ON FUNCTION supabase_functions.http_request() FROM PUBLIC;
+      GRANT EXECUTE ON FUNCTION supabase_functions.http_request() TO postgres, anon, authenticated, service_role;
+    COMMIT;
 {{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/db/config.yaml b/charts/supabase/templates/db/migration.config.yaml
similarity index 58%
rename from charts/supabase/templates/db/config.yaml
rename to charts/supabase/templates/db/migration.config.yaml
index 7a7a34baa34d7d3b06bd7ca1829522e488dae3b3..77acec568c7502c56e40a5939758bdf9d8a0059a 100644
--- a/charts/supabase/templates/db/config.yaml
+++ b/charts/supabase/templates/db/migration.config.yaml
@@ -1,10 +1,10 @@
 {{- if .Values.db.enabled -}}
-apiVersion: v1
 kind: ConfigMap
+apiVersion: v1
 metadata:
-  name: {{ include "supabase.db.fullname" . }}
+  name: {{ include "supabase.db.fullname" . }}-migrations
   labels:
     {{- include "supabase.labels" . | nindent 4 }}
 data:
-  {{- toYaml .Values.db.environment | nindent 2 }}
+  {{- toYaml .Values.db.config | nindent 2 }}
 {{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/db/storage.yaml b/charts/supabase/templates/db/storage.yaml
deleted file mode 100644
index 28ad48f0d003563e66441d67bec6d1e81d41425a..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/db/storage.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-{{- if .Values.db.persistence.enabled -}}
-kind: PersistentVolumeClaim
-apiVersion: v1
-metadata:
-  name: {{ include "supabase.db.fullname" . }}-pvc
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.db.storage.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  storageClassName: {{ .Values.db.storage.storageClass }}
-  accessModes:
-  - ReadWriteOnce
-  resources:
-    requests:
-      storage: {{ .Values.db.storage.size }}
-{{- end }}
-
-
diff --git a/charts/supabase/templates/db/volume.yaml b/charts/supabase/templates/db/volume.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a02bc337b81f4144b6e53882d6dc77797d3ebcd9
--- /dev/null
+++ b/charts/supabase/templates/db/volume.yaml
@@ -0,0 +1,25 @@
+{{- if .Values.db.enabled -}}
+{{- if .Values.db.persistence.enabled -}}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: {{ include "supabase.db.fullname" . }}-pvc
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.db.persistence.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+  {{- if .Values.db.persistence.storageClassName }}
+  storageClassName: {{ .Values.db.persistence.storageClassName }}
+  {{- end }}
+  accessModes:
+  {{- range .Values.db.persistence.accessModes }}
+    - {{ . | quote }}
+  {{- end }}
+  resources:
+    requests:
+      storage: {{ .Values.db.persistence.size | quote }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/functions/_helpers.tpl b/charts/supabase/templates/functions/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..10e6bea23d16c7b9df6e2763972c6cac6b5119ec
--- /dev/null
+++ b/charts/supabase/templates/functions/_helpers.tpl
@@ -0,0 +1,43 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "supabase.functions.name" -}}
+{{- default (print .Chart.Name "-functions") .Values.functions.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "supabase.functions.fullname" -}}
+{{- if .Values.functions.fullnameOverride }}
+{{- .Values.functions.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default (print .Chart.Name "-functions") .Values.functions.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "supabase.functions.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "supabase.functions.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "supabase.functions.serviceAccountName" -}}
+{{- if .Values.functions.serviceAccount.create }}
+{{- default (include "supabase.functions.fullname" .) .Values.functions.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.functions.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/functions/deployment.yaml b/charts/supabase/templates/functions/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3bf7a7d9ecfa0641a5c5664b5b97209b4e078621
--- /dev/null
+++ b/charts/supabase/templates/functions/deployment.yaml
@@ -0,0 +1,121 @@
+{{- if .Values.functions.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "supabase.functions.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  {{- if not .Values.functions.autoscaling.enabled }}
+  replicas: {{ .Values.functions.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "supabase.functions.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.functions.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "supabase.functions.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.functions.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "supabase.functions.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.functions.podSecurityContext | nindent 8 }}
+      containers:
+        - args:
+            - start
+            - --main-service
+            - /home/deno/functions/main
+          name: {{ include "supabase.functions.name" $ }}
+          securityContext:
+            {{- toYaml .Values.functions.securityContext | nindent 12 }}
+          image: "{{ .Values.functions.image.repository }}:{{ .Values.functions.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.functions.image.pullPolicy }}
+          env:
+            {{- range $key, $value := .Values.functions.environment }}
+            - name: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            - name: DB_HOSTNAME
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . }}
+              {{- else }}
+              value: $(DB_HOST)
+              {{- end }}
+            - name: DB_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password
+            - name: DB_PASSWORD_ENC
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password_encoded
+            - name: DB_DATABASE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
+            - name: JWT_SECRET
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.jwt" . }}
+                  key: secret
+            - name: SUPABASE_ANON_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.jwt" . }}
+                  key: anonKey
+            - name: SUPABASE_SERVICE_ROLE_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.jwt" . }}
+                  key: serviceKey
+            - name: POSTGRES_BACKEND_URL
+              value: $(DB_DRIVER)://$(DB_USERNAME):$(DB_PASSWORD_ENC)@$(DB_HOSTNAME):$(DB_PORT)/$(DB_DATABASE)?search_path=auth&sslmode=$(DB_SSL)
+          {{- with .Values.functions.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.functions.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          volumeMounts:
+            {{- with .Values.functions.volumeMounts }}
+              {{- toYaml . | nindent 12 }}
+            {{- end }}
+            - mountPath: /home/deno/functions/main
+              name: functions-main
+          {{- with .Values.functions.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+      volumes:
+        {{- with .Values.functions.volumes }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+        - name: functions-main
+          configMap:
+            name: {{ include "supabase.functions.fullname" . }}-main
+      {{- with .Values.functions.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.functions.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.functions.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/functions/functions.config.yaml b/charts/supabase/templates/functions/functions.config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8aed927d64ea220ebdc4a526839afc9b80597e00
--- /dev/null
+++ b/charts/supabase/templates/functions/functions.config.yaml
@@ -0,0 +1,104 @@
+{{- if .Values.functions.enabled -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "supabase.functions.fullname" . }}-main
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+data:
+  index.ts: |
+    import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
+    import * as jose from 'https://deno.land/x/jose@v4.14.4/index.ts'
+
+    console.log('main function started')
+
+    const JWT_SECRET = Deno.env.get('JWT_SECRET')
+    const VERIFY_JWT = Deno.env.get('VERIFY_JWT') === 'true'
+
+    function getAuthToken(req: Request) {
+      const authHeader = req.headers.get('authorization')
+      if (!authHeader) {
+        throw new Error('Missing authorization header')
+      }
+      const [bearer, token] = authHeader.split(' ')
+      if (bearer !== 'Bearer') {
+        throw new Error(`Auth header is not 'Bearer {token}'`)
+      }
+      return token
+    }
+
+    async function verifyJWT(jwt: string): Promise<boolean> {
+      const encoder = new TextEncoder()
+      const secretKey = encoder.encode(JWT_SECRET)
+      try {
+        await jose.jwtVerify(jwt, secretKey)
+      } catch (err) {
+        console.error(err)
+        return false
+      }
+      return true
+    }
+
+    serve(async (req: Request) => {
+      if (req.method !== 'OPTIONS' && VERIFY_JWT) {
+        try {
+          const token = getAuthToken(req)
+          const isValidJWT = await verifyJWT(token)
+
+          if (!isValidJWT) {
+            return new Response(JSON.stringify({ msg: 'Invalid JWT' }), {
+              status: 401,
+              headers: { 'Content-Type': 'application/json' },
+            })
+          }
+        } catch (e) {
+          console.error(e)
+          return new Response(JSON.stringify({ msg: e.toString() }), {
+            status: 401,
+            headers: { 'Content-Type': 'application/json' },
+          })
+        }
+      }
+
+      const url = new URL(req.url)
+      const { pathname } = url
+      const path_parts = pathname.split('/')
+      const service_name = path_parts[1]
+
+      if (!service_name || service_name === '') {
+        const error = { msg: 'missing function name in request' }
+        return new Response(JSON.stringify(error), {
+          status: 400,
+          headers: { 'Content-Type': 'application/json' },
+        })
+      }
+
+      const servicePath = `/home/deno/functions/${service_name}`
+      console.error(`serving the request with ${servicePath}`)
+
+      const memoryLimitMb = 150
+      const workerTimeoutMs = 1 * 60 * 1000
+      const noModuleCache = false
+      const importMapPath = null
+      const envVarsObj = Deno.env.toObject()
+      const envVars = Object.keys(envVarsObj).map((k) => [k, envVarsObj[k]])
+
+      try {
+        const worker = await EdgeRuntime.userWorkers.create({
+          servicePath,
+          memoryLimitMb,
+          workerTimeoutMs,
+          noModuleCache,
+          importMapPath,
+          envVars,
+        })
+        return await worker.fetch(req)
+      } catch (e) {
+        const error = { msg: e.toString() }
+        return new Response(JSON.stringify(error), {
+          status: 500,
+          headers: { 'Content-Type': 'application/json' },
+        })
+      }
+    })
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/functions/service.yaml b/charts/supabase/templates/functions/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f70f1e8d4a200b8241cb2afde064f35952c3d83e
--- /dev/null
+++ b/charts/supabase/templates/functions/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.functions.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "supabase.functions.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.functions.service.type }}
+  ports:
+    - port: {{ .Values.functions.service.port }}
+      targetPort: 9000
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "supabase.functions.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/functions/serviceaccount.yaml b/charts/supabase/templates/functions/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f8e60abf460296153626965678e37994db65777d
--- /dev/null
+++ b/charts/supabase/templates/functions/serviceaccount.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.functions.enabled -}}
+{{- if .Values.functions.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "supabase.functions.serviceAccountName" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.functions.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/imgproxy/_helpers.tpl b/charts/supabase/templates/imgproxy/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..c37ad0264427ac80118206da760829e20f57eda0
--- /dev/null
+++ b/charts/supabase/templates/imgproxy/_helpers.tpl
@@ -0,0 +1,43 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "supabase.imgproxy.name" -}}
+{{- default (print .Chart.Name "-imgproxy") .Values.imgproxy.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "supabase.imgproxy.fullname" -}}
+{{- if .Values.imgproxy.fullnameOverride }}
+{{- .Values.imgproxy.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default (print .Chart.Name "-imgproxy") .Values.imgproxy.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "supabase.imgproxy.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "supabase.imgproxy.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "supabase.imgproxy.serviceAccountName" -}}
+{{- if .Values.imgproxy.serviceAccount.create }}
+{{- default (include "supabase.imgproxy.fullname" .) .Values.imgproxy.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.imgproxy.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/imgproxy/deployment.yaml b/charts/supabase/templates/imgproxy/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ad89b030963b96c575a3db119e7d6c69b54f33ea
--- /dev/null
+++ b/charts/supabase/templates/imgproxy/deployment.yaml
@@ -0,0 +1,91 @@
+{{- if .Values.imgproxy.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "supabase.imgproxy.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  {{- if not .Values.imgproxy.autoscaling.enabled }}
+  replicas: {{ .Values.imgproxy.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "supabase.imgproxy.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.imgproxy.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "supabase.imgproxy.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.imgproxy.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "supabase.imgproxy.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.imgproxy.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ include "supabase.imgproxy.name" $ }}
+          securityContext:
+            {{- toYaml .Values.imgproxy.securityContext | nindent 12 }}
+          image: "{{ .Values.imgproxy.image.repository }}:{{ .Values.imgproxy.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.imgproxy.image.pullPolicy }}
+          env:
+            {{- range $key, $value := .Values.imgproxy.environment }}
+            - name: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+          {{- with .Values.imgproxy.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.imgproxy.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+          {{- if or (.Values.imgproxy.persistence.enabled) (.Values.imgproxy.volumes) }}
+          volumeMounts:
+            {{- with .Values.imgproxy.volumeMounts }}
+              {{- toYaml . | nindent 12 }}
+            {{- end }}
+            {{- if .Values.imgproxy.persistence.enabled }}
+            - mountPath: /var/lib/storage
+              name: imgproxy-volume
+            {{- end }}
+          {{- end }}
+          {{- with .Values.imgproxy.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+      {{- if or (.Values.imgproxy.persistence.enabled) (.Values.imgproxy.volumes) }}
+      volumes:
+        {{- with .Values.imgproxy.volumes }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+        {{- if .Values.imgproxy.persistence.enabled }}
+        - name: imgproxy-volume
+          persistentVolumeClaim:
+            claimName: {{ include "supabase.imgproxy.fullname" . }}-pvc
+        {{- end }}
+      {{- end }}
+      {{- with .Values.imgproxy.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.imgproxy.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.imgproxy.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/imgproxy/service.yaml b/charts/supabase/templates/imgproxy/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..109f3d59d4469875f8f7904a11eba7fd6e93c88f
--- /dev/null
+++ b/charts/supabase/templates/imgproxy/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.imgproxy.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "supabase.imgproxy.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.imgproxy.service.type }}
+  ports:
+    - port: {{ .Values.imgproxy.service.port }}
+      targetPort: 5001
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "supabase.imgproxy.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/imgproxy/serviceaccount.yaml b/charts/supabase/templates/imgproxy/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..04e62b9b809a2126820fa240f9d335b7346ac25b
--- /dev/null
+++ b/charts/supabase/templates/imgproxy/serviceaccount.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.imgproxy.enabled -}}
+{{- if .Values.imgproxy.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "supabase.imgproxy.serviceAccountName" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.imgproxy.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/imgproxy/volume.yaml b/charts/supabase/templates/imgproxy/volume.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..34204bd04b40afded542a10e8680660048848969
--- /dev/null
+++ b/charts/supabase/templates/imgproxy/volume.yaml
@@ -0,0 +1,25 @@
+{{- if .Values.imgproxy.enabled -}}
+{{- if .Values.imgproxy.persistence.enabled -}}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: {{ include "supabase.imgproxy.fullname" . }}-pvc
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.imgproxy.persistence.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+  {{- if .Values.imgproxy.persistence.storageClassName }}
+  storageClassName: {{ .Values.imgproxy.persistence.storageClassName }}
+  {{- end }}
+  accessModes:
+  {{- range .Values.imgproxy.persistence.accessModes }}
+    - {{ . | quote }}
+  {{- end }}
+  resources:
+    requests:
+      storage: {{ .Values.imgproxy.persistence.size | quote }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/kong/config.yaml b/charts/supabase/templates/kong/config.yaml
index fc4f22fc4fa5477ca4fa897dbab86931f97e7af2..2edd25af6fcdf3100b94e97034b850a9c4c90d86 100644
--- a/charts/supabase/templates/kong/config.yaml
+++ b/charts/supabase/templates/kong/config.yaml
@@ -6,45 +6,51 @@ metadata:
   labels:
     {{- include "supabase.labels" . | nindent 4 }}
 data:
-  {{- toYaml .Values.kong.environment | nindent 2 }}
   wrapper.sh: |
-    #!/bin/sh
+    #!/bin/bash
 
     set -euo pipefail
 
-    echo "Replacing env placeholders of /home/kong/kong.yml"
+    echo "Replacing env placeholders of /usr/local/kong/kong.yml"
 
     sed \
     -e "s/\${SUPABASE_ANON_KEY}/${SUPABASE_ANON_KEY}/" \
     -e "s/\${SUPABASE_SERVICE_KEY}/${SUPABASE_SERVICE_KEY}/" \
-    /home/kong/template.yml \
-    > /home/kong/kong.yml
+    -e "s/\${DASHBOARD_USERNAME}/${DASHBOARD_USERNAME}/" \
+    -e "s/\${DASHBOARD_PASSWORD}/${DASHBOARD_PASSWORD}/" \
+    /usr/local/kong/template.yml \
+    > /usr/local/kong/kong.yml
 
     exec /docker-entrypoint.sh kong docker-start
-{{- if .Values.kong.config -}}
-  template.yml:
-  {{- toYaml .Values.kong.config | nindent 4 }}
-{{- else }}
   template.yml: |
-    _format_version: "1.1"
+    _format_version: '2.1'
+    _transform: true
 
     consumers:
+    {{- if .Values.secret.dashboard }}
+      - username: DASHBOARD
+    {{- end }}
       - username: anon
         keyauth_credentials:
             - key: ${SUPABASE_ANON_KEY}
       - username: service_role
         keyauth_credentials:
             - key: ${SUPABASE_SERVICE_KEY}
-
     acls:
       - consumer: anon
         group: anon
       - consumer: service_role
         group: admin
-
+    {{- if .Values.secret.dashboard }}
+    basicauth_credentials:
+      - consumer: DASHBOARD
+        username: ${DASHBOARD_USERNAME}
+        password: ${DASHBOARD_PASSWORD}
+    {{- end }}
     services:
+    {{- if .Values.auth.enabled }}
       - name: auth-v1-open
-        url: http://{{ include "supabase.auth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:9999/verify
+        url: http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}/verify
         routes:
           - name: auth-v1-open
             strip_path: true
@@ -53,7 +59,7 @@ data:
         plugins:
           - name: cors
       - name: auth-v1-open-callback
-        url: http://{{ include "supabase.auth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:9999/callback
+        url: http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}/callback
         routes:
           - name: auth-v1-open-callback
             strip_path: true
@@ -62,7 +68,7 @@ data:
         plugins:
           - name: cors
       - name: auth-v1-open-authorize
-        url: http://{{ include "supabase.auth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:9999/authorize
+        url: http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}/authorize
         routes:
           - name: auth-v1-open-authorize
             strip_path: true
@@ -70,11 +76,9 @@ data:
               - /auth/v1/authorize
         plugins:
           - name: cors
-
-
       - name: auth-v1
-        _comment: "GoTrue: /auth/v1/* -> http://{{ include "supabase.auth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:9999/*"
-        url: http://{{ include "supabase.auth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:9999
+        _comment: "GoTrue: /auth/v1/* -> http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}/*"
+        url: http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}
         routes:
           - name: auth-v1-all
             strip_path: true
@@ -91,11 +95,11 @@ data:
               allow:
                 - admin
                 - anon
-
-
+    {{- end }}
+    {{- if .Values.rest.enabled }}
       - name: rest-v1
-        _comment: "PostgREST: /rest/v1/* -> http://{{ include "supabase.rest.fullname" . }}.{{ .Release.Namespace }}:3000/*"
-        url: http://{{ include "supabase.rest.fullname" . }}.{{ .Release.Namespace }}:3000/
+        _comment: "PostgREST: /rest/v1/* -> http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}/*"
+        url: http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}/
         routes:
           - name: rest-v1-all
             strip_path: true
@@ -112,10 +116,35 @@ data:
               allow:
                 - admin
                 - anon
-
+      - name: graphql-v1
+        _comment: 'PostgREST: /graphql/v1/* -> http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}/rpc/graphql'
+        url: http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}/rpc/graphql
+        routes:
+          - name: graphql-v1-all
+            strip_path: true
+            paths:
+              - /graphql/v1
+        plugins:
+          - name: cors
+          - name: key-auth
+            config:
+              hide_credentials: true
+          - name: request-transformer
+            config:
+              add:
+                headers:
+                  - Content-Profile:graphql_public
+          - name: acl
+            config:
+              hide_groups_header: true
+              allow:
+                - admin
+                - anon
+    {{- end }}
+    {{- if .Values.realtime.enabled }}
       - name: realtime-v1
-        _comment: "Realtime: /realtime/v1/* -> ws://{{ include "supabase.realtime.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:4000/socket/*"
-        url: http://{{ include "supabase.realtime.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:4000/socket
+        _comment: "Realtime: /realtime/v1/* -> ws://{{ include "supabase.realtime.fullname" . }}:{{ .Values.realtime.service.port }}/socket/*"
+        url: http://{{ include "supabase.realtime.fullname" . }}:{{ .Values.realtime.service.port }}/socket
         routes:
           - name: realtime-v1-all
             strip_path: true
@@ -132,10 +161,11 @@ data:
               allow:
                 - admin
                 - anon
-
+    {{- end }}
+    {{- if .Values.storage.enabled }}
       - name: storage-v1
-        _comment: "Storage: /storage/v1/* -> http://{{ include "supabase.storage.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:5000/*"
-        url: http://{{ include "supabase.storage.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:5000/
+        _comment: "Storage: /storage/v1/* -> http://{{ include "supabase.storage.fullname" . }}:{{ .Values.storage.service.port }}/*"
+        url: http://{{ include "supabase.storage.fullname" . }}:{{ .Values.storage.service.port }}/
         routes:
           - name: storage-v1-all
             strip_path: true
@@ -143,10 +173,33 @@ data:
               - /storage/v1/
         plugins:
           - name: cors
-
+    {{- end }}
+    {{- if .Values.functions.enabled }}
+      - name: functions-v1
+        _comment: 'Edge Functions: /functions/v1/* -> http://{{ include "supabase.functions.fullname" . }}:{{ .Values.functions.service.port }}/*'
+        url: http://functions:{{ .Values.functions.service.port }}/
+        routes:
+          - name: functions-v1-all
+            strip_path: true
+            paths:
+              - /functions/v1/
+        plugins:
+          - name: cors
+    {{- end }}
+    {{- if .Values.analytics.enabled }}
+      - name: analytics-v1
+        _comment: 'Analytics: /analytics/v1/* -> http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/*'
+        url: http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/
+        routes:
+          - name: analytics-v1-all
+            strip_path: true
+            paths:
+              - /analytics/v1/
+    {{- end }}
+    {{- if .Values.meta.enabled }}
       - name: meta
-        _comment: "pg-meta: /pg/* -> http://{{ include "supabase.meta.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:8080/*"
-        url: http://{{ include "supabase.meta.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:8080/
+        _comment: "pg-meta: /pg/* -> http://{{ include "supabase.meta.fullname" . }}:{{ .Values.meta.service.port }}/*"
+        url: http://{{ include "supabase.meta.fullname" . }}:{{ .Values.meta.service.port }}/
         routes:
           - name: meta-all
             strip_path: true
@@ -161,5 +214,20 @@ data:
               hide_groups_header: true
               allow:
                 - admin
-{{- end }}
+    {{- end }}
+      - name: dashboard
+        _comment: 'Studio: /* -> http://{{ include "supabase.studio.fullname" . }}:{{ .Values.studio.service.port }}/*'
+        url: http://{{ include "supabase.studio.fullname" . }}:{{ .Values.studio.service.port }}/
+        routes:
+          - name: dashboard-all
+            strip_path: true
+            paths:
+              - /
+    {{- if .Values.secret.dashboard }}
+        plugins:
+          - name: cors
+          - name: basic-auth
+            config:
+              hide_credentials: true
+    {{- end }}
 {{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/kong/deployment.yaml b/charts/supabase/templates/kong/deployment.yaml
index 4981bddc5394e294d69c1b475b3aaab6fe9b208a..173c470daceba5cf5fc0b807fc87cb830d43f13f 100644
--- a/charts/supabase/templates/kong/deployment.yaml
+++ b/charts/supabase/templates/kong/deployment.yaml
@@ -34,26 +34,43 @@ spec:
             {{- toYaml .Values.kong.securityContext | nindent 12 }}
           image: "{{ .Values.kong.image.repository }}:{{ .Values.kong.image.tag | default .Chart.AppVersion }}"
           imagePullPolicy: {{ .Values.kong.image.pullPolicy }}
-          command: ["/bin/sh"]
+          command: ["/bin/bash"]
           args: ["/scripts/wrapper.sh"]
           env:
             {{- range $key, $value := .Values.kong.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.kong.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
             {{- end }}
             - name: SUPABASE_ANON_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: anonKey
             - name: SUPABASE_SERVICE_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: serviceKey
+            {{- if .Values.secret.dashboard }}
+            - name: DASHBOARD_USERNAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.dashboard" . }}
+                  key: username
+            - name: DASHBOARD_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.dashboard" . }}
+                  key: password
+            {{- end }}
+          {{- with .Values.kong.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.kong.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 8000
@@ -63,7 +80,7 @@ spec:
             {{- toYaml . | nindent 12 }}
           {{- end }}
           volumeMounts:
-            - mountPath: /home/kong/template.yml
+            - mountPath: /usr/local/kong/template.yml
               name: config
               subPath: template.yml
             - mountPath: /scripts
diff --git a/charts/supabase/templates/meta/config.yaml b/charts/supabase/templates/meta/config.yaml
deleted file mode 100644
index 9ae5c986c14531d5143446d863f3de174ab68d9a..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/meta/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.meta.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.meta.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.meta.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/meta/deployment.yaml b/charts/supabase/templates/meta/deployment.yaml
index 7d9f47ff1e4d33933511b91ee87a130cd4405fb2..254371a5b33139da3ac5ca4d0e35593a9673a595 100644
--- a/charts/supabase/templates/meta/deployment.yaml
+++ b/charts/supabase/templates/meta/deployment.yaml
@@ -37,21 +37,22 @@ spec:
           env:
             {{- range $key, $value := .Values.meta.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.meta.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOST
+              value: {{ include "supabase.db.fullname" . }}
             {{- end }}
-            - name: DB_USER
-              valueFrom:
-                secretKeyRef:
-                  name: {{ .Values.db.secretName }}
-                  key: username
             - name: DB_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: DB_NAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
             - name: PG_META_DB_HOST
               value: $(DB_HOST)
             - name: PG_META_DB_PORT
@@ -64,6 +65,14 @@ spec:
               value: $(DB_PASSWORD)
             - name: PG_META_DB_SSL_MODE
               value: $(DB_SSL)
+          {{- with .Values.meta.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.meta.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 8080
diff --git a/charts/supabase/templates/meta/ingress.yaml b/charts/supabase/templates/meta/ingress.yaml
deleted file mode 100644
index 5253db292bf201bf3f6148c55874d0307ceb710b..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/meta/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.meta.enabled -}}
-{{- if .Values.meta.ingress.enabled -}}
-{{- $fullName := include "supabase.meta.fullname" . -}}
-{{- $svcPort := .Values.meta.service.port -}}
-{{- if and .Values.meta.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.meta.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.meta.ingress.annotations "kubernetes.io/ingress.class" .Values.meta.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.meta.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.meta.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.meta.ingress.className }}
-  {{- end }}
-  {{- if .Values.meta.ingress.tls }}
-  tls:
-    {{- range .Values.meta.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.meta.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/minio/_helpers.tpl b/charts/supabase/templates/minio/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..241d041ecdef904eef48fa205405ec3067b2a0ea
--- /dev/null
+++ b/charts/supabase/templates/minio/_helpers.tpl
@@ -0,0 +1,43 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "supabase.minio.name" -}}
+{{- default (print .Chart.Name "-minio") .Values.minio.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "supabase.minio.fullname" -}}
+{{- if .Values.minio.fullnameOverride }}
+{{- .Values.minio.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default (print .Chart.Name "-minio") .Values.minio.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "supabase.minio.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "supabase.minio.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "supabase.minio.serviceAccountName" -}}
+{{- if .Values.minio.serviceAccount.create }}
+{{- default (include "supabase.minio.fullname" .) .Values.minio.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.minio.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/minio/deployment.yaml b/charts/supabase/templates/minio/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dc97073d282913a6821ce8dc254281c91d88c013
--- /dev/null
+++ b/charts/supabase/templates/minio/deployment.yaml
@@ -0,0 +1,100 @@
+{{- if .Values.minio.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "supabase.minio.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  {{- if not .Values.minio.autoscaling.enabled }}
+  replicas: {{ .Values.minio.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "supabase.minio.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.minio.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "supabase.minio.selectorLabels" . | nindent 8 }}
+    spec:
+      restartPolicy: Always
+      {{- with .Values.minio.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "supabase.minio.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.minio.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ include "supabase.minio.name" $ }}
+          securityContext:
+            {{- toYaml .Values.minio.securityContext | nindent 12 }}
+          image: "{{ .Values.minio.image.repository }}:{{ .Values.minio.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.minio.image.pullPolicy }}
+          args:
+            - server
+            - --console-address
+            - ":9001"
+            - /data
+          env:
+            - name: MINIO_ROOT_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: keyId
+            - name: MINIO_ROOT_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: accessKey
+          {{- with .Values.minio.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.minio.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          ports:
+            - name: http
+              containerPort: 9000
+              protocol: TCP
+          {{- with .Values.minio.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          volumeMounts:
+          {{- with .Values.minio.volumeMounts }}
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+            - mountPath: /data
+              name: minio-data
+      {{- with .Values.minio.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.minio.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.minio.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      volumes:
+        - name: minio-data
+          {{- if .Values.minio.persistence.enabled }}
+          persistentVolumeClaim:
+            claimName: {{ include "supabase.minio.fullname" . }}-pvc
+          {{- else }}
+          emptyDir:
+            medium: ""
+          {{- end }}
+        {{- with .Values.minio.volumes }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/minio/service.yaml b/charts/supabase/templates/minio/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..30b6b1f6a02ce071b7d40c70b31b0bfa310fcf86
--- /dev/null
+++ b/charts/supabase/templates/minio/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.minio.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "supabase.minio.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.minio.service.type }}
+  ports:
+    - port: {{ .Values.minio.service.port }}
+      targetPort: 9000
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "supabase.minio.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/minio/serviceaccount.yaml b/charts/supabase/templates/minio/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..84116a1c194ad623aa99c76e75e10d9cbdca43fb
--- /dev/null
+++ b/charts/supabase/templates/minio/serviceaccount.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.minio.enabled -}}
+{{- if .Values.minio.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "supabase.minio.serviceAccountName" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.minio.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/minio/volume.yaml b/charts/supabase/templates/minio/volume.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..26e3e66d806b56e63981dc98c5006e9871ce5bea
--- /dev/null
+++ b/charts/supabase/templates/minio/volume.yaml
@@ -0,0 +1,25 @@
+{{- if .Values.minio.enabled -}}
+{{- if .Values.minio.persistence.enabled -}}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: {{ include "supabase.minio.fullname" . }}-pvc
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.minio.persistence.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+  {{- if .Values.minio.persistence.minioClassName }}
+  minioClassName: {{ .Values.minio.persistence.minioClassName }}
+  {{- end }}
+  accessModes:
+  {{- range .Values.minio.persistence.accessModes }}
+    - {{ . | quote }}
+  {{- end }}
+  resources:
+    requests:
+      storage: {{ .Values.minio.persistence.size | quote }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/realtime/config.yaml b/charts/supabase/templates/realtime/config.yaml
deleted file mode 100644
index 1ce92f8d6ac221093e06ad7ed7616296ddd2d7c0..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/realtime/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.realtime.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.realtime.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.realtime.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/realtime/deployment.yaml b/charts/supabase/templates/realtime/deployment.yaml
index cf4b301a647aaa366e989ed5c2ba1b730a53b4a3..dcc0c043297b5c92f7fdb762f7e1dd50ef4520d7 100644
--- a/charts/supabase/templates/realtime/deployment.yaml
+++ b/charts/supabase/templates/realtime/deployment.yaml
@@ -34,14 +34,18 @@ spec:
           imagePullPolicy: IfNotPresent
           env:
             - name: DB_HOST
-              value: {{ .Values.realtime.environment.DB_HOST | quote }}
-            - name: DB_PORT
-              value: {{ .Values.realtime.environment.DB_PORT | quote }}
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . | quote }}
+              {{- else }}
+              value: {{ .Values.auth.environment.DB_HOST | quote }}
+              {{- end }}
             - name: DB_USER
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: username
+            - name: DB_PORT
+              value: {{ .Values.analytics.environment.DB_PORT | quote }}
           command: ["/bin/sh", "-c"]
           args:
             - |
@@ -61,31 +65,40 @@ spec:
           env:
             {{- range $key, $value := .Values.realtime.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.realtime.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOST
+              value: {{ include "supabase.db.fullname" . }}
             {{- end }}
-            - name: DB_USER
-              valueFrom:
-                secretKeyRef:
-                  name: {{ .Values.db.secretName }}
-                  key: username
             - name: DB_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: DB_NAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
             - name: JWT_SECRET
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: secret
             - name: API_JWT_SECRET
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: secret
+          {{- with .Values.realtime.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.realtime.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 4000
diff --git a/charts/supabase/templates/realtime/ingress.yaml b/charts/supabase/templates/realtime/ingress.yaml
deleted file mode 100644
index 416c484f2df43c97c77177fd3d50704dfa96e52d..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/realtime/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.realtime.enabled -}}
-{{- if .Values.realtime.ingress.enabled -}}
-{{- $fullName := include "supabase.realtime.fullname" . -}}
-{{- $svcPort := .Values.realtime.service.port -}}
-{{- if and .Values.realtime.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.realtime.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.realtime.ingress.annotations "kubernetes.io/ingress.class" .Values.realtime.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.realtime.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.realtime.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.realtime.ingress.className }}
-  {{- end }}
-  {{- if .Values.realtime.ingress.tls }}
-  tls:
-    {{- range .Values.realtime.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.realtime.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/rest/config.yaml b/charts/supabase/templates/rest/config.yaml
deleted file mode 100644
index acd847936e0f89f38a70a958fc808c77cc130e1a..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/rest/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.rest.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.rest.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.rest.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/rest/deployment.yaml b/charts/supabase/templates/rest/deployment.yaml
index f1980ef5feec9c96eb2ab369d5784757214977bf..226527ba9257f4e5d21a59a313f5a6dbeedc476c 100644
--- a/charts/supabase/templates/rest/deployment.yaml
+++ b/charts/supabase/templates/rest/deployment.yaml
@@ -37,28 +37,47 @@ spec:
           env:
             {{- range $key, $value := .Values.rest.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.rest.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOST
+              value: {{ include "supabase.db.fullname" . }}
             {{- end }}
-            - name: DB_USER
-              valueFrom:
-                secretKeyRef:
-                  name: {{ .Values.db.secretName }}
-                  key: username
             - name: DB_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: DB_PASSWORD_ENC
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password_encoded
+            - name: DB_NAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
             - name: PGRST_DB_URI
-              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(DB_SSL)
+              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD_ENC)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(DB_SSL)
             - name: PGRST_JWT_SECRET
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: secret
+            - name: JWT_EXPIRY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.jwt" . }}
+                  key: expiry
+          {{- with .Values.rest.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.rest.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 3000
diff --git a/charts/supabase/templates/rest/ingress.yaml b/charts/supabase/templates/rest/ingress.yaml
deleted file mode 100644
index 4ec5656454bedaa8f68084932ab34567c6594bea..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/rest/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.rest.enabled -}}
-{{- if .Values.rest.ingress.enabled -}}
-{{- $fullName := include "supabase.rest.fullname" . -}}
-{{- $svcPort := .Values.rest.service.port -}}
-{{- if and .Values.rest.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.rest.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.rest.ingress.annotations "kubernetes.io/ingress.class" .Values.rest.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.rest.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.rest.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.rest.ingress.className }}
-  {{- end }}
-  {{- if .Values.rest.ingress.tls }}
-  tls:
-    {{- range .Values.rest.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.rest.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/secrets/_helpers.tpl b/charts/supabase/templates/secrets/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..1b167a8ca7100ba45d3a04a9e1c6223468b8f681
--- /dev/null
+++ b/charts/supabase/templates/secrets/_helpers.tpl
@@ -0,0 +1,41 @@
+{{/*
+Expand the name of the JWT secret.
+*/}}
+{{- define "supabase.secret.jwt" -}}
+{{- printf "%s-jwt" (include "supabase.fullname" .) }}
+{{- end -}}
+
+{{/*
+Expand the name of the SMTP secret.
+*/}}
+{{- define "supabase.secret.smtp" -}}
+{{- printf "%s-smtp" (include "supabase.fullname" .) }}
+{{- end -}}
+
+{{/*
+Expand the name of the dashboard secret.
+*/}}
+{{- define "supabase.secret.dashboard" -}}
+{{- printf "%s-dashboard" (include "supabase.fullname" .) }}
+{{- end -}}
+
+{{/*
+Expand the name of the database secret.
+*/}}
+{{- define "supabase.secret.db" -}}
+{{- printf "%s-db" (include "supabase.fullname" .) }}
+{{- end -}}
+
+{{/*
+Expand the name of the analytics secret.
+*/}}
+{{- define "supabase.secret.analytics" -}}
+{{- printf "%s-analytics" (include "supabase.fullname" .) }}
+{{- end -}}
+
+{{/*
+Expand the name of the s3 secret.
+*/}}
+{{- define "supabase.secret.s3" -}}
+{{- printf "%s-s3" (include "supabase.fullname" .) }}
+{{- end -}}
diff --git a/charts/supabase/templates/secrets/analytics.yaml b/charts/supabase/templates/secrets/analytics.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..83e7b42090fe5c693d89dc16facb6c15f7ba01c4
--- /dev/null
+++ b/charts/supabase/templates/secrets/analytics.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.secret.analytics }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.analytics" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.analytics }}
+  {{ $key }}: {{ $value | b64enc }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/secrets/dashboard.yaml b/charts/supabase/templates/secrets/dashboard.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f81ef57b3cbe3f5390a8418b7a6a417f6a553343
--- /dev/null
+++ b/charts/supabase/templates/secrets/dashboard.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.secret.dashboard }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.dashboard" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.dashboard }}
+  {{ $key }}: {{ $value | b64enc }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/secrets/db.yaml b/charts/supabase/templates/secrets/db.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1a6a26e0ec25bc67e07bf9c9165d0361bcaf3823
--- /dev/null
+++ b/charts/supabase/templates/secrets/db.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.db" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.db }}
+  {{ $key }}: {{ $value | b64enc }}
+{{- end }}
+  password_encoded: {{ .Values.secret.db.password | urlquery | b64enc }}
diff --git a/charts/supabase/templates/secrets/jwt.yaml b/charts/supabase/templates/secrets/jwt.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5622d23243bc42a3536a95f236728f215793076a
--- /dev/null
+++ b/charts/supabase/templates/secrets/jwt.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.secret.jwt }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.jwt" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.jwt }}
+  {{ $key }}: {{ $value | toString | b64enc }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/secrets/s3.yaml b/charts/supabase/templates/secrets/s3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1752e65812036aebba7e0ead11a27aaf8979c6a8
--- /dev/null
+++ b/charts/supabase/templates/secrets/s3.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.secret.s3 }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.s3" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.s3 }}
+  {{ $key }}: {{ $value | toString | b64enc }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/secrets/smtp.yaml b/charts/supabase/templates/secrets/smtp.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..38b70b70878b6180df9ce993fb3876d7a27c5608
--- /dev/null
+++ b/charts/supabase/templates/secrets/smtp.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.secret.smtp }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "supabase.secret.smtp" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := .Values.secret.smtp }}
+  {{ $key }}: {{ $value | b64enc }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/storage/config.yaml b/charts/supabase/templates/storage/config.yaml
deleted file mode 100644
index d6b205467ad4b06096cd347a68bf0b1247ccee1e..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/storage/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.storage.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.storage.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.storage.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/storage/deployment.yaml b/charts/supabase/templates/storage/deployment.yaml
index 6fdea4df56bceba4e11c62f4d9de718e4eb943db..5fe6d5d134e18bf9e7ff146f3fff1c6b34944c8f 100644
--- a/charts/supabase/templates/storage/deployment.yaml
+++ b/charts/supabase/templates/storage/deployment.yaml
@@ -35,14 +35,18 @@ spec:
           imagePullPolicy: IfNotPresent
           env:
             - name: DB_HOST
-              value: {{ .Values.storage.environment.DB_HOST | quote }}
-            - name: DB_PORT
-              value: {{ .Values.storage.environment.DB_PORT | quote }}
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . | quote }}
+              {{- else }}
+              value: {{ .Values.auth.environment.DB_HOST | quote }}
+              {{- end }}
             - name: DB_USER
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: username
+            - name: DB_PORT
+              value: {{ .Values.analytics.environment.DB_PORT | quote }}
           command: ["/bin/sh", "-c"]
           args:
             - |
@@ -51,6 +55,31 @@ spec:
               sleep 2
               done
             - echo "Database is ready"
+        {{- if .Values.minio.enabled }}
+        - env:
+            - name: MINIO_ROOT_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: keyId
+            - name: MINIO_ROOT_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: accessKey
+          name: init-bucket
+          image: minio/mc
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/sh
+            - -c
+            - |
+              until /usr/bin/mc alias set supa-minio http://{{ include "supabase.minio.fullname" . }}:{{ .Values.minio.service.port }} $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD; do
+                echo "Waiting for minio to start..."
+                sleep 2
+              done
+              /usr/bin/mc mb --ignore-existing supa-minio/stub
+        {{- end }}
       containers:
         - name: {{ include "supabase.storage.name" $ }}
           securityContext:
@@ -60,38 +89,76 @@ spec:
           env:
             {{- range $key, $value := .Values.storage.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.storage.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.db.enabled }}
+            - name: DB_HOST
+              value: {{ include "supabase.db.fullname" . }}
+            {{- end }}
+            {{- if .Values.rest.enabled }}
+            - name: POSTGREST_URL
+              value: http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}
             {{- end }}
-            - name: DB_USER
-              valueFrom:
-                secretKeyRef:
-                  name: {{ .Values.db.secretName }}
-                  key: username
             - name: DB_PASSWORD
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.db.secretName }}
+                  name: {{ include "supabase.secret.db" . }}
                   key: password
+            - name: DB_PASSWORD_ENC
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: password_encoded
+            - name: DB_NAME
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: database
             - name: DATABASE_URL
-              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?search_path=auth&sslmode=$(DB_SSL)
+              value: $(DB_DRIVER)://$(DB_USER):$(DB_PASSWORD_ENC)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?search_path=auth&sslmode=$(DB_SSL)
             - name: PGRST_JWT_SECRET
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: secret
             - name: ANON_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: anonKey
             - name: SERVICE_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: serviceKey
+            {{- if .Values.imgproxy.enabled }}
+            - name: IMGPROXY_URL
+              value: http://{{ include "supabase.imgproxy.fullname" . }}:{{ .Values.imgproxy.service.port | int }}
+            {{- end }}
+            {{- if .Values.secret.s3 }}
+            - name: AWS_ACCESS_KEY_ID
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: keyId
+            - name: AWS_SECRET_ACCESS_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.s3" . }}
+                  key: accessKey
+            {{- end }}
+            {{- if .Values.minio.enabled }}
+            - name: GLOBAL_S3_ENDPOINT
+              value: http://{{ include "supabase.minio.fullname" . }}:{{ default 9000 .Values.minio.service.port }}
+            {{- end }}
+          {{- with .Values.storage.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.storage.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 5000
@@ -100,10 +167,12 @@ spec:
           resources:
             {{- toYaml . | nindent 12 }}
           {{- end }}
-          {{- with .Values.storage.volumeMounts }}
           volumeMounts:
+          {{- with .Values.storage.volumeMounts }}
             {{- toYaml . | nindent 12 }}
           {{- end }}
+            - mountPath: /var/lib/storage
+              name: storage-data
       {{- with .Values.storage.nodeSelector }}
       nodeSelector:
         {{- toYaml . | nindent 8 }}
@@ -117,11 +186,14 @@ spec:
         {{- toYaml . | nindent 8 }}
       {{- end }}
       volumes:
-        {{- if .Values.storage.persistence.enabled }}
         - name: storage-data
+          {{- if .Values.storage.persistence.enabled }}
           persistentVolumeClaim:
             claimName: {{ include "supabase.storage.fullname" . }}-pvc
-        {{- end }}
+          {{- else }}
+          emptyDir:
+            medium: ""
+          {{- end }}
         {{- with .Values.storage.volumes }}
           {{- toYaml . | nindent 8 }}
         {{- end }}
diff --git a/charts/supabase/templates/storage/ingress.yaml b/charts/supabase/templates/storage/ingress.yaml
deleted file mode 100644
index bede0887bfbc5417c292c9b377b8aa68316c4516..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/storage/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.storage.enabled -}}
-{{- if .Values.storage.ingress.enabled -}}
-{{- $fullName := include "supabase.storage.fullname" . -}}
-{{- $svcPort := .Values.storage.service.port -}}
-{{- if and .Values.storage.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.storage.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.storage.ingress.annotations "kubernetes.io/ingress.class" .Values.storage.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.storage.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.storage.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.storage.ingress.className }}
-  {{- end }}
-  {{- if .Values.storage.ingress.tls }}
-  tls:
-    {{- range .Values.storage.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.storage.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/studio/config.yaml b/charts/supabase/templates/studio/config.yaml
deleted file mode 100644
index 106c052c791233d62ffd537bd40372f3f2ddcddf..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/studio/config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- if .Values.studio.enabled -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "supabase.studio.fullname" . }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-data:
-  {{- toYaml .Values.studio.environment | nindent 2 }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/studio/deployment.yaml b/charts/supabase/templates/studio/deployment.yaml
index b0c25472fb77e08109a4f3d2fa6ebeda3762263a..2d4ddc7daab6bebd5efa5e488d0d755af7b4d8fa 100644
--- a/charts/supabase/templates/studio/deployment.yaml
+++ b/charts/supabase/templates/studio/deployment.yaml
@@ -37,21 +37,43 @@ spec:
           env:
             {{- range $key, $value := .Values.studio.environment }}
             - name: {{ $key }}
-              valueFrom:
-                configMapKeyRef:
-                  name: {{ include "supabase.studio.fullname" $ }}
-                  key: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            {{- if .Values.kong.enabled }}
+            - name: SUPABASE_URL
+              value: http://{{ include "supabase.kong.fullname" . }}:{{ .Values.kong.service.port }}
+            {{- end }}
+            {{- if .Values.meta.enabled }}
+            - name: STUDIO_PG_META_URL
+              value: http://{{ include "supabase.meta.fullname" . }}:{{ .Values.meta.service.port }}
             {{- end }}
             - name: SUPABASE_ANON_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: anonKey
             - name: SUPABASE_SERVICE_KEY
               valueFrom:
                 secretKeyRef:
-                  name: {{ .Values.jwt.secretName }}
+                  name: {{ include "supabase.secret.jwt" . }}
                   key: serviceKey
+            {{- if .Values.analytics.enabled }}
+            - name: LOGFLARE_URL
+              value: http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}
+            - name: LOGFLARE_API_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.analytics" . }}
+                  key: apiKey
+            {{- end }}
+          {{- with .Values.studio.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.studio.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
           ports:
             - name: http
               containerPort: 3000
diff --git a/charts/supabase/templates/studio/ingress.yaml b/charts/supabase/templates/studio/ingress.yaml
deleted file mode 100644
index 06153180acd491a36e9a0d5a48d68a9453314267..0000000000000000000000000000000000000000
--- a/charts/supabase/templates/studio/ingress.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-{{- if .Values.studio.enabled -}}
-{{- if .Values.studio.ingress.enabled -}}
-{{- $fullName := include "supabase.studio.fullname" . -}}
-{{- $svcPort := .Values.studio.service.port -}}
-{{- if and .Values.studio.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
-  {{- if not (hasKey .Values.studio.ingress.annotations "kubernetes.io/ingress.class") }}
-  {{- $_ := set .Values.studio.ingress.annotations "kubernetes.io/ingress.class" .Values.studio.ingress.className}}
-  {{- end }}
-{{- end }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    {{- include "supabase.labels" . | nindent 4 }}
-  {{- with .Values.studio.ingress.annotations }}
-  annotations:
-    {{- toYaml . | nindent 4 }}
-  {{- end }}
-spec:
-  {{- if and .Values.studio.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
-  ingressClassName: {{ .Values.studio.ingress.className }}
-  {{- end }}
-  {{- if .Values.studio.ingress.tls }}
-  tls:
-    {{- range .Values.studio.ingress.tls }}
-    - hosts:
-        {{- range .hosts }}
-        - {{ . | quote }}
-        {{- end }}
-      secretName: {{ .secretName }}
-    {{- end }}
-  {{- end }}
-  rules:
-    {{- range .Values.studio.ingress.hosts }}
-    - host: {{ .host | quote }}
-      http:
-        paths:
-          {{- range .paths }}
-          - path: {{ .path }}
-            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
-            pathType: {{ .pathType }}
-            {{- end }}
-            backend:
-              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
-              service:
-                name: {{ $fullName }}
-                port:
-                  number: {{ $svcPort }}
-              {{- else }}
-              serviceName: {{ $fullName }}
-              servicePort: {{ $svcPort }}
-              {{- end }}
-          {{- end }}
-    {{- end }}
-{{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/test/analytics.yaml b/charts/supabase/templates/test/analytics.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b97c3408d2378d8dd6d9b7be7e77f225a606eca0
--- /dev/null
+++ b/charts/supabase/templates/test/analytics.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.analytics.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-analytics
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-analytics
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/health
+              echo "Sevice {{ include "supabase.analytics.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/auth.yaml b/charts/supabase/templates/test/auth.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..19a7fb1fa5df26474add56837c2446fd9dba49dc
--- /dev/null
+++ b/charts/supabase/templates/test/auth.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.auth.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-auth
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-auth
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.auth.fullname" . }}:{{ .Values.auth.service.port }}/health
+              echo "Sevice {{ include "supabase.auth.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/db.yaml b/charts/supabase/templates/test/db.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4863f7a698298465513dd9327e957f5e8a0f4ebb
--- /dev/null
+++ b/charts/supabase/templates/test/db.yaml
@@ -0,0 +1,39 @@
+{{- if .Values.db.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-db
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - command:
+            - /bin/sh
+            - -c
+            - |
+              pg_isready -h $(DB_HOST) -p $(DB_PORT) -U $(DB_USER) || $(echo "\e[0;31mFailed to connect to the database." && exit 1)
+              echo "Database is ready"
+          env:
+            - name: DB_HOST
+              {{- if .Values.db.enabled }}
+              value: {{ include "supabase.db.fullname" . | quote }}
+              {{- else }}
+              value: {{ .Values.auth.environment.DB_HOST | quote }}
+              {{- end }}
+            - name: DB_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.db" . }}
+                  key: username
+            - name: DB_PORT
+              value: {{ .Values.auth.environment.DB_PORT | quote }}
+          image: postgres:15-alpine
+          imagePullPolicy: IfNotPresent
+          name: test-db
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/imgproxy.yaml b/charts/supabase/templates/test/imgproxy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b283dc8af170c5433b9f56e4e48b9228a2af8734
--- /dev/null
+++ b/charts/supabase/templates/test/imgproxy.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.imgproxy.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-imgproxy
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-imgproxy
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.imgproxy.fullname" . }}:{{ .Values.imgproxy.service.port }}/health
+              echo "Sevice {{ include "supabase.imgproxy.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/kong.yaml b/charts/supabase/templates/test/kong.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f8c741f83e20aa7ac70e8544a81a4eff96cf7ff5
--- /dev/null
+++ b/charts/supabase/templates/test/kong.yaml
@@ -0,0 +1,40 @@
+{{- if .Values.kong.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-kong
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - env:
+            - name: DASHBOARD_USERNAME
+              valueFrom:
+                secretKeyRef:
+                  key: username
+                  name: {{ include "supabase.fullname" . }}-dashboard
+            - name: DASHBOARD_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  key: password
+                  name: {{ include "supabase.fullname" . }}-dashboard
+          name: test-kong
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              echo "Attempting to access dashboard with provided credentials..."
+              curl -sL --fail \
+                -o /dev/null \
+                "http://${DASHBOARD_USERNAME}:${DASHBOARD_PASSWORD}@{{ include "supabase.kong.fullname" . }}:{{ .Values.kong.service.port }}" \
+                || ( echo -e "\e[0;31mFailed to get a valid response." && exit 1 )
+              echo "Successfully connected."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/meta.yaml b/charts/supabase/templates/test/meta.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9aee7f54b23afdbfbc5210a054e6c293a7a48d53
--- /dev/null
+++ b/charts/supabase/templates/test/meta.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.meta.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-meta
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-meta
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.meta.fullname" . }}:{{ .Values.meta.service.port }}/health
+              echo "Sevice {{ include "supabase.meta.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/minio.yaml b/charts/supabase/templates/test/minio.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b3c3db27f7a4e2a9a908de95c997bceabd7a3830
--- /dev/null
+++ b/charts/supabase/templates/test/minio.yaml
@@ -0,0 +1,25 @@
+{{- if .Values.minio.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-minio
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-minio
+          image: kdevup/curljq
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.minio.fullname" . }}:{{ .Values.minio.service.port }}/minio/health/live
+              echo "Sevice {{ include "supabase.minio.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/realtime.yaml b/charts/supabase/templates/test/realtime.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e373fde8282047930da5cdf8339f5bc5b9ef2fb3
--- /dev/null
+++ b/charts/supabase/templates/test/realtime.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.realtime.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-realtime
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-realtime
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.realtime.fullname" . }}:{{ .Values.realtime.service.port }}
+              echo "Sevice {{ include "supabase.realtime.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/rest.yaml b/charts/supabase/templates/test/rest.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..927ffc73bc550c41f17b3749399ebdc8c5953df7
--- /dev/null
+++ b/charts/supabase/templates/test/rest.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.rest.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-rest
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-rest
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.rest.fullname" . }}:{{ .Values.rest.service.port }}
+              echo "Sevice {{ include "supabase.rest.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/storage.yaml b/charts/supabase/templates/test/storage.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..db129fff85bbf67d9353b5add395374ca85c0c2e
--- /dev/null
+++ b/charts/supabase/templates/test/storage.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.storage.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-storage
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-storage
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.storage.fullname" . }}:{{ .Values.storage.service.port }}/status
+              echo "Sevice {{ include "supabase.storage.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/test/studio.yaml b/charts/supabase/templates/test/studio.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7e5082d9cda8ca809f7c51c5d3010d2210f6fa6c
--- /dev/null
+++ b/charts/supabase/templates/test/studio.yaml
@@ -0,0 +1,26 @@
+{{- if .Values.studio.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "supabase.fullname" . }}-test-studio
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  ttlSecondsAfterFinished: 100
+  template:
+    spec:
+      containers:
+        - name: test-studio
+          image: kdevup/curljq
+          imagePullPolicy: IfNotPresent
+          command:
+            - /bin/bash
+            - -c
+            - |
+              curl -sfo /dev/null \
+                http://{{ include "supabase.studio.fullname" . }}:{{ .Values.studio.service.port }}/api/profile
+              echo "Sevice {{ include "supabase.studio.fullname" . }} is healthy."
+      restartPolicy: Never
+{{- end }}
diff --git a/charts/supabase/templates/vector/_helpers.tpl b/charts/supabase/templates/vector/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..bd861b450d977688bd6e9e7e68159fb491a85616
--- /dev/null
+++ b/charts/supabase/templates/vector/_helpers.tpl
@@ -0,0 +1,43 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "supabase.vector.name" -}}
+{{- default (print .Chart.Name "-vector") .Values.vector.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "supabase.vector.fullname" -}}
+{{- if .Values.vector.fullnameOverride }}
+{{- .Values.vector.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default (print .Chart.Name "-vector") .Values.vector.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "supabase.vector.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "supabase.vector.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "supabase.vector.serviceAccountName" -}}
+{{- if .Values.vector.serviceAccount.create }}
+{{- default (include "supabase.vector.fullname" .) .Values.vector.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.vector.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/supabase/templates/vector/config.yaml b/charts/supabase/templates/vector/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..df2e897384de705233b38f9523ad1fd1aed06f35
--- /dev/null
+++ b/charts/supabase/templates/vector/config.yaml
@@ -0,0 +1,255 @@
+{{- if .Values.vector.enabled }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "supabase.vector.fullname" . }}-config
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+data:
+  secret.sh: |
+    #!/bin/sh
+    cat << EOF
+    {
+      "logflare_api_key": {
+        "value": "$LOGFLARE_API_KEY",
+        "error": null
+      }
+    }
+    EOF
+  vector.yml: |
+    secret:
+      credentials:
+        type: exec
+        command:
+          - /etc/vector/secret.sh
+
+    api:
+      enabled: true
+      address: 0.0.0.0:{{ .Values.vector.service.port }}
+
+    sources:
+      kubernetes_host:
+        type: kubernetes_logs
+        extra_label_selector: app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/name!={{ include "supabase.vector.name" . }}
+
+    transforms:
+      project_logs:
+        type: remap
+        inputs:
+          - kubernetes_host
+        source: |-
+          .project = "default"
+          .event_message = del(.message)
+          .appname = del(.kubernetes.container_name)
+          del(.file)
+          del(.kubernetes)
+          del(.source_type)
+          del(.stream)
+      router:
+        type: route
+        inputs:
+          - project_logs
+        route:
+          kong: '.appname == {{ include "supabase.kong.name" . | quote }}'
+          auth: '.appname == {{ include "supabase.auth.name" . | quote }}'
+          rest: '.appname == {{ include "supabase.rest.name" . | quote }}'
+          realtime: '.appname == {{ include "supabase.realtime.name" . | quote }}'
+          storage: '.appname == {{ include "supabase.storage.name" . | quote }}'
+          functions: '.appname == {{ include "supabase.functions.name" . | quote }}'
+          db: '.appname == {{ include "supabase.db.name" . | quote }}'
+      # Ignores non nginx errors since they are related with kong booting up
+      kong_logs:
+        type: remap
+        inputs:
+          - router.kong
+        source: |-
+          req, err = parse_nginx_log(.event_message, "combined")
+          if err == null {
+              .timestamp = req.timestamp
+              .metadata.request.headers.referer = req.referer
+              .metadata.request.headers.user_agent = req.agent
+              .metadata.request.headers.cf_connecting_ip = req.client
+              .metadata.request.method = req.method
+              .metadata.request.path = req.path
+              .metadata.request.protocol = req.protocol
+              .metadata.response.status_code = req.status
+          }
+          if err != null {
+            abort
+          }
+      # Ignores non nginx errors since they are related with kong booting up
+      kong_err:
+        type: remap
+        inputs:
+          - router.kong
+        source: |-
+          .metadata.request.method = "GET"
+          .metadata.response.status_code = 200
+          parsed, err = parse_nginx_log(.event_message, "error")
+          if err == null {
+              .timestamp = parsed.timestamp
+              .severity = parsed.severity
+              .metadata.request.host = parsed.host
+              .metadata.request.headers.cf_connecting_ip = parsed.client
+              url, err = split(parsed.request, " ")
+              if err == null {
+                  .metadata.request.method = url[0]
+                  .metadata.request.path = url[1]
+                  .metadata.request.protocol = url[2]
+              }
+          }
+          if err != null {
+            abort
+          }
+      # Gotrue logs are structured json strings which frontend parses directly. But we keep metadata for consistency.
+      auth_logs:
+        type: remap
+        inputs:
+          - router.auth
+        source: |-
+          parsed, err = parse_json(.event_message)
+          if err == null {
+              .metadata.timestamp = parsed.time
+              .metadata = merge!(.metadata, parsed)
+          }
+      # PostgREST logs are structured so we separate timestamp from message using regex
+      rest_logs:
+        type: remap
+        inputs:
+          - router.rest
+        source: |-
+          parsed, err = parse_regex(.event_message, r'^(?P<time>.*): (?P<msg>.*)$')
+          if err == null {
+              .event_message = parsed.msg
+              .timestamp = parse_timestamp!(parsed.time, format: "%e/%b/%Y %R %:z")
+              .metadata.host = .project
+          }
+      # Realtime logs are structured so we parse the severity level using regex (ignore time because it has no date)
+      realtime_logs:
+        type: remap
+        inputs:
+          - router.realtime
+        source: |-
+          .metadata.project = del(.project)
+          .metadata.external_id = .metadata.project
+          parsed, err = parse_regex(.event_message, r'^(?P<time>\d+:\d+:\d+\.\d+) \[(?P<level>\w+)\] (?P<msg>.*)$')
+          if err == null {
+              .event_message = parsed.msg
+              .metadata.level = parsed.level
+          }
+      # Storage logs may contain json objects so we parse them for completeness
+      storage_logs:
+        type: remap
+        inputs:
+          - router.storage
+        source: |-
+          .metadata.project = del(.project)
+          .metadata.tenantId = .metadata.project
+          parsed, err = parse_json(.event_message)
+          if err == null {
+              .event_message = parsed.msg
+              .metadata.level = parsed.level
+              .metadata.timestamp = parsed.time
+              .metadata.context[0].host = parsed.hostname
+              .metadata.context[0].pid = parsed.pid
+          }
+      # Postgres logs some messages to stderr which we map to warning severity level
+      db_logs:
+        type: remap
+        inputs:
+          - router.db
+        source: |-
+          .metadata.host = "db-default"
+          .metadata.parsed.timestamp = .timestamp
+          
+          parsed, err = parse_regex(.event_message, r'.*(?P<level>INFO|NOTICE|WARNING|ERROR|LOG|FATAL|PANIC?):.*', numeric_groups: true)
+
+          if err != null || parsed == null {
+            .metadata.parsed.error_severity = "info"
+          }
+          if parsed != null {
+          .metadata.parsed.error_severity = parsed.level
+          }
+          if .metadata.parsed.error_severity == "info" {
+              .metadata.parsed.error_severity = "log"
+          }
+          .metadata.parsed.error_severity = upcase!(.metadata.parsed.error_severity)
+
+    {{- if .Values.analytics.enabled }}
+    sinks:
+      logflare_auth:
+        type: 'http'
+        inputs:
+          - auth_logs
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=gotrue.logs.prod&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_realtime:
+        type: 'http'
+        inputs:
+          - realtime_logs
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=realtime.logs.prod&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_rest:
+        type: 'http'
+        inputs:
+          - rest_logs
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=postgREST.logs.prod&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_db:
+        type: 'http'
+        inputs:
+          - db_logs
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        # We must route the sink through kong because ingesting logs before logflare is fully initialised will
+        # lead to broken queries from studio. This works by the assumption that containers are started in the
+        # following order: vector > db > logflare > kong
+        uri: 'http://{{ include "supabase.kong.fullname" . }}:{{ .Values.kong.service.port }}/analytics/v1/api/logs?source_name=postgres.logs&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_functions:
+        type: 'http'
+        inputs:
+          - router.functions
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=deno-relay-logs&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_storage:
+        type: 'http'
+        inputs:
+          - storage_logs
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=storage.logs.prod.2&api_key=SECRET[credentials.logflare_api_key]'
+      logflare_kong:
+        type: 'http'
+        inputs:
+          - kong_logs
+          - kong_err
+        encoding:
+          codec: 'json'
+        method: 'post'
+        request:
+          retry_max_duration_secs: 10
+        uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=cloudflare.logs.prod&api_key=SECRET[credentials.logflare_api_key]'
+    {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/vector/deployment.yaml b/charts/supabase/templates/vector/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5dae5fd02824e9243a6291bbf0cbfbc15d7b99ba
--- /dev/null
+++ b/charts/supabase/templates/vector/deployment.yaml
@@ -0,0 +1,103 @@
+{{- if .Values.vector.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "supabase.vector.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+    vector.dev/exclude: "true"
+spec:
+  {{- if not .Values.vector.autoscaling.enabled }}
+  replicas: {{ .Values.vector.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "supabase.vector.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      annotations:
+      {{- with .Values.vector.podAnnotations }}
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+        checksum/config: {{ include (print $.Template.BasePath "/vector/config.yaml") . | sha256sum }}
+      labels:
+        {{- include "supabase.vector.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.vector.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "supabase.vector.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.vector.podSecurityContext | nindent 8 }}
+      containers:
+        - args:
+            - --config
+            - /etc/vector/vector.yml
+          name: {{ include "supabase.vector.name" $ }}
+          securityContext:
+            {{- toYaml .Values.vector.securityContext | nindent 12 }}
+          image: "{{ .Values.vector.image.repository }}:{{ .Values.vector.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.vector.image.pullPolicy }}
+          env:
+            {{- range $key, $value := .Values.vector.environment }}
+            - name: {{ $key }}
+              value: {{ $value | quote }}
+            {{- end }}
+            - name: VECTOR_SELF_NODE_NAME
+              valueFrom:
+                fieldRef:
+                  fieldPath: spec.nodeName
+          {{- if .Values.analytics.enabled }}
+            - name: LOGFLARE_API_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "supabase.secret.analytics" . }}
+                  key: apiKey
+          {{- end }}
+          {{- with .Values.vector.livenessProbe }}
+          livenessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.vector.readinessProbe }}
+          readinessProbe:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          ports:
+            - containerPort: {{ .Values.vector.service.port }}
+              protocol: TCP
+          volumeMounts:
+            {{- with .Values.vector.volumeMounts }}
+              {{- toYaml . | nindent 12 }}
+            {{- end }}
+            - mountPath: /etc/vector/vector.yml
+              name: vector-config
+              subPath: vector.yml
+            - mountPath: /etc/vector/secret.sh
+              name: vector-config
+              subPath: secret.sh
+          {{- with .Values.vector.resources }}
+          resources:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+      volumes:
+        {{- with .Values.vector.volumes }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+        - name: vector-config
+          configMap:
+            name:  {{ include "supabase.vector.fullname" . }}-config
+            defaultMode: 0777
+      {{- with .Values.vector.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.vector.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.vector.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/vector/service.yaml b/charts/supabase/templates/vector/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..be52f122a4945584c65500e982ca361f2174ee0a
--- /dev/null
+++ b/charts/supabase/templates/vector/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.vector.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "supabase.vector.fullname" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.vector.service.type }}
+  ports:
+    - port: {{ .Values.vector.service.port }}
+      targetPort: 9001
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "supabase.vector.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/templates/vector/serviceaccount.yaml b/charts/supabase/templates/vector/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4c71eaf6e58493ea0757d7b6866da138ae9e03b0
--- /dev/null
+++ b/charts/supabase/templates/vector/serviceaccount.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.vector.enabled -}}
+{{- if .Values.vector.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "supabase.vector.serviceAccountName" . }}
+  labels:
+    {{- include "supabase.labels" . | nindent 4 }}
+  {{- with .Values.vector.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ include "supabase.fullname" . }}-reader
+rules:
+  - apiGroups: [""]
+    resources: ["nodes", "namespaces", "pods"]
+    verbs: ["list", "watch"]
+  - apiGroups: [""]
+    resources: ["pods/log"]
+    resourceNames:
+      - {{ include "supabase.fullname" . }}-*
+    verbs: ["get"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "supabase.fullname" . }}-view
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "supabase.vector.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace }}
+roleRef:
+  kind: ClusterRole
+  name: {{ include "supabase.fullname" . }}-reader
+  apiGroup: rbac.authorization.k8s.io
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/supabase/values.example.yaml b/charts/supabase/values.example.yaml
index f8b873fa53856a69c93715259dc7736452fb20ac..835c8b1673f7a60e55c643d8dbf79c8cdcb39ea4 100644
--- a/charts/supabase/values.example.yaml
+++ b/charts/supabase/values.example.yaml
@@ -1,180 +1,151 @@
-jwt:
-  secretName: "demo-supabase-jwt"
-
-smtp:
-  secretName: "demo-supabase-smtp"
+secret:
+  jwt:
+    anonKey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
+    serviceKey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
+    secret: your-super-secret-jwt-token-with-at-least-32-characters-long
+  smtp:
+    username: your-mail@example.com
+    password: example123456
+  dashboard:
+    username: supabase
+    password: this_password_is_insecure_and_should_be_updated
+  db:
+    username: postgres
+    password: example123456
+    database: postgres
+  analytics:
+    apiKey: your-super-secret-and-long-logflare-key
 
 db:
   enabled: true
   image:
-    repository: supabase/postgres
-    tag: 14.1.0.105
-  secretName: "demo-supabase-db"
-  persistence: 
+    tag: 15.1.0.147
+  livenessProbe:
+    exec:
+      command:
+        - pg_isready
+        - -U
+        - postgres
+    initialDelaySeconds: 3
+  persistence:
     enabled: false
-  storage:
-      mountPath: /var/lib/postgresql/data
-      size: 20Gi
-      storageClass: standard
-      annotations:
-        helm.sh/resource-policy: "keep"
 
 studio:
   image:
-    repository: supabase/studio
-    tag: 20230127-6bfd87b
+    tag: 20240326-5e5586d
   environment:
-    SUPABASE_URL: http://localhost
-    SUPABASE_REST_URL: http://localhost/rest/v1/
-    STUDIO_PG_META_URL: http://demo-supabase-kong.default.svc.cluster.local:8000/pg
-    SUPABASE_PUBLIC_URL: http://localhost/
-  ingress:
-    enabled: true
-    className: "nginx"
-    annotations:
-      nginx.ingress.kubernetes.io/rewrite-target: /
-    tls: []
-      # - secretName: studio.localhost
-      #   hosts:
-      #     - studio.localhost
-    hosts:
-      - host: studio.localhost
-        paths:
-          - path: /
-            pathType: Prefix
-            backend:
-              serviceName: api
-              servicePort: 3000
+    STUDIO_DEFAULT_ORGANIZATION: "My Organization"
+    STUDIO_DEFAULT_PROJECT: "My Project"
+    SUPABASE_PUBLIC_URL: http://example.com/
+    NEXT_PUBLIC_ENABLE_LOGS: "true"
+  livenessProbe:
+    httpGet:
+      path: /api/profile
+      port: 3000
+    initialDelaySeconds: 3
 
 auth:
   image:
-    repo: v2.40.1
+    tag: v2.143.0
   environment:
-    DB_HOST: demo-supabase-db.default.svc.cluster.local
-    DB_PORT: "5432"
-    DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow
-    GOTRUE_API_HOST: "0.0.0.0"
-    GOTRUE_API_PORT: "9999"
-    GOTRUE_SITE_URL: http://studio.localhost
-    GOTRUE_URI_ALLOW_LIST: "*"
-    GOTRUE_DISABLE_SIGNUP: "false"
-    GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
-    GOTRUE_JWT_ADMIN_ROLES: service_role
-    GOTRUE_JWT_AUD: authenticated
-    GOTRUE_JWT_EXP: "3600"
+    API_EXTERNAL_URL: http://example.com
+    GOTRUE_SITE_URL: http://example.com
     GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
     GOTRUE_MAILER_AUTOCONFIRM: "true"
     GOTRUE_SMTP_ADMIN_EMAIL: "your-mail@example.com"
     GOTRUE_SMTP_HOST: "smtp.example.com"
     GOTRUE_SMTP_PORT: "587"
     GOTRUE_SMTP_SENDER_NAME: "your-mail@example.com"
-    GOTRUE_EXTERNAL_PHONE_ENABLED: "false"
-    GOTRUE_SMS_AUTOCONFIRM: "false"
-    GOTRUE_MAILER_URLPATHS_INVITE: "http://localhost:32534/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_CONFIRMATION: "http://localhost:32534/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_RECOVERY: "http://localhost:32534/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: "http://localhost:32534/auth/v1/verify"
 
 rest:
   image:
-    repository: postgrest/postgrest
-    tag: v9.0.1.20220717
-  environment:
-    DB_HOST: demo-supabase-db.default.svc.cluster.local
-    DB_PORT: "5432"
-    DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow
-    PGRST_DB_SCHEMA: public,storage
-    PGRST_DB_ANON_ROLE: anon
-    PGRST_DB_USE_LEGACY_GUCS: "false"
+    tag: v12.0.1
 
 realtime:
   image:
-    repository: supabase/realtime
-    tag: v2.1.0
-  environment:
-    DB_HOST: demo-supabase-db.default.svc.cluster.local
-    DB_PORT: "5432"
-    DB_NAME: postgres
-    DB_SSL: "false"
-    PORT: "4000"
-    REPLICATION_MODE: RLS
-    REPLICATION_POLL_INTERVAL: "100"
-    SECURE_CHANNELS: "true"
-    SLOT_NAME: supabase_realtime_rls
-    TEMPORARY_SLOT: "true"
-    DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime'
-    DB_ENC_KEY: supabaserealtime
-    FLY_ALLOC_ID: fly123
-    FLY_APP_NAME: realtime
-    SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
-    ERL_AFLAGS: -proto_dist inet_tcp
-    ENABLE_TAILSCALE: "false"
-    DNS_NODES: "''"
+    tag: v2.27.5
+  livenessProbe:
+    httpGet:
+      path: /
+      port: 4000
+    initialDelaySeconds: 3
+
 meta:
-  environment:
-    DB_HOST: demo-supabase-db.default.svc.cluster.local
-    DB_PORT: "5432"
-    DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: disable
-    PG_META_PORT: "8080"
+  image:
+    tag: v0.80.0
 
 storage:
   image:
-    repository: supabase/storage-api
-    tag: v0.26.1
+    tag: v0.46.4
+  livenessProbe:
+    httpGet:
+      path: /status
+      port: 5000
+    initialDelaySeconds: 3
+  persistence:
+    enabled: false
+
+imgproxy:
+  image:
+    tag: v3.8.0
   environment:
-    DB_HOST: demo-supabase-db.default.svc.cluster.local
-    DB_PORT: "5432"
-    DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: disable
-    POSTGREST_URL: http://demo-supabase-rest.default.svc.cluster.local:3000
-    PGOPTIONS: -c search_path=storage,public
-    FILE_SIZE_LIMIT: '52428800'
-    STORAGE_BACKEND: file
-    FILE_STORAGE_BACKEND_PATH: /var/lib/storage
-    TENANT_ID: stub
-    REGION: stub
-    GLOBAL_S3_BUCKET: stub
-  persistence: 
+    IMGPROXY_ENABLE_WEBP_DETECTION: "true"
+  livenessProbe:
+    exec:
+      command:
+        - imgproxy
+        - health
+    initialDelaySeconds: 3
+  persistence:
     enabled: false
-    accessModes:
-      - ReadWriteOnce
-    size: 4Gi
-    storageClassName: standard
-    annotations:
-      helm.sh/resource-policy: "keep"
 
 kong:
   image:
     repository: kong
     tag: 2.8.1
   environment:
-    KONG_DATABASE: "off"
-    KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
-    KONG_DNS_ORDER: LAST,A,CNAME
-    KONG_PLUGINS: request-transformer,cors,key-auth,acl
-    KONG_LOG_LEVEL: debug
-
+    KONG_DECLARATIVE_CONFIG: /usr/local/kong/kong.yml
+    KONG_LOG_LEVEL: info
   ingress:
     enabled: true
     className: "nginx"
     annotations:
       nginx.ingress.kubernetes.io/rewrite-target: /
     tls: []
-      # - secretName: localhost
+      # - secretName: example-ingress-tls
       #   hosts:
-      #     - localhost
+      #     - example.com
     hosts:
-      - host: localhost
+      - host: example.com
         paths:
           - path: /
             pathType: Prefix
-            backend:
-              serviceName: api
-              servicePort: 80
\ No newline at end of file
+
+analytics:
+  image:
+    tag: 1.4.0
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 4000
+    initialDelaySeconds: 3
+
+vector:
+  image:
+    tag: 0.34.0-alpine
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 9001
+    initialDelaySeconds: 3
+  volumeMounts:
+    - name: pod-logs
+      mountPath: /var/log/pods
+  volumes:
+    - name: pod-logs
+      hostPath:
+        path: /var/log/pods
+
+functions:
+  image:
+    tag: v1.41.2
diff --git a/charts/supabase/values.yaml b/charts/supabase/values.yaml
index 3dd2c159d7fe4797cbd29ea11a4ae5a5e72b1eed..d4dca75233715b973dc02deb807da97d11fd8fb6 100644
--- a/charts/supabase/values.yaml
+++ b/charts/supabase/values.yaml
@@ -1,30 +1,57 @@
 # File structure of values.yaml:
-# |-- 1. Database
-# |-- 2. Studio
-# |-- 3. Auth
-# |-- 4. Rest
-# |-- 5. Realtime
-# |-- 6. Meta
-# |-- 7. Storage
-# |-- 8. Kong
+# |-- 1.  Database
+# |-- 2.  Studio
+# |-- 3.  Auth
+# |-- 4.  Rest
+# |-- 5.  Realtime
+# |-- 6.  Meta
+# |-- 7.  Storage
+# |-- 8.  Image Proxy
+# |-- 9.  Kong
+# |-- 10. Analytics
+# |-- 11. Vector
+# |-- 12. Functions
+# |-- 13. Minio
 
-# jwt will be used to reference secret in multiple services:
-# Anon & Service key: Studio, Storage, Kong
-# JWT Secret: Auth, Rest, Realtime, Storage
-jwt:
-  secretName: "JWT_SECRET_NAME"
-
-# smtp will be used to reference secret including smtp credentials
-smtp:
-  secretName: "SMTP_SECRET_NAME"
+secret:
+  # jwt will be used to reference secret in multiple services:
+  # Anon & Service key: Studio, Storage, Kong
+  # JWT Secret: Analytics, Auth, Rest, Realtime, Storage
+  jwt:
+    anonKey: ""
+    serviceKey: ""
+    secret: ""
+    expiry: 3600
+  # database credentials
+  # these fields must be provided even if using external database
+  db:
+    username: ""
+    password: ""
+    database: ""
+  # analytics Logflare API key
+  analytics:
+    apiKey: ""
+  # smtp will be used to reference secret including smtp credentials
+  smtp:
+    # username: ""
+    # password: ""
+  # secret used to access the studio dashboard
+  # leave it empty to disable dashboard authentication
+  dashboard:
+    # username: ""
+    # password: ""
+  # S3 credentials for storage object bucket
+  s3:
+    # keyId: ""
+    # accessKey: ""
 
 # Optional: Postgres Database
-# A standalone Postgres database configured to work with Supabase services. 
-# You can spin up any other Postgres database container if required. 
+# A standalone Postgres database configured to work with Supabase services.
+# You can spin up any other Postgres database container if required.
 # If so, make sure to adjust DB_HOST accordingly to point to the right database service.
 db:
-  enabled: false # Disable the database provisioning
-  secretName: "DB_SECRET_NAME" # Still NEEDS TO BE DEFINED, even if database provisioning is disabled
+  # Enable database provisioning
+  enabled: true
   image:
     repository: supabase/postgres
     pullPolicy: IfNotPresent
@@ -33,6 +60,8 @@ db:
   replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -55,26 +84,13 @@ db:
     type: ClusterIP
     port: 5432
   environment:
+    POSTGRES_HOST: /var/run/postgresql
+    PGPORT: "5432"
+    POSTGRES_PORT: "5432"
     # POSTGRES_HOST_AUTH_METHOD: md5
-  ingress:
-    enabled: false
-    className: "nginx"
-    annotations:
-      nginx.ingress.kubernetes.io/rewrite-target: /
-      # cert-manager.io/cluster-issuer: "letsencrypt-staging"
-      # kubernetes.io/tls-acme: "true"
-    tls:
-      - secretName: DB.EXAMPLE.COM
-        hosts:
-          - DB.EXAMPLE.COM
-    hosts:
-      - host: DB.EXAMPLE.COM
-        paths:
-          - path: /
-            pathType: Prefix
-            backend:
-              serviceName: database
-              servicePort: 5432
+    # Enable SSL for postgres by specifying paths for mounted certificate key pair
+    # POSTGRES_SSL_CERT: /path/to/ssl/server.crt
+    # POSTGRES_SSL_KEY: /path/to/ssl/server.key
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -97,6 +113,14 @@ db:
     # requests:
     #   cpu: 100m
     #   memory: 128Mi
+  persistence:
+    enabled: true
+    storageClassName: ""
+    annotations: {}
+    size: 8Gi
+    accessModes:
+      - ReadWriteOnce
+    class: ""
   autoscaling:
     enabled: true
     minReplicas: 1
@@ -106,10 +130,13 @@ db:
   nodeSelector: {}
   tolerations: []
   affinity: {}
+  # Additional migration scripts can be defined here
+  config: {}
 
 # Studio Application
 studio:
-  enabled: true # Disable the studio
+  # Enable studio provisioning
+  enabled: true
   image:
     repository: supabase/studio
     pullPolicy: IfNotPresent
@@ -118,6 +145,8 @@ studio:
   replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -140,28 +169,11 @@ studio:
     type: ClusterIP
     port: 3000
   environment:
-    SUPABASE_URL: https://API.EXAMPLE.COM
-    SUPABASE_REST_URL: https://API.EXAMPLE.COM/rest/v1/
-    STUDIO_PG_META_URL: http://RELEASE_NAME-kong.NAMESPACE.svc.cluster.local:8000/pg
-  ingress:
-    enabled: true
-    className: "nginx"
-    annotations:
-      nginx.ingress.kubernetes.io/rewrite-target: /
-      # cert-manager.io/cluster-issuer: "letsencrypt-staging"
-      # kubernetes.io/tls-acme: "true"
-    tls:
-      - secretName: STUDIO.EXAMPLE.COM
-        hosts:
-          - STUDIO.EXAMPLE.COM
-    hosts:
-      - host: STUDIO.EXAMPLE.COM
-        paths:
-          - path: /
-            pathType: Prefix
-            backend:
-              serviceName: api
-              servicePort: 3000
+    STUDIO_DEFAULT_ORGANIZATION: Default Organization
+    STUDIO_DEFAULT_PROJECT: Default Project
+    STUDIO_PORT: "3000"
+    SUPABASE_PUBLIC_URL: http://example.com
+    NEXT_PUBLIC_ENABLE_LOGS: "true"
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -196,7 +208,8 @@ studio:
 
 # Auth Service
 auth:
-  enabled: true # Disable the auth service
+  # Enable auth provisioning
+  enabled: true
   image:
     repository: supabase/gotrue
     pullPolicy: IfNotPresent
@@ -205,6 +218,8 @@ auth:
   replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -227,14 +242,16 @@ auth:
     type: ClusterIP
     port: 9999
   environment:
-    DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
-    DB_PORT: "5432"
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USER: supabase_auth_admin
+    DB_PORT: 5432
     DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow # disable, allow, prefer, require, verify-ca, verify-full
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
+    API_EXTERNAL_URL: http://example.com
     GOTRUE_API_HOST: "0.0.0.0"
     GOTRUE_API_PORT: "9999"
-    GOTRUE_SITE_URL: https://STUDIO.EXAMPLE.COM
+    GOTRUE_SITE_URL: http://example.com
     GOTRUE_URI_ALLOW_LIST: "*"
     GOTRUE_DISABLE_SIGNUP: "false"
     GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
@@ -243,25 +260,18 @@ auth:
     GOTRUE_JWT_EXP: "3600"
     GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
     GOTRUE_MAILER_AUTOCONFIRM: "true"
+    # GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED: true
+    # GOTRUE_SMTP_MAX_FREQUENCY: 1s
     GOTRUE_SMTP_ADMIN_EMAIL: "SMTP_ADMIN_MAIL"
     GOTRUE_SMTP_HOST: "SMTP_HOST"
     GOTRUE_SMTP_PORT: "SMTP_PORT"
     GOTRUE_SMTP_SENDER_NAME: "SMTP_SENDER_NAME"
     GOTRUE_EXTERNAL_PHONE_ENABLED: "false"
     GOTRUE_SMS_AUTOCONFIRM: "false"
-    GOTRUE_MAILER_URLPATHS_INVITE: "https://API.EXAMPLE.COM/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_CONFIRMATION: "https://API.EXAMPLE.COM/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_RECOVERY: "https://API.EXAMPLE.COM/auth/v1/verify"
-    GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: "https://API.EXAMPLE.COM/auth/v1/verify"
-  ingress:
-    enabled: false
-    className: ""
-    annotations: {}
-    hosts: []
-    tls: []
-    #  - secretName: chart-example-tls
-    #    hosts:
-    #      - chart-example.local
+    GOTRUE_MAILER_URLPATHS_INVITE: "/auth/v1/verify"
+    GOTRUE_MAILER_URLPATHS_CONFIRMATION: "/auth/v1/verify"
+    GOTRUE_MAILER_URLPATHS_RECOVERY: "/auth/v1/verify"
+    GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: "/auth/v1/verify"
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -296,14 +306,17 @@ auth:
 
 # Rest Service
 rest:
-  enabled: true # Disable the rest service
+  # Enable postgrest provisioning
+  enabled: true
   image:
     repository: postgrest/postgrest
     pullPolicy: IfNotPresent
-    tag: "latest" 
+    tag: "latest"
   imagePullSecrets: []
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -326,23 +339,15 @@ rest:
     type: ClusterIP
     port: 3000
   environment:
-    DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
-    DB_PORT: "5432"
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USER: authenticator
+    DB_PORT: 5432
     DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow # disable, allow, prefer, require, verify-ca, verify-full
-    PGRST_DB_SCHEMA: public,storage
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
+    PGRST_DB_SCHEMAS: public,storage,graphql_public
     PGRST_DB_ANON_ROLE: anon
-    PGRST_DB_USE_LEGACY_GUCS: "false"
-  ingress:
-    enabled: false
-    className: ""
-    annotations: {}
-    hosts: []
-    tls: []
-    #  - secretName: chart-example-tls
-    #    hosts:
-    #      - chart-example.local
+    PGRST_DB_USE_LEGACY_GUCS: false
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -377,14 +382,17 @@ rest:
 
 # Realtime Service
 realtime:
-  enabled: true # Disable the realtime service
+  # Enable realtime provisioning
+  enabled: true
   image:
     repository: supabase/realtime
     pullPolicy: IfNotPresent
     tag: "latest"
   imagePullSecrets: []
   nameOverride: ""
-  fullnameOverride: "" 
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -407,25 +415,20 @@ realtime:
     type: ClusterIP
     port: 4000
   environment:
-    DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
-    DB_PORT: "5432"
-    DB_NAME: postgres
-    DB_SSL: "false"
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USER: supabase_admin
+    DB_PORT: 5432
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
+    DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
+    DB_ENC_KEY: supabaserealtime
     PORT: "4000"
-    REPLICATION_MODE: RLS
-    REPLICATION_POLL_INTERVAL: "100"
-    SECURE_CHANNELS: "true"
-    SLOT_NAME: supabase_realtime_rls
-    TEMPORARY_SLOT: "true"
-  ingress:
-    enabled: false
-    className: ""
-    annotations: {}
-    hosts: []
-    tls: []
-    #  - secretName: chart-example-tls
-    #    hosts:
-    #      - chart-example.local
+    FLY_ALLOC_ID: fly123
+    FLY_APP_NAME: realtime
+    SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
+    ERL_AFLAGS: -proto_dist inet_tcp
+    ENABLE_TAILSCALE: "false"
+    DNS_NODES: "''"
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -460,15 +463,18 @@ realtime:
 
 # Meta Service
 meta:
-  enabled: true # Disable the meta service
+  # Enable meta provisioning
+  enabled: true
   image:
     repository: supabase/postgres-meta
     pullPolicy: IfNotPresent
     tag: "latest"
   imagePullSecrets: []
-  replicaCount: 1  
+  replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -491,21 +497,13 @@ meta:
     type: ClusterIP
     port: 8080
   environment:
-    DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
-    DB_PORT: "5432"
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USER: supabase_admin
+    DB_PORT: 5432
     DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow # disable, allow, prefer, require, verify-ca, verify-full
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
     PG_META_PORT: "8080"
-  ingress:
-    enabled: false
-    className: ""
-    annotations: {}
-    hosts: []
-    tls: []
-    #  - secretName: chart-example-tls
-    #    hosts:
-    #      - chart-example.local
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -536,11 +534,12 @@ meta:
     # targetMemoryUtilizationPercentage: 80
   nodeSelector: {}
   tolerations: []
-  affinity: {}    
+  affinity: {}
 
 # Storage Service
 storage:
-  enabled: true # Disable the storage service
+  # Enable storage provisioning
+  enabled: true
   image:
     repository: supabase/storage-api
     pullPolicy: IfNotPresent
@@ -549,6 +548,8 @@ storage:
   replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -571,28 +572,105 @@ storage:
     type: ClusterIP
     port: 5000
   environment:
-    DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
-    DB_PORT: "5432"
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USER: supabase_storage_admin
+    DB_PORT: 5432
     DB_DRIVER: postgres
-    DB_NAME: postgres
-    DB_SSL: allow # disable, allow, prefer, require, verify-ca, verify-full
-    POSTGREST_URL: http://RELEASE_NAME-rest.NAMESPACE.svc.cluster.local:3000
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
     PGOPTIONS: -c search_path=storage,public
-    FILE_SIZE_LIMIT: '52428800'
-    STORAGE_BACKEND: file
+    FILE_SIZE_LIMIT: "52428800"
+    STORAGE_BACKEND: file  # file, s3
     FILE_STORAGE_BACKEND_PATH: /var/lib/storage
     TENANT_ID: stub
     REGION: stub
     GLOBAL_S3_BUCKET: stub
-  ingress:
-    enabled: false
-    className: ""
+    # Set variables below and secret.s3 above to enable S3 storage bucket
+    # If using this chart's minio, skip the endpoint and protocol below
+    # GLOBAL_S3_ENDPOINT: http://minio:9000
+    # GLOBAL_S3_PROTOCOL: http
+    # GLOBAL_S3_FORCE_PATH_STYLE: true
+    # AWS_DEFAULT_REGION: stub
+  # volumeMounts:
+  #   - name: volume_name
+  #     mountPath: /path/to/my/secret
+  # volumes:
+  #   - name: volume_name
+  #     secret:
+  #       defaultMode: 733
+  #       secretName: my_secret
+  #       items:
+  #       - key: my_secret.txt
+  #         path: name_of_file_in_container.txt
+  resources: {}
+    # We usually recommend not to specify default resources and to leave this as a conscious
+    # choice for the user. This also increases chances charts run on environments with little
+    # resources, such as Minikube. If you do want to specify resources, uncomment the following
+    # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+    # limits:
+    #   cpu: 100m
+    #   memory: 128Mi
+    # requests:
+    #   cpu: 100m
+    #   memory: 128Mi
+  persistence:
+    enabled: true
+    storageClassName: ""
     annotations: {}
-    hosts: []
-    tls: []
-    #  - secretName: chart-example-tls
-    #    hosts:
-    #      - chart-example.local
+    size: 10Gi
+    accessModes:
+      - ReadWriteOnce
+    class: ""
+  autoscaling:
+    enabled: true
+    minReplicas: 1
+    maxReplicas: 100
+    targetCPUUtilizationPercentage: 80
+    # targetMemoryUtilizationPercentage: 80
+  nodeSelector: {}
+  tolerations: []
+  affinity: {}
+
+# imgproxy
+imgproxy:
+  # Enable imgproxy provisioning
+  enabled: true
+  image:
+    repository: darthsim/imgproxy
+    pullPolicy: IfNotPresent
+    tag: "latest"
+  imagePullSecrets: []
+  replicaCount: 1
+  nameOverride: ""
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
+  serviceAccount:
+    # Specifies whether a service account should be created
+    create: true
+    # Annotations to add to the service account
+    annotations: {}
+    # The name of the service account to use.
+    # If not set and create is true, a name is generated using the fullname template
+    name: ""
+  podAnnotations: {}
+  podSecurityContext: {}
+    # fsGroup: 2000
+  securityContext: {}
+    # capabilities:
+    #   drop:
+    #   - ALL
+    # readOnlyRootFilesystem: true
+    # runAsNonRoot: true
+    # runAsUser: 1000
+  service:
+    type: ClusterIP
+    port: 5001
+  environment:
+    IMGPROXY_BIND: ":5001"
+    IMGPROXY_LOCAL_FILESYSTEM_ROOT: /
+    IMGPROXY_USE_ETAG: "true"
+    IMGPROXY_ENABLE_WEBP_DETECTION: "true"
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -635,7 +713,8 @@ storage:
 
 # Kong
 kong:
-  enabled: true # Disable the kong service
+  # Enable kong provisioning
+  enabled: true
   image:
     repository: kong
     pullPolicy: IfNotPresent
@@ -644,6 +723,8 @@ kong:
   replicaCount: 1
   nameOverride: ""
   fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
   serviceAccount:
     # Specifies whether a service account should be created
     create: true
@@ -667,10 +748,13 @@ kong:
     port: 8000
   environment:
     KONG_DATABASE: "off"
-    KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
+    KONG_DECLARATIVE_CONFIG: /usr/local/kong/kong.yml
     # https://github.com/supabase/cli/issues/14
     KONG_DNS_ORDER: LAST,A,CNAME
-    KONG_PLUGINS: request-transformer,cors,key-auth,acl
+    KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
+    KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k
+    KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
+    KONG_LOG_LEVEL: warn
   ingress:
     enabled: true
     className: "nginx"
@@ -678,18 +762,18 @@ kong:
       nginx.ingress.kubernetes.io/rewrite-target: /
       # cert-manager.io/cluster-issuer: "letsencrypt-staging"
       # kubernetes.io/tls-acme: "true"
-    tls:
-      - secretName: API.EXAMPLE.COM
-        hosts:
-          - API.EXAMPLE.COM
+    tls: []
+      # Define TLS secret for SSL termination.
+      # This section can be left blank if using cluster certificate manager.
+      # Otherwise, setting this in tandem with certificate manager will overwrite the secret name.
+      # - secretName: example-com-tls
+      #   hosts:
+      #     - example.com
     hosts:
-      - host: API.EXAMPLE.COM
+      - host: example.com
         paths:
           - path: /
             pathType: Prefix
-            backend:
-              serviceName: api
-              servicePort: 80
   # volumeMounts:
   #   - name: volume_name
   #     mountPath: /path/to/my/secret
@@ -721,152 +805,305 @@ kong:
   nodeSelector: {}
   tolerations: []
   affinity: {}
-  config: {}
-  #   _format_version: "1.1"
-
-  #   ###
-  #   ### Consumers / Users
-  #   ###
-  #   consumers:
-  #     - username: anon
-  #       keyauth_credentials:
-  #         - key: ${JWT_ANON_KEY}
-  #     - username: service_role
-  #       keyauth_credentials:
-  #         - key: ${JWT_SERVICE_KEY}
-
-  #   ###
-  #   ### Access Control List
-  #   ###
-  #   acls:
-  #     - consumer: anon
-  #       group: anon
-  #     - consumer: service_role
-  #       group: admin
 
-  #   ###
-  #   ### API Routes
-  #   ###
-  #   services:
-  #     ## Open Auth routes
-  #     - name: auth-v1-open
-  #       url: http://svc.cluster.local:9999/verify
-  #       routes:
-  #         - name: auth-v1-open
-  #           strip_path: true
-  #           paths:
-  #             - /auth/v1/verify
-  #       plugins:
-  #         - name: cors
-  #     - name: auth-v1-open-callback
-  #       url: http://svc.cluster.local:9999/callback
-  #       routes:
-  #         - name: auth-v1-open-callback
-  #           strip_path: true
-  #           paths:
-  #             - /auth/v1/callback
-  #       plugins:
-  #         - name: cors
-  #     - name: auth-v1-open-authorize
-  #       url: http://svc.cluster.local:9999/authorize
-  #       routes:
-  #         - name: auth-v1-open-authorize
-  #           strip_path: true
-  #           paths:
-  #             - /auth/v1/authorize
-  #       plugins:
-  #         - name: cors
-
-  #     ## Secure Auth routes
-  #     - name: auth-v1
-  #       _comment: "GoTrue: /auth/v1/* -> http://svc.cluster.local:9999/*"
-  #       url: http://svc.cluster.local:9999/
-  #       routes:
-  #         - name: auth-v1-all
-  #           strip_path: true
-  #           paths:
-  #             - /auth/v1/
-  #       plugins:
-  #         - name: cors
-  #         - name: key-auth
-  #           config:
-  #             hide_credentials: false
-  #         - name: acl
-  #           config:
-  #             hide_groups_header: true
-  #             allow:
-  #               - admin
-  #               - anon
-
-  #     ## Secure REST routes
-  #     - name: rest-v1
-  #       _comment: "PostgREST: /rest/v1/* -> http://DATABASE_ENDPOINT:3000/*"
-  #       url: http://DATABASE_ENDPOINT:3000/
-  #       routes:
-  #         - name: rest-v1-all
-  #           strip_path: true
-  #           paths:
-  #             - /rest/v1/
-  #       plugins:
-  #         - name: cors
-  #         - name: key-auth
-  #           config:
-  #             hide_credentials: true
-  #         - name: acl
-  #           config:
-  #             hide_groups_header: true
-  #             allow:
-  #               - admin
-  #               - anon
+# Analytics
+analytics:
+  # Enable analytics provisioning
+  enabled: true
+  image:
+    repository: supabase/logflare
+    pullPolicy: IfNotPresent
+    tag: "latest"
+  imagePullSecrets: []
+  replicaCount: 1
+  nameOverride: ""
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
+  serviceAccount:
+    # Specifies whether a service account should be created
+    create: true
+    # Annotations to add to the service account
+    annotations: {}
+    # The name of the service account to use.
+    # If not set and create is true, a name is generated using the fullname template
+    name: ""
+  podAnnotations: {}
+  podSecurityContext: {}
+    # fsGroup: 2000
+  securityContext: {}
+    # capabilities:
+    #   drop:
+    #   - ALL
+    # readOnlyRootFilesystem: true
+    # runAsNonRoot: true
+    # runAsUser: 1000
+  service:
+    type: ClusterIP
+    port: 4000
+  environment:
+    LOGFLARE_NODE_HOST: 127.0.0.1
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USERNAME: supabase_admin
+    DB_PORT: 5432
+    DB_DRIVER: postgresql
+    DB_SCHEMA: _analytics
+    LOGFLARE_SINGLE_TENANT: "true"
+    LOGFLARE_SUPABASE_MODE: "true"
+    FEATURE_FLAG_OVERRIDE: multibackend=true
+  # Enable Big Query backend for analytics
+  bigQuery:
+    enabled: false
+    projectId: google-project-id
+    projectNumber: google-project-number
+    gcloudJson: ""
+  # volumeMounts:
+  #   - name: volume_name
+  #     mountPath: /path/to/my/secret
+  # volumes:
+  #   - name: volume_name
+  #     secret:
+  #       defaultMode: 733
+  #       secretName: my_secret
+  #       items:
+  #       - key: my_secret.txt
+  #         path: name_of_file_in_container.txt
+  resources: {}
+    # We usually recommend not to specify default resources and to leave this as a conscious
+    # choice for the user. This also increases chances charts run on environments with little
+    # resources, such as Minikube. If you do want to specify resources, uncomment the following
+    # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+    # limits:
+    #   cpu: 100m
+    #   memory: 128Mi
+    # requests:
+    #   cpu: 100m
+    #   memory: 128Mi
+  autoscaling:
+    enabled: true
+    minReplicas: 1
+    maxReplicas: 100
+    targetCPUUtilizationPercentage: 80
+    # targetMemoryUtilizationPercentage: 80
+  nodeSelector: {}
+  tolerations: []
+  affinity: {}
 
-  #     ## Secure Realtime routes
-  #     - name: realtime-v1
-  #       _comment: "Realtime: /realtime/v1/* -> ws://svc.cluster.local:4000/socket/*"
-  #       url: http://svc.cluster.local:4000/socket/
-  #       routes:
-  #         - name: realtime-v1-all
-  #           strip_path: true
-  #           paths:
-  #             - /realtime/v1/
-  #       plugins:
-  #         - name: cors
-  #         - name: key-auth
-  #           config:
-  #             hide_credentials: false
-  #         - name: acl
-  #           config:
-  #             hide_groups_header: true
-  #             allow:
-  #               - admin
-  #               - anon
+# Vector
+vector:
+  # Enable vector provisioning
+  enabled: true
+  image:
+    repository: timberio/vector
+    pullPolicy: IfNotPresent
+    tag: "latest"
+  imagePullSecrets: []
+  replicaCount: 1
+  nameOverride: ""
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
+  serviceAccount:
+    # Specifies whether a service account should be created
+    create: true
+    # Annotations to add to the service account
+    annotations: {}
+    # The name of the service account to use.
+    # If not set and create is true, a name is generated using the fullname template
+    name: ""
+  podAnnotations: {}
+  podSecurityContext: {}
+    # fsGroup: 2000
+  securityContext: {}
+    # capabilities:
+    #   drop:
+    #   - ALL
+    # readOnlyRootFilesystem: true
+    # runAsNonRoot: true
+    # runAsUser: 1000
+  service:
+    type: ClusterIP
+    port: 9001
+  # volumeMounts:
+  #   - name: volume_name
+  #     mountPath: /path/to/my/secret
+  # volumes:
+  #   - name: volume_name
+  #     secret:
+  #       defaultMode: 733
+  #       secretName: my_secret
+  #       items:
+  #       - key: my_secret.txt
+  #         path: name_of_file_in_container.txt
+  resources: {}
+    # We usually recommend not to specify default resources and to leave this as a conscious
+    # choice for the user. This also increases chances charts run on environments with little
+    # resources, such as Minikube. If you do want to specify resources, uncomment the following
+    # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+    # limits:
+    #   cpu: 100m
+    #   memory: 128Mi
+    # requests:
+    #   cpu: 100m
+    #   memory: 128Mi
+  autoscaling:
+    enabled: true
+    minReplicas: 1
+    maxReplicas: 100
+    targetCPUUtilizationPercentage: 80
+    # targetMemoryUtilizationPercentage: 80
+  nodeSelector: {}
+  tolerations: []
+  affinity: {}
 
-  #     ## Storage routes: the storage server manages its own auth
-  #     - name: storage-v1
-  #       _comment: "Storage: /storage/v1/* -> http://svc.cluster.local:5000/*"
-  #       url: http://svc.cluster.local:5000/
-  #       routes:
-  #         - name: storage-v1-all
-  #           strip_path: true
-  #           paths:
-  #             - /storage/v1/
-  #       plugins:
-  #         - name: cors
+# Functions
+functions:
+  # Enable functions provisioning
+  enabled: true
+  image:
+    repository: supabase/edge-runtime
+    pullPolicy: IfNotPresent
+    tag: "latest"
+  imagePullSecrets: []
+  replicaCount: 1
+  nameOverride: ""
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
+  serviceAccount:
+    # Specifies whether a service account should be created
+    create: true
+    # Annotations to add to the service account
+    annotations: {}
+    # The name of the service account to use.
+    # If not set and create is true, a name is generated using the fullname template
+    name: ""
+  podAnnotations: {}
+  podSecurityContext: {}
+    # fsGroup: 2000
+  securityContext: {}
+    # capabilities:
+    #   drop:
+    #   - ALL
+    # readOnlyRootFilesystem: true
+    # runAsNonRoot: true
+    # runAsUser: 1000
+  service:
+    type: ClusterIP
+    port: 9000
+  environment:
+    # Override the database hostname if using external database
+    # DB_HOST: DATABASE.NAMESPACE.svc.cluster.local
+    DB_USERNAME: supabase_functions_admin
+    DB_PORT: 5432
+    DB_DRIVER: postgresql
+    DB_SSL: disable  # disable, allow, prefer, require, verify-ca, verify-full
+  # Mount user functions
+  # volumeMounts:
+  #   - name: my_functions
+  #     mountPath: /home/deno/functions/main/main
+  # volumes:
+  #   - name: my_functions
+  #     secret:
+  #       defaultMode: 733
+  #       secretName: my_secret
+  #       items:
+  #       - key: my_secret.ts
+  #         path: name_of_file_in_container.ts
+  resources: {}
+    # We usually recommend not to specify default resources and to leave this as a conscious
+    # choice for the user. This also increases chances charts run on environments with little
+    # resources, such as Minikube. If you do want to specify resources, uncomment the following
+    # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+    # limits:
+    #   cpu: 100m
+    #   memory: 128Mi
+    # requests:
+    #   cpu: 100m
+    #   memory: 128Mi
+  autoscaling:
+    enabled: true
+    minReplicas: 1
+    maxReplicas: 100
+    targetCPUUtilizationPercentage: 80
+    # targetMemoryUtilizationPercentage: 80
+  nodeSelector: {}
+  tolerations: []
+  affinity: {}
 
-  #     ## Secure Database routes
-  #     - name: meta
-  #       _comment: "pg-meta: /pg/* -> http://svc.cluster.local:8080/*"
-  #       url: http://svc.cluster.local:8080/
-  #       routes:
-  #         - name: meta-all
-  #           strip_path: true
-  #           paths:
-  #             - /pg/
-  #       plugins:
-  #         - name: key-auth
-  #           config:
-  #             hide_credentials: false
-  #         - name: acl
-  #           config:
-  #             hide_groups_header: true
-  #             allow:
-  #               - admin
\ No newline at end of file
+# minio
+minio:
+  enabled: false
+  image:
+    repository: minio/minio
+    pullPolicy: IfNotPresent
+    tag: "latest"
+  imagePullSecrets: []
+  replicaCount: 1
+  nameOverride: ""
+  fullnameOverride: ""
+  livenessProbe: {}
+  readinessProbe: {}
+  serviceAccount:
+    # Specifies whether a service account should be created
+    create: true
+    # Annotations to add to the service account
+    annotations: {}
+    # The name of the service account to use.
+    # If not set and create is true, a name is generated using the fullname template
+    name: ""
+  podAnnotations: {}
+  podSecurityContext: {}
+    # fsGroup: 2000
+  securityContext: {}
+    # capabilities:
+    #   drop:
+    #   - ALL
+    # readOnlyRootFilesystem: true
+    # runAsNonRoot: true
+    # runAsUser: 1000
+  service:
+    type: ClusterIP
+    port: 9000
+  environment: {}
+  # Mount user functions
+  # volumeMounts:
+  #   - name: my_functions
+  #     mountPath: /home/deno/functions/main/main
+  # volumes:
+  #   - name: my_functions
+  #     secret:
+  #       defaultMode: 733
+  #       secretName: my_secret
+  #       items:
+  #       - key: my_secret.ts
+  #         path: name_of_file_in_container.ts
+  resources: {}
+    # We usually recommend not to specify default resources and to leave this as a conscious
+    # choice for the user. This also increases chances charts run on environments with little
+    # resources, such as Minikube. If you do want to specify resources, uncomment the following
+    # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+    # limits:
+    #   cpu: 100m
+    #   memory: 128Mi
+    # requests:
+    #   cpu: 100m
+    #   memory: 128Mi
+  persistence:
+    enabled: false
+    storageClassName: ""
+    annotations: {}
+    size: 10Gi
+    accessModes:
+      - ReadWriteOnce
+    class: ""
+  autoscaling:
+    enabled: true
+    minReplicas: 1
+    maxReplicas: 100
+    targetCPUUtilizationPercentage: 80
+    # targetMemoryUtilizationPercentage: 80
+  nodeSelector: {}
+  tolerations: []
+  affinity: {}