From 5dc8a97e99b5c63c3c8773c2dbb6a6957f42c4c2 Mon Sep 17 00:00:00 2001 From: Yann Autissier Date: Mon, 10 Feb 2025 00:07:05 +0100 Subject: [PATCH] update supabase to latest version --- make/def.mk | 4 +- stack/supabase/.env.dist | 1 - stack/supabase/.env.example | 6 + stack/supabase/docker-compose.yml | 273 +++++++++++++++++------------- stack/supabase/supabase.mk | 2 +- 5 files changed, 165 insertions(+), 121 deletions(-) diff --git a/make/def.mk b/make/def.mk index 082c7e5..ed2c127 100644 --- a/make/def.mk +++ b/make/def.mk @@ -175,7 +175,7 @@ INFO = $(if $(VERBOSE),$(if $(filter-out true,$(IGNORE_VERBOSE)), \ )) # macro base64t: Print trimed base64 encoded string from $1 -base64t = $(shell echo -en '$(1)' |openssl enc -A -base64 |sed 's/+/-/g;s|/|_|g;s/=*$$//;') +base64t = $(shell echo -n '$(1)' |openssl enc -A -base64 |sed 's/+/-/g;s|/|_|g;s/=*$$//;') # macro hs256: Print hmac sha256 digest from string $1 with key $2 hs256 = $(shell echo -n '$(1)' |openssl dgst -sha256 -binary -hmac '$(2)') @@ -195,7 +195,7 @@ JWT = $(strip \ $(eval b64_payload := $(call base64t,$(payload))) \ $(eval b64_signature := $(call base64t,$(call hs256,$(b64_header).$(b64_payload),$(secret)))) \ $(eval b64_signature := $(call b64_hs256,$(b64_header).$(b64_payload),$(secret))) \ - $(if $(DEBUG),$(header) - $(payload) - $(secret)) \ + $(if $(DEBUG),$(header) - $(payload) - $(secret) --- ) \ $(b64_header).$(b64_payload).$(b64_signature)) # macro RESU: Print USER associated to MAIL diff --git a/stack/supabase/.env.dist b/stack/supabase/.env.dist index c1ec3d9..ec11f5d 100644 --- a/stack/supabase/.env.dist +++ b/stack/supabase/.env.dist @@ -1,7 +1,6 @@ DOCKER_SOCKET_LOCATION=/var/run/docker.sock SUPABASE_DASHBOARD_PASSWORD=$(head -c11 /dev/random |base64 |sed 's/+/-/g;s/\//_/g;s/=*$//;') SUPABASE_JWT_IAT=${SUPABASE_JWT_IAT} -SUPABASE_JWT_EXP=${SUPABASE_JWT_EXP} # JWT_SECRET: 40 chars SUPABASE_JWT_SECRET=$(head -c30 /dev/random |base64 |sed 's/+/-/g;s/\//_/g;s/=*$//;') SUPABASE_LOGFLARE_API_KEY=$(head -c42 /dev/random |base64 |sed 's/+/-/g;s/\//_/g;s/=*$//;') diff --git a/stack/supabase/.env.example b/stack/supabase/.env.example index 1e77372..bb74500 100644 --- a/stack/supabase/.env.example +++ b/stack/supabase/.env.example @@ -9,6 +9,9 @@ ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKIC SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q DASHBOARD_USERNAME=supabase DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated +SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq +VAULT_ENC_KEY=your-encryption-key-32-chars-min + ############ # Database - You can change these to any PostgreSQL database that has logical replication enabled. @@ -19,6 +22,7 @@ POSTGRES_DB=postgres POSTGRES_PORT=5432 # default user is postgres + ############ # Supavisor -- Database pooler ############ @@ -93,12 +97,14 @@ IMGPROXY_ENABLE_WEBP_DETECTION=true # Add your OpenAI API key to enable SQL Editor Assistant OPENAI_API_KEY= + ############ # Functions - Configuration for Functions ############ # NOTE: VERIFY_JWT applies to all functions. Per-function VERIFY_JWT is not supported yet. FUNCTIONS_VERIFY_JWT=false + ############ # Logs - Configuration for Logflare # Please refer to https://supabase.com/docs/reference/self-hosting-analytics/introduction diff --git a/stack/supabase/docker-compose.yml b/stack/supabase/docker-compose.yml index 4cee961..a46e725 100644 --- a/stack/supabase/docker-compose.yml +++ b/stack/supabase/docker-compose.yml @@ -1,15 +1,17 @@ # Usage -# Start: docker compose up -# With helpers: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up -# Stop: docker compose down -# Destroy: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans +# Start: docker compose up +# With helpers: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up +# Stop: docker compose down +# Destroy: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans +# Reset everything: ./reset.sh name: supabase services: + studio: container_name: supabase-studio - image: supabase/studio:20241202-71e5240 + image: supabase/studio:20250113-83c9420 restart: unless-stopped healthcheck: test: @@ -51,11 +53,12 @@ services: container_name: supabase-kong image: kong:2.8.1 restart: unless-stopped - # https://unix.stackexchange.com/a/294837 - entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start' ports: - ${KONG_HTTP_PORT}:8000/tcp - ${KONG_HTTPS_PORT}:8443/tcp + volumes: + # https://github.com/supabase/supabase/issues/12661 + - ./volumes/api/kong.yml:/home/kong/temp.yml:ro depends_on: analytics: condition: service_healthy @@ -71,19 +74,13 @@ services: SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY} DASHBOARD_USERNAME: ${DASHBOARD_USERNAME} DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD} - volumes: - # https://github.com/supabase/supabase/issues/12661 - - ./volumes/api/kong.yml:/home/kong/temp.yml:ro + # https://unix.stackexchange.com/a/294837 + entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start' auth: container_name: supabase-auth - image: supabase/gotrue:v2.164.0 - depends_on: - db: - # Disable this if you are using an external Postgres database - condition: service_healthy - analytics: - condition: service_healthy + image: supabase/gotrue:v2.167.0 + restart: unless-stopped healthcheck: test: [ @@ -97,7 +94,12 @@ services: timeout: 5s interval: 5s retries: 3 - restart: unless-stopped + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + analytics: + condition: service_healthy environment: GOTRUE_API_HOST: 0.0.0.0 GOTRUE_API_PORT: 9999 @@ -158,20 +160,16 @@ services: # GOTRUE_HOOK_SEND_EMAIL_URI: "http://host.docker.internal:54321/functions/v1/email_sender" # GOTRUE_HOOK_SEND_EMAIL_SECRETS: "v1,whsec_VGhpcyBpcyBhbiBleGFtcGxlIG9mIGEgc2hvcnRlciBCYXNlNjQgc3RyaW5n" - - - - rest: container_name: supabase-rest image: postgrest/postgrest:v12.2.0 + restart: unless-stopped depends_on: db: # Disable this if you are using an external Postgres database condition: service_healthy analytics: condition: service_healthy - restart: unless-stopped environment: PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS} @@ -180,12 +178,16 @@ services: PGRST_DB_USE_LEGACY_GUCS: "false" PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET} PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY} - command: "postgrest" + command: + [ + "postgrest" + ] realtime: # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain container_name: realtime-dev.supabase-realtime - image: supabase/realtime:v2.33.70 + image: supabase/realtime:v2.34.7 + restart: unless-stopped depends_on: db: # Disable this if you are using an external Postgres database @@ -208,7 +210,6 @@ services: timeout: 5s interval: 5s retries: 3 - restart: unless-stopped environment: PORT: 4000 DB_HOST: ${POSTGRES_HOST} @@ -219,7 +220,7 @@ services: DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime' DB_ENC_KEY: supabaserealtime API_JWT_SECRET: ${JWT_SECRET} - SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq + SECRET_KEY_BASE: ${SECRET_KEY_BASE} ERL_AFLAGS: -proto_dist inet_tcp DNS_NODES: "''" RLIMIT_NOFILE: "10000" @@ -230,15 +231,10 @@ services: # To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up storage: container_name: supabase-storage - image: supabase/storage-api:v1.11.13 - depends_on: - db: - # Disable this if you are using an external Postgres database - condition: service_healthy - rest: - condition: service_started - imgproxy: - condition: service_started + image: supabase/storage-api:v1.14.5 + restart: unless-stopped + volumes: + - ./volumes/storage:/var/lib/storage:z healthcheck: test: [ @@ -252,7 +248,14 @@ services: timeout: 5s interval: 5s retries: 3 - restart: unless-stopped + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + rest: + condition: service_started + imgproxy: + condition: service_started environment: ANON_KEY: ${ANON_KEY} SERVICE_KEY: ${SERVICE_ROLE_KEY} @@ -268,14 +271,20 @@ services: GLOBAL_S3_BUCKET: stub ENABLE_IMAGE_TRANSFORMATION: "true" IMGPROXY_URL: http://imgproxy:5001 - volumes: - - ./volumes/storage:/var/lib/storage:z imgproxy: container_name: supabase-imgproxy image: darthsim/imgproxy:v3.8.0 + restart: unless-stopped + volumes: + - ./volumes/storage:/var/lib/storage:z healthcheck: - test: [ "CMD", "imgproxy", "health" ] + test: + [ + "CMD", + "imgproxy", + "health" + ] timeout: 5s interval: 5s retries: 3 @@ -284,19 +293,17 @@ services: IMGPROXY_LOCAL_FILESYSTEM_ROOT: / IMGPROXY_USE_ETAG: "true" IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION} - volumes: - - ./volumes/storage:/var/lib/storage:z meta: container_name: supabase-meta image: supabase/postgres-meta:v0.84.2 + restart: unless-stopped depends_on: db: # Disable this if you are using an external Postgres database condition: service_healthy analytics: condition: service_healthy - restart: unless-stopped environment: PG_META_PORT: 8080 PG_META_DB_HOST: ${POSTGRES_HOST} @@ -307,8 +314,10 @@ services: functions: container_name: supabase-edge-functions - image: supabase/edge-runtime:v1.65.3 + image: supabase/edge-runtime:v1.66.5 restart: unless-stopped + volumes: + - ./volumes/functions:/home/deno/functions:Z depends_on: analytics: condition: service_healthy @@ -320,32 +329,39 @@ services: SUPABASE_DB_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} # TODO: Allow configuring VERIFY_JWT per function. This PR might help: https://github.com/supabase/cli/pull/786 VERIFY_JWT: "${FUNCTIONS_VERIFY_JWT}" - volumes: - - ./volumes/functions:/home/deno/functions:Z command: - - start - - --main-service - - /home/deno/functions/main + [ + "start", + "--main-service", + "/home/deno/functions/main" + ] analytics: container_name: supabase-analytics image: supabase/logflare:1.4.0 - healthcheck: - test: [ "CMD", "curl", "http://localhost:4000/health" ] - timeout: 5s - interval: 5s - retries: 10 restart: unless-stopped - depends_on: - db: - # Disable this if you are using an external Postgres database - condition: service_healthy + ports: + - 4000:4000 # Uncomment to use Big Query backend for analytics # volumes: # - type: bind # source: ${PWD}/gcloud.json # target: /opt/app/rel/logflare/bin/gcloud.json # read_only: true + healthcheck: + test: + [ + "CMD", + "curl", + "http://localhost:4000/health" + ] + timeout: 5s + interval: 5s + retries: 10 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy environment: LOGFLARE_NODE_HOST: 127.0.0.1 DB_USERNAME: supabase_admin @@ -366,38 +382,12 @@ services: # Uncomment to use Big Query backend for analytics # GOOGLE_PROJECT_ID: ${GOOGLE_PROJECT_ID} # GOOGLE_PROJECT_NUMBER: ${GOOGLE_PROJECT_NUMBER} - ports: - - 4000:4000 # Comment out everything below this point if you are using an external Postgres database db: container_name: supabase-db - image: supabase/postgres:15.6.1.146 - healthcheck: - test: pg_isready -U postgres -h localhost - interval: 5s - timeout: 5s - retries: 10 - depends_on: - vector: - condition: service_healthy - command: - - postgres - - -c - - config_file=/etc/postgresql/postgresql.conf - - -c - - log_min_messages=fatal # prevents Realtime polling queries from appearing in logs + image: supabase/postgres:15.8.1.020 restart: unless-stopped - environment: - POSTGRES_HOST: /var/run/postgresql - PGPORT: ${POSTGRES_PORT} - POSTGRES_PORT: ${POSTGRES_PORT} - PGPASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - PGDATABASE: ${POSTGRES_DB} - POSTGRES_DB: ${POSTGRES_DB} - JWT_SECRET: ${JWT_SECRET} - JWT_EXP: ${JWT_EXPIRY} volumes: - ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z # Must be superuser to create event trigger @@ -416,14 +406,51 @@ services: - ./volumes/db/pooler.sql:/docker-entrypoint-initdb.d/migrations/99-pooler.sql:Z # Use named volume to persist pgsodium decryption key between restarts - db-config:/etc/postgresql-custom + healthcheck: + test: + [ + "CMD", + "pg_isready", + "-U", + "postgres", + "-h", + "localhost" + ] + interval: 5s + timeout: 5s + retries: 10 + depends_on: + vector: + condition: service_healthy + environment: + POSTGRES_HOST: /var/run/postgresql + PGPORT: ${POSTGRES_PORT} + POSTGRES_PORT: ${POSTGRES_PORT} + PGPASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATABASE: ${POSTGRES_DB} + POSTGRES_DB: ${POSTGRES_DB} + JWT_SECRET: ${JWT_SECRET} + JWT_EXP: ${JWT_EXPIRY} + command: + [ + "postgres", + "-c", + "config_file=/etc/postgresql/postgresql.conf", + "-c", + "log_min_messages=fatal" # prevents Realtime polling queries from appearing in logs + ] vector: container_name: supabase-vector image: timberio/vector:0.28.1-alpine + restart: unless-stopped + volumes: + - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro + - ${DOCKER_SOCKET_LOCATION}:/var/run/docker.sock:ro healthcheck: test: [ - "CMD", "wget", "--no-verbose", @@ -434,19 +461,35 @@ services: timeout: 5s interval: 5s retries: 3 - volumes: - - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro - - ${DOCKER_SOCKET_LOCATION:-/var/run/docker.sock}:/var/run/docker.sock:ro environment: LOGFLARE_API_KEY: ${LOGFLARE_API_KEY} - command: [ "--config", "/etc/vector/vector.yml" ] + command: + [ + "--config", + "/etc/vector/vector.yml" + ] # Update the DATABASE_URL if you are using an external Postgres database supavisor: container_name: supabase-pooler image: supabase/supavisor:1.1.56 + restart: unless-stopped + ports: + - ${POSTGRES_PORT}:5432 + - ${POOLER_PROXY_PORT_TRANSACTION}:6543 + volumes: + - ./volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro healthcheck: - test: curl -sSfL --head -o /dev/null "http://127.0.0.1:4000/api/health" + test: + [ + "CMD", + "curl", + "-sSfL", + "--head", + "-o", + "/dev/null", + "http://127.0.0.1:4000/api/health" + ] interval: 10s timeout: 5s retries: 5 @@ -455,33 +498,29 @@ services: condition: service_healthy analytics: condition: service_healthy - command: - - /bin/sh - - -c - - /app/bin/migrate && /app/bin/supavisor eval "$$(cat /etc/pooler/pooler.exs)" && /app/bin/server - restart: unless-stopped - ports: - - ${POSTGRES_PORT}:5432 - - ${POOLER_PROXY_PORT_TRANSACTION}:6543 environment: - - PORT=4000 - - POSTGRES_PORT=${POSTGRES_PORT} - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - DATABASE_URL=ecto://supabase_admin:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/_supabase - - CLUSTER_POSTGRES=true - - SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq - - VAULT_ENC_KEY=your-encryption-key-32-chars-min - - API_JWT_SECRET=${JWT_SECRET} - - METRICS_JWT_SECRET=${JWT_SECRET} - - REGION=local - - ERL_AFLAGS=-proto_dist inet_tcp - - POOLER_TENANT_ID=${POOLER_TENANT_ID} - - POOLER_DEFAULT_POOL_SIZE=${POOLER_DEFAULT_POOL_SIZE} - - POOLER_MAX_CLIENT_CONN=${POOLER_MAX_CLIENT_CONN} - - POOLER_POOL_MODE=transaction - volumes: - - ./volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro + PORT: 4000 + POSTGRES_PORT: ${POSTGRES_PORT} + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_URL: ecto://supabase_admin:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/_supabase + CLUSTER_POSTGRES: true + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + VAULT_ENC_KEY: ${VAULT_ENC_KEY} + API_JWT_SECRET: ${JWT_SECRET} + METRICS_JWT_SECRET: ${JWT_SECRET} + REGION: local + ERL_AFLAGS: -proto_dist inet_tcp + POOLER_TENANT_ID: ${POOLER_TENANT_ID} + POOLER_DEFAULT_POOL_SIZE: ${POOLER_DEFAULT_POOL_SIZE} + POOLER_MAX_CLIENT_CONN: ${POOLER_MAX_CLIENT_CONN} + POOLER_POOL_MODE: transaction + command: + [ + "/bin/sh", + "-c", + "/app/bin/migrate && /app/bin/supavisor eval \"$$(cat /etc/pooler/pooler.exs)\" && /app/bin/server" + ] volumes: db-config: diff --git a/stack/supabase/supabase.mk b/stack/supabase/supabase.mk index 39c41e3..f1d1ba3 100644 --- a/stack/supabase/supabase.mk +++ b/stack/supabase/supabase.mk @@ -1,4 +1,4 @@ -ENV_VARS += SUPABASE_ADDITIONAL_REDIRECT_URLS SUPABASE_ANON_KEY SUPABASE_JWT_IAT SUPABASE_JWT_EXP SUPABASE_KONG_SERVICE_8000_TAGS SUPABASE_PUBLIC_URL SUPABASE_REALTIME_TENANT SUPABASE_SERVICE_ROLE_KEY SUPABASE_EDGE_RUNTIME_VERSION SUPABASE_KONG_VERSION SUPABASE_POSTGRES_VERSION SUPABASE_VECTOR_VERSION +ENV_VARS += SUPABASE_ADDITIONAL_REDIRECT_URLS SUPABASE_ANON_KEY SUPABASE_JWT_IAT SUPABASE_KONG_SERVICE_8000_TAGS SUPABASE_PUBLIC_URL SUPABASE_REALTIME_TENANT SUPABASE_SERVICE_ROLE_KEY SUPABASE_EDGE_RUNTIME_VERSION SUPABASE_KONG_VERSION SUPABASE_POSTGRES_VERSION SUPABASE_VECTOR_VERSION SUPABASE_ADDITIONAL_REDIRECT_URLS ?= $(subst $(space),$(comma),$(call url,SUPABASE)) SUPABASE_ANON_KEY ?= $(call JWT,,$(SUPABASE_JWT_PAYLOAD_ANON),$(SUPABASE_JWT_SECRET)) SUPABASE_DOCKER_IMAGES ?= supabase/edge-runtime:$(SUPABASE_EDGE_RUNTIME_VERSION) kong:$(SUPABASE_KONG_VERSION) supabase/postgres:$(SUPABASE_POSTGRES_VERSION) timberio/vector:$(SUPABASE_VECTOR_VERSION)