diff --git a/charts/supabase/templates/db/deployment.yaml b/charts/supabase/templates/db/deployment.yaml index f6d5089517e6f6059559426c9e00d035874bf5e8..e75aadf57f9380ca992d8e700008aa4c13206a5f 100644 --- a/charts/supabase/templates/db/deployment.yaml +++ b/charts/supabase/templates/db/deployment.yaml @@ -37,20 +37,18 @@ spec: command: ["/bin/sh", "-c"] args: - | - echo "Creating new PGDATA directory in PVC (for subpath)..." mkdir -p /var/lib/postgresql/data/postgres-data echo "Copying init scripts into existing image script directory..." cp -r /docker-entrypoint-initdb.d/* /initdb.d/ - # init-scripts - 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-jwt.sql /initdb.d/init-scripts/ - # migrations - cp /custom-init-scripts/99-realtime.sql /initdb.d/migrations/ - cp /custom-init-scripts/97-_supabase.sql /initdb.d/migrations/ - cp /custom-init-scripts/99-logs.sql /initdb.d/migrations/ - cp /custom-init-scripts/99-pooler.sql /initdb.d/migrations/ + cp /custom-init-scripts/99-realtime.sql /initdb.d/migrations/99-realtime.sql + cp /custom-init-scripts/98-webhooks.sql /initdb.d/init-scripts/98-webhooks.sql + cp /custom-init-scripts/99-roles.sql /initdb.d/init-scripts/99-roles.sql + # Initialize the database settings with JWT_SECRET and JWT_EXP + cp /custom-init-scripts/99-jwt.sql /initdb.d/init-scripts/99-jwt.sql + cp /custom-init-scripts/97-_supabase.sql /initdb.d/migrations/97-_supabase.sql + cp /custom-init-scripts/99-logs.sql /initdb.d/migrations/99-logs.sql + cp /custom-init-scripts/99-pooler.sql /initdb.d/migrations/99-pooler.sql echo "Copying user-defined migration scripts..." cp /custom-migrations/* /initdb.d/migrations/ || echo "Skip migrations" diff --git a/charts/supabase/templates/db/initdb.config.yaml b/charts/supabase/templates/db/initdb.config.yaml index aec2e9c684dee94d6f4177cab57c3beefa04cd7a..ce9b89b1492ddcaf787dffc32bf1d8ea428449cf 100644 --- a/charts/supabase/templates/db/initdb.config.yaml +++ b/charts/supabase/templates/db/initdb.config.yaml @@ -10,26 +10,31 @@ data: \set jwt_secret `echo "$JWT_SECRET"` \set jwt_exp `echo "$JWT_EXP"` - ALTER DATABASE postgres SET "app.settings.jwt_secret" TO :jwt_secret; - ALTER DATABASE postgres SET "app.settings.jwt_exp" TO :jwt_exp; + 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"` \c _supabase create schema if not exists _analytics; alter schema _analytics owner to :pguser; - \c postgres + \c postgres + 99-realtime.sql: | \set pguser `echo "$POSTGRES_USER"` create schema if not exists _realtime; alter schema _realtime owner to :pguser; + 99-pooler.sql: | \set pguser `echo "$POSTGRES_USER"` + \c _supabase create schema if not exists _supavisor; alter schema _supavisor owner to :pguser; \c postgres + 99-roles.sql: | -- NOTE: change to your own passwords for production environments \set pgpass `echo "$POSTGRES_PASSWORD"` @@ -38,8 +43,8 @@ data: 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'; - + ALTER USER supabase_storage_admin WITH PASSWORD :'pgpass'; + 98-webhooks.sql: | BEGIN; -- Create pg_net extension @@ -84,29 +89,29 @@ data: 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( @@ -123,7 +128,7 @@ data: 'table', TG_TABLE_NAME, 'schema', TG_TABLE_SCHEMA ); - + SELECT http_post INTO request_id FROM net.http_post( url, payload, @@ -134,12 +139,12 @@ data: 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$; @@ -252,6 +257,7 @@ data: 97-_supabase.sql: | \set pguser `echo "$POSTGRES_USER"` + CREATE DATABASE _supabase WITH OWNER :pguser; diff --git a/charts/supabase/templates/kong/config.yaml b/charts/supabase/templates/kong/config.yaml index 2edd25af6fcdf3100b94e97034b850a9c4c90d86..c675352dc1a139ff05e07ef7e645bf40044cb6fe 100644 --- a/charts/supabase/templates/kong/config.yaml +++ b/charts/supabase/templates/kong/config.yaml @@ -142,11 +142,12 @@ data: - anon {{- end }} {{- if .Values.realtime.enabled }} - - name: realtime-v1 + - name: realtime-v1-ws _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 + protocol: ws routes: - - name: realtime-v1-all + - name: realtime-v1-ws strip_path: true paths: - /realtime/v1/ @@ -161,6 +162,26 @@ data: allow: - admin - anon + - name: realtime-v1-rest + _comment: 'Realtime: /realtime/v1/* -> ws://ws://{{ include "supabase.realtime.fullname" . }}:{{ .Values.realtime.service.port }}/socket/*' + url: http://{{ include "supabase.realtime.fullname" . }}:{{ .Values.realtime.service.port }}/api + protocol: http + routes: + - name: realtime-v1-rest + strip_path: true + paths: + - /realtime/v1/api + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: false + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon {{- end }} {{- if .Values.storage.enabled }} - name: storage-v1 diff --git a/charts/supabase/templates/vector/config.yaml b/charts/supabase/templates/vector/config.yaml index df2e897384de705233b38f9523ad1fd1aed06f35..1822e4d8f6a2e84a13873cba6b880f9ce880fecf 100644 --- a/charts/supabase/templates/vector/config.yaml +++ b/charts/supabase/templates/vector/config.yaml @@ -186,7 +186,8 @@ data: 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]' + encoding: + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=gotrue.logs.prod&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_realtime: type: 'http' inputs: @@ -196,7 +197,7 @@ data: 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]' + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=realtime.logs.prod&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_rest: type: 'http' inputs: @@ -206,7 +207,7 @@ data: 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]' + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=postgREST.logs.prod&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_db: type: 'http' inputs: @@ -219,7 +220,7 @@ data: # 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]' + uri: 'http://{{ include "supabase.kong.fullname" . }}:{{ .Values.kong.service.port }}/analytics/v1/api/logs?source_name=postgres.logs&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_functions: type: 'http' inputs: @@ -229,7 +230,7 @@ data: 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]' + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=deno-relay-logs&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_storage: type: 'http' inputs: @@ -239,7 +240,7 @@ data: 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]' + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=storage.logs.prod.2&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' logflare_kong: type: 'http' inputs: @@ -250,6 +251,6 @@ data: 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]' + uri: 'http://{{ include "supabase.analytics.fullname" . }}:{{ .Values.analytics.service.port }}/api/logs?source_name=cloudflare.logs.prod&api_key={{ required "LOGFLARE_API_KEY is required" .Values.analytics.apiKey }}' {{- end }} {{- end }} \ No newline at end of file diff --git a/charts/supabase/values.yaml b/charts/supabase/values.yaml index 27900a1ff2890d4bf7d8121d3f09022231c80a0d..dc981c5aad66a03f2ad2d7578841764fad39a788 100644 --- a/charts/supabase/values.yaml +++ b/charts/supabase/values.yaml @@ -91,7 +91,7 @@ db: image: repository: supabase/postgres pullPolicy: IfNotPresent - tag: "latest" + tag: 15.8.1.060 imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -179,7 +179,7 @@ studio: image: repository: supabase/studio pullPolicy: IfNotPresent - tag: "latest" + tag: 20250317-6955350 imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -255,7 +255,7 @@ auth: image: repository: supabase/gotrue pullPolicy: IfNotPresent - tag: "latest" + tag: "v2.170.0" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -357,7 +357,7 @@ rest: image: repository: postgrest/postgrest pullPolicy: IfNotPresent - tag: "latest" + tag: "v12.2.8" imagePullSecrets: [] nameOverride: "" fullnameOverride: "" @@ -449,16 +449,16 @@ realtime: # If not set and create is true, a name is generated using the fullname template name: "" podAnnotations: {} - podSecurityContext: - runAsUser: 65534 + podSecurityContext: {} + # runAsUser: 65534 # fsGroup: 2000 - securityContext: + securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65534 + # runAsNonRoot: true + # runAsUser: 65534 service: type: ClusterIP port: 4000 @@ -516,7 +516,7 @@ meta: image: repository: supabase/postgres-meta pullPolicy: IfNotPresent - tag: "latest" + tag: "v0.87.1" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -592,7 +592,7 @@ storage: image: repository: supabase/storage-api pullPolicy: IfNotPresent - tag: "latest" + tag: "v1.19.3" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -616,7 +616,7 @@ storage: # drop: # - ALL # readOnlyRootFilesystem: true - # runAsNonRoot: true + runAsNonRoot: true runAsUser: 1000 service: type: ClusterIP @@ -688,7 +688,7 @@ imgproxy: image: repository: darthsim/imgproxy pullPolicy: IfNotPresent - tag: "latest" + tag: "v3.8.0" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -768,7 +768,7 @@ kong: image: repository: kong pullPolicy: IfNotPresent - tag: "latest" + tag: "2.8.1" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -864,7 +864,7 @@ analytics: image: repository: supabase/logflare pullPolicy: IfNotPresent - tag: "latest" + tag: "1.12.0" imagePullSecrets: [] replicaCount: 1 nameOverride: "" @@ -904,6 +904,7 @@ analytics: LOGFLARE_SINGLE_TENANT: "true" LOGFLARE_SUPABASE_MODE: "true" FEATURE_FLAG_OVERRIDE: multibackend=true + LOGFLARE_MIN_CLUSTER_SIZE: 1 # Enable Big Query backend for analytics bigQuery: enabled: false @@ -949,12 +950,16 @@ vector: image: repository: timberio/vector pullPolicy: IfNotPresent - tag: "latest" + tag: "0.28.1-alpine" imagePullSecrets: [] replicaCount: 1 nameOverride: "" fullnameOverride: "" - livenessProbe: {} + livenessProbe: + httpGet: + path: /health + port: 9001 + initialDelaySeconds: 3 readinessProbe: {} serviceAccount: # Specifies whether a service account should be created @@ -1017,7 +1022,7 @@ functions: image: repository: supabase/edge-runtime pullPolicy: IfNotPresent - tag: "latest" + tag: "v1.67.4" imagePullSecrets: [] replicaCount: 1 nameOverride: ""