diff --git a/docker-compose.yml b/docker-compose.yml index 70adce5..6848ad2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,9 @@ services: JWT_EXP: ${JWT_EXPIRY:-3600} volumes: - db-data:/var/lib/postgresql/data - # Migrations mounted separately - DO NOT use /docker-entrypoint-initdb.d (overwrites Supabase init) + # Init script to create schemas (runs first due to 00- prefix) + - ./supabase/docker/00-init-schemas.sql:/docker-entrypoint-initdb.d/00-init-schemas.sql:ro + # Migrations mounted separately for manual execution - ./supabase/migrations:/migrations:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] diff --git a/supabase/docker/00-init-schemas.sql b/supabase/docker/00-init-schemas.sql new file mode 100644 index 0000000..1914780 --- /dev/null +++ b/supabase/docker/00-init-schemas.sql @@ -0,0 +1,93 @@ +-- Initialize required schemas and roles for Supabase services +-- This runs FIRST (00- prefix) before other init scripts + +-- Create roles if they don't exist +DO $$ +BEGIN + -- Create anon role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'anon') THEN + CREATE ROLE anon NOLOGIN NOINHERIT; + END IF; + + -- Create authenticated role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticated') THEN + CREATE ROLE authenticated NOLOGIN NOINHERIT; + END IF; + + -- Create service_role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'service_role') THEN + CREATE ROLE service_role NOLOGIN NOINHERIT BYPASSRLS; + END IF; + + -- Create supabase_admin role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_admin') THEN + CREATE ROLE supabase_admin LOGIN SUPERUSER CREATEDB CREATEROLE REPLICATION BYPASSRLS; + END IF; + + -- Create authenticator role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticator') THEN + CREATE ROLE authenticator NOINHERIT LOGIN; + END IF; + + -- Create supabase_auth_admin role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_auth_admin') THEN + CREATE ROLE supabase_auth_admin NOLOGIN NOINHERIT; + END IF; + + -- Create supabase_storage_admin role + IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_storage_admin') THEN + CREATE ROLE supabase_storage_admin NOLOGIN NOINHERIT; + END IF; +END +$$; + +-- Grant roles +GRANT anon TO authenticator; +GRANT authenticated TO authenticator; +GRANT service_role TO authenticator; +GRANT supabase_admin TO postgres; + +-- Set passwords (use the same as postgres password from env) +-- Note: These are set via ALTER ROLE since we can't use variables in CREATE ROLE +ALTER ROLE supabase_admin WITH PASSWORD 'postgres'; +ALTER ROLE authenticator WITH PASSWORD 'postgres'; + +-- Create schemas +CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_auth_admin; +CREATE SCHEMA IF NOT EXISTS storage AUTHORIZATION supabase_storage_admin; +CREATE SCHEMA IF NOT EXISTS extensions; +CREATE SCHEMA IF NOT EXISTS _realtime; +CREATE SCHEMA IF NOT EXISTS graphql; +CREATE SCHEMA IF NOT EXISTS graphql_public; + +-- Grant schema usage +GRANT USAGE ON SCHEMA public TO anon, authenticated, service_role; +GRANT USAGE ON SCHEMA auth TO anon, authenticated, service_role, supabase_auth_admin; +GRANT USAGE ON SCHEMA storage TO anon, authenticated, service_role, supabase_storage_admin; +GRANT USAGE ON SCHEMA extensions TO anon, authenticated, service_role; +GRANT USAGE ON SCHEMA graphql_public TO anon, authenticated, service_role; + +-- Grant auth schema to supabase_auth_admin +GRANT ALL ON SCHEMA auth TO supabase_auth_admin; +GRANT ALL ON ALL TABLES IN SCHEMA auth TO supabase_auth_admin; +GRANT ALL ON ALL SEQUENCES IN SCHEMA auth TO supabase_auth_admin; +GRANT ALL ON ALL ROUTINES IN SCHEMA auth TO supabase_auth_admin; + +-- Grant storage schema to supabase_storage_admin +GRANT ALL ON SCHEMA storage TO supabase_storage_admin; +GRANT ALL ON ALL TABLES IN SCHEMA storage TO supabase_storage_admin; +GRANT ALL ON ALL SEQUENCES IN SCHEMA storage TO supabase_storage_admin; +GRANT ALL ON ALL ROUTINES IN SCHEMA storage TO supabase_storage_admin; + +-- Set default privileges +ALTER DEFAULT PRIVILEGES IN SCHEMA auth GRANT ALL ON TABLES TO supabase_auth_admin; +ALTER DEFAULT PRIVILEGES IN SCHEMA auth GRANT ALL ON SEQUENCES TO supabase_auth_admin; +ALTER DEFAULT PRIVILEGES IN SCHEMA storage GRANT ALL ON TABLES TO supabase_storage_admin; +ALTER DEFAULT PRIVILEGES IN SCHEMA storage GRANT ALL ON SEQUENCES TO supabase_storage_admin; + +-- Set search path +ALTER DATABASE postgres SET search_path TO public, extensions; + +-- Create extensions in extensions schema +CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA extensions; +CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA extensions;