From d3288ad3c2dbf5112807af607e753b6ee5dd15fc Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Tue, 6 Oct 2026 07:03:47 +0000 Subject: [PATCH] dev2 supabase kit: auth reads volumes/auth/auth.env The base Supabase compose file ships every GOTRUE_SMS_* line commented out, and the overlay gave auth no way to add them, so a stack had phone sign-in enabled with no SMS provider: qrypt.chat answered every SMS login with "Unable to get SMS provider". auth now gets an env_file (volumes/auth/auth.env, created empty 0600 in both modes) for a site's GOTRUE_* extras; environment: in the base file still wins. Co-Authored-By: Claude Opus 5.5 --- dev2/README.md | 2 +- dev2/templates/supabase-stack.sh | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dev2/README.md b/dev2/README.md index cbef035..46131cf 100644 --- a/dev2/README.md +++ b/dev2/README.md @@ -32,7 +32,7 @@ dev2-site migrate --yes the whole move, resumable; each step below is a | `railway-stop` | `deploymentRemove` + `serviceDisconnect` (or the next push silently redeploys on Railway) | | `merge` | merges the scaffold PR; CI deploys the default branch to dev2 | | `retire` | `--yes`: `serviceDelete` for the app, companions and data services. Only after `verify --public` | -| `supabase-stack` | (kind `supabase`, second pass) a self-hosted Supabase stack of its own under `~/www//supabase` (compose project `-supabase`, api `8200+n`, db `5500+n`, pooler `6600+n`, subnet `172.31.(100+n).0/24`, `n = port-3200`), public host `supabase.` added to the site's cert/vhost/dns via `sites.d` | +| `supabase-stack` | (kind `supabase`, second pass) a self-hosted Supabase stack of its own under `~/www//supabase` (compose project `-supabase`, api `8200+n`, db `5500+n`, pooler `6600+n`, subnet `172.31.(100+n).0/24`, `n = port-3200`), public host `supabase.` added to the site's cert/vhost/dns via `sites.d`. The `auth` service also reads `volumes/auth/auth.env` (created empty, 0600), which holds the site's `GOTRUE_*` settings that the base compose file only ships commented out. For example, phone sign-in needs `GOTRUE_SMS_PROVIDER=twilio` and the `GOTRUE_SMS_TWILIO_*` credentials there | | `supabase-pull` | dumps the cloud project through its session pooler (password from the app's `SUPABASE_DB_PASSWORD`, or `--reset-password` through the management API) into `/root/dumps/-supabase-` | | `supabase-load` | loads it (extensions, schema, data, grants, buckets, absolute storage-URL rewrite over every text/json column, realtime, cron) | | `supabase-storage` | copies every Storage object through the two Storage APIs (node in a container on dev2; resumable) | diff --git a/dev2/templates/supabase-stack.sh b/dev2/templates/supabase-stack.sh index e00f576..d4456b0 100755 --- a/dev2/templates/supabase-stack.sh +++ b/dev2/templates/supabase-stack.sh @@ -66,6 +66,13 @@ backup_ext() { local f=$1 d b stem ext n=1; [ -e "$f" ] || return 0; d=$(dirname backup() { local f=$1 n=1; [ -e "$f" ] || return 0; while [ -e "$f.bak-$(printf %03d $n)" ]; do n=$((n+1)); done; cp -a "$f" "$f.bak-$(printf %03d $n)"; } set_env() { local k=$1 v=$2; if grep -q "^$k=" "$DIR/.env"; then awk -v k="$k" -v v="$v" 'BEGIN{FS="="} $1==k {print k "=" v; next} {print}' "$DIR/.env" > "$DIR/.env.tmp" && mv "$DIR/.env.tmp" "$DIR/.env"; else printf '%s=%s\n' "$k" "$v" >> "$DIR/.env"; fi; } get_env() { grep "^$1=" "$DIR/.env" | head -n1 | cut -d= -f2-; } +# Files the overlay names in env_file must exist, empty is fine. auth.env holds a +# site's GOTRUE_* extras (e.g. GOTRUE_SMS_PROVIDER=twilio + its credentials for +# phone sign-in), which the base compose file only ships commented out. +ensure_env_files() { + [ -f "$DIR/volumes/functions/secrets.env" ] || { install -d "$DIR/volumes/functions"; (umask 077; : > "$DIR/volumes/functions/secrets.env"); } + [ -f "$DIR/volumes/auth/auth.env" ] || { install -d "$DIR/volumes/auth"; (umask 077; : > "$DIR/volumes/auth/auth.env"); } +} compose() { (cd "$DIR" && docker compose "$@"); } DBC="$SLUG-supabase-db" sql_admin() { docker exec -i "$DBC" psql -U supabase_admin -h localhost -d postgres -v ON_ERROR_STOP=1 -X -q -At "$@"; } @@ -95,6 +102,7 @@ render_overlay() { api-gw) echo " networks:"; echo " default:"; echo " aliases: [envoy, kong]"; echo " ports: !override"; echo " - \"127.0.0.1:${API_PORT}:8000/tcp\"" ;; supavisor) echo " ports: !override"; echo " - \"127.0.0.1:${POOLER_PORT}:6543\"" ;; storage) echo " environment:"; echo " FILE_SIZE_LIMIT: 5368709120" ;; # the base file pins 50 MiB; buckets declare up to GiBs + auth) echo " env_file:"; echo " - ./volumes/auth/auth.env" ;; # per-site GOTRUE_* extras the base file leaves commented (SMS provider, hooks); environment: still wins functions) echo " env_file:"; echo " - .env"; echo " - ./volumes/functions/secrets.env" ;; # cloud function secrets (supabase-functions) db) echo " shm_size: 512m"; echo " ports: !override"; echo " - \"${DB_PORT}:5432\""; echo " volumes:" echo " - ./volumes/$SLUG/$SLUG.conf:/etc/postgresql-custom/conf.d/zz-$SLUG.conf:ro,z" @@ -145,7 +153,7 @@ lean_overlay() { # dropped services (or creates restored ones). db is never recreated here. if [ "$MODE" = services ]; then [ -f "$DIR/.env" ] && [ -f "$DIR/docker-compose.$SLUG.yml" ] || die "no stack at $DIR; run the full supabase-stack first" - cd "$DIR" + cd "$DIR"; ensure_env_files new="$DIR/.docker-compose.$SLUG.yml.new"; (umask 027; lean_overlay "$DIR/docker-compose.$SLUG.yml" > "$new") # every file COMPOSE_FILE lists, with this overlay swapped for the new one fargs=(); IFS=: read -ra cfs <<< "$(get_env COMPOSE_FILE)"; [ ${#cfs[@]} -gt 0 ] || die "no COMPOSE_FILE in $DIR/.env" @@ -278,7 +286,7 @@ chown "$PG_UID:$PG_GID" "$V/tls/server.key" "$V/tls/server.crt" log "Overlay docker-compose.$SLUG.yml (own project name, container names, ports, subnet; dropped: ${DROP_SERVICES:-none})" render_overlay > "$DIR/docker-compose.$SLUG.yml" -[ -f "$DIR/volumes/functions/secrets.env" ] || { install -d "$DIR/volumes/functions"; (umask 077; : > "$DIR/volumes/functions/secrets.env"); } +ensure_env_files # ---------------------------------------------------------------- 3. start log "Starting $SLUG-supabase"