From eae6905d428cc071a4dc458f3a49656c4353d18d Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 1 Nov 2022 12:26:12 +0800 Subject: [PATCH] chore: update self hosted to use latest postgres image (#9973) * chore: remove outdated migration files * chore: update docker compose to use latest images * chore: remove commented lines * chore: update default role passwords * chore: add no restart flag in dev * chore: update example env * chore: add comments * chore: bump storage and studio images * chore: default pgmeta to use admin role * chore: do not update su role --- docker/.env.example | 2 +- docker/.gitignore | 1 - docker/dev/docker-compose.dev.yml | 11 +- docker/docker-compose.yml | 54 ++++--- docker/volumes/db/init/00-initial-schema.sql | 48 ------ docker/volumes/db/init/01-auth-schema.sql | 145 ----------------- docker/volumes/db/init/02-storage-schema.sql | 116 ------------- docker/volumes/db/init/03-post-setup.sql | 68 -------- docker/volumes/db/init/04-pg-graphql.sql | 162 ------------------- docker/volumes/db/roles.sql | 7 + 10 files changed, 49 insertions(+), 565 deletions(-) delete mode 100644 docker/volumes/db/init/00-initial-schema.sql delete mode 100644 docker/volumes/db/init/01-auth-schema.sql delete mode 100644 docker/volumes/db/init/02-storage-schema.sql delete mode 100644 docker/volumes/db/init/03-post-setup.sql delete mode 100644 docker/volumes/db/init/04-pg-graphql.sql create mode 100644 docker/volumes/db/roles.sql diff --git a/docker/.env.example b/docker/.env.example index eee55a93768..aa0ee2f2148 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -55,7 +55,7 @@ MAILER_URLPATHS_EMAIL_CHANGE="/auth/v1/verify" ENABLE_EMAIL_SIGNUP=true ENABLE_EMAIL_AUTOCONFIRM=false SMTP_ADMIN_EMAIL=admin@example.com -SMTP_HOST=mail +SMTP_HOST=supabase-mail SMTP_PORT=2500 SMTP_USER=fake_mail_user SMTP_PASS=fake_mail_password diff --git a/docker/.gitignore b/docker/.gitignore index e5c6762c078..33c83313c67 100644 --- a/docker/.gitignore +++ b/docker/.gitignore @@ -1,5 +1,4 @@ volumes/db/data -volumes/db/init/data.sql volumes/storage .env test.http diff --git a/docker/dev/docker-compose.dev.yml b/docker/dev/docker-compose.dev.yml index 49ec4c7370e..136c34ab3e0 100644 --- a/docker/dev/docker-compose.dev.yml +++ b/docker/dev/docker-compose.dev.yml @@ -3,18 +3,23 @@ version: "3.8" services: mail: container_name: supabase-mail - image: inbucket/inbucket:stable + image: inbucket/inbucket:3.0.3 ports: - '2500:2500' # SMTP - '9000:9000' # web interface - '1100:1100' # POP3 + auth: + environment: + - GOTRUE_SMTP_USER= + - GOTRUE_SMTP_PASS= meta: ports: - 5555:8080 db: + restart: 'no' volumes: - - /var/lib/postgresql/data - - ./dev/data.sql:/docker-entrypoint-initdb.d/data.sql + # Seed data should be inserted last (alphabetical order) + - ./dev/data.sql:/docker-entrypoint-initdb.d/seed.sql storage: volumes: - /var/lib/storage diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 40fbf557243..bfcf022d9bc 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -9,7 +9,7 @@ version: "3.8" services: studio: container_name: supabase-studio - image: supabase/studio:latest + image: supabase/studio:0.22.08 restart: unless-stopped ports: - ${STUDIO_PORT}:3000/tcp @@ -27,7 +27,7 @@ services: kong: container_name: supabase-kong - image: kong:2.1 + image: kong:2.8.1 restart: unless-stopped ports: - ${KONG_HTTP_PORT}:8000/tcp @@ -41,13 +41,14 @@ services: KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k volumes: - - ./volumes/api:/var/lib/kong + - ./volumes/api:/var/lib/kong:ro auth: container_name: supabase-auth image: supabase/gotrue:v2.19.4 depends_on: - - db # Disable this if you are using an external Postgres database + db: # Disable this if you are using an external Postgres database + condition: service_healthy restart: unless-stopped environment: GOTRUE_API_HOST: 0.0.0.0 @@ -55,7 +56,7 @@ services: API_EXTERNAL_URL: ${API_EXTERNAL_URL} GOTRUE_DB_DRIVER: postgres - GOTRUE_DB_DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=auth + GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} GOTRUE_SITE_URL: ${SITE_URL} GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS} @@ -69,6 +70,8 @@ services: GOTRUE_EXTERNAL_EMAIL_ENABLED: ${ENABLE_EMAIL_SIGNUP} GOTRUE_MAILER_AUTOCONFIRM: ${ENABLE_EMAIL_AUTOCONFIRM} + # GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED: true + # GOTRUE_SMTP_MAX_FREQUENCY: 1s GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL} GOTRUE_SMTP_HOST: ${SMTP_HOST} GOTRUE_SMTP_PORT: ${SMTP_PORT} @@ -85,12 +88,13 @@ services: rest: container_name: supabase-rest - image: postgrest/postgrest:v9.0.1 + image: postgrest/postgrest:v9.0.1.20220717 depends_on: - - db # Disable this if you are using an external Postgres database + db: # Disable this if you are using an external Postgres database + condition: service_healthy restart: unless-stopped environment: - PGRST_DB_URI: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS} PGRST_DB_ANON_ROLE: anon PGRST_JWT_SECRET: ${JWT_SECRET} @@ -100,13 +104,14 @@ services: container_name: supabase-realtime image: supabase/realtime:v0.25.1 depends_on: - - db # Disable this if you are using an external Postgres database + db: # Disable this if you are using an external Postgres database + condition: service_healthy restart: unless-stopped environment: DB_HOST: ${POSTGRES_HOST} DB_PORT: ${POSTGRES_PORT} DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} + DB_USER: supabase_admin DB_PASSWORD: ${POSTGRES_PASSWORD} DB_SSL: "false" PORT: 4000 @@ -122,18 +127,19 @@ services: storage: container_name: supabase-storage - image: supabase/storage-api:v0.10.0 + image: supabase/storage-api:v0.21.4 depends_on: - - db # Disable this if you are using an external Postgres database - - rest + db: # Disable this if you are using an external Postgres database + condition: service_healthy + rest: + condition: service_started restart: unless-stopped environment: ANON_KEY: ${ANON_KEY} SERVICE_KEY: ${SERVICE_ROLE_KEY} POSTGREST_URL: http://rest:3000 PGRST_JWT_SECRET: ${JWT_SECRET} - DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} - PGOPTIONS: -c search_path=storage,public + DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} FILE_SIZE_LIMIT: 52428800 STORAGE_BACKEND: file FILE_STORAGE_BACKEND_PATH: /var/lib/storage @@ -146,22 +152,28 @@ services: meta: container_name: supabase-meta - image: supabase/postgres-meta:v0.29.0 + image: supabase/postgres-meta:v0.50.2 depends_on: - - db # Disable this if you are using an external Postgres database + db: # Disable this if you are using an external Postgres database + condition: service_healthy restart: unless-stopped environment: PG_META_PORT: 8080 PG_META_DB_HOST: ${POSTGRES_HOST} PG_META_DB_PORT: ${POSTGRES_PORT} PG_META_DB_NAME: ${POSTGRES_DB} - PG_META_DB_USER: ${POSTGRES_USER} + PG_META_DB_USER: supabase_admin PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD} # Comment out everything below this point if you are using an external Postgres database db: container_name: supabase-db - image: supabase/postgres:14.1.0.77 + image: supabase/postgres:14.1.0.82 + healthcheck: + test: pg_isready -U postgres -h localhost + interval: 5s + timeout: 5s + retries: 10 command: - postgres - -c @@ -172,7 +184,7 @@ services: ports: - ${POSTGRES_PORT}:5432 environment: + POSTGRES_HOST: /var/run/postgresql POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - # - ./volumes/db/data:/var/lib/postgresql/data - - ./volumes/db/init:/docker-entrypoint-initdb.d + - ./volumes/db/roles.sql:/docker-entrypoint-initdb.d/roles.sql diff --git a/docker/volumes/db/init/00-initial-schema.sql b/docker/volumes/db/init/00-initial-schema.sql deleted file mode 100644 index 474b866773a..00000000000 --- a/docker/volumes/db/init/00-initial-schema.sql +++ /dev/null @@ -1,48 +0,0 @@ --- Set up realtime -create schema if not exists realtime; --- create publication supabase_realtime; -- defaults to empty publication -create publication supabase_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'; diff --git a/docker/volumes/db/init/01-auth-schema.sql b/docker/volumes/db/init/01-auth-schema.sql deleted file mode 100644 index 3544f9afb04..00000000000 --- a/docker/volumes/db/init/01-auth-schema.sql +++ /dev/null @@ -1,145 +0,0 @@ - -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 -$$; - -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 -$$; - --- usage on auth functions to API roles -GRANT USAGE ON SCHEMA auth TO anon, authenticated, service_role; - --- 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; diff --git a/docker/volumes/db/init/02-storage-schema.sql b/docker/volumes/db/init/02-storage-schema.sql deleted file mode 100644 index ba891b018b7..00000000000 --- a/docker/volumes/db/init/02-storage-schema.sql +++ /dev/null @@ -1,116 +0,0 @@ -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; diff --git a/docker/volumes/db/init/03-post-setup.sql b/docker/volumes/db/init/03-post-setup.sql deleted file mode 100644 index 64dc7399fd5..00000000000 --- a/docker/volumes/db/init/03-post-setup.sql +++ /dev/null @@ -1,68 +0,0 @@ -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 pgrst, 'reload schema'; -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; diff --git a/docker/volumes/db/init/04-pg-graphql.sql b/docker/volumes/db/init/04-pg-graphql.sql deleted file mode 100644 index a3eb7b9ede0..00000000000 --- a/docker/volumes/db/init/04-pg-graphql.sql +++ /dev/null @@ -1,162 +0,0 @@ -create schema if not exists graphql_public; - --- GraphQL Placeholder Entrypoint -create or replace function graphql_public.graphql( - "operationName" text default null, - query text default null, - variables jsonb default null, - extensions jsonb default null -) - returns jsonb - language plpgsql -as $$ - DECLARE - server_version float; - BEGIN - server_version = (SELECT (SPLIT_PART((select version()), ' ', 2))::float); - - IF server_version >= 14 THEN - RETURN jsonb_build_object( - 'errors', jsonb_build_array( - jsonb_build_object( - 'message', 'pg_graphql extension is not enabled.' - ) - ) - ); - ELSE - RETURN jsonb_build_object( - 'errors', jsonb_build_array( - jsonb_build_object( - 'message', 'pg_graphql is only available on projects running Postgres 14 onwards.' - ) - ) - ); - END IF; - END; -$$; - -grant usage on schema graphql_public to postgres, anon, authenticated, service_role; -alter default privileges in schema graphql_public grant all on tables to postgres, anon, authenticated, service_role; -alter default privileges in schema graphql_public grant all on functions to postgres, anon, authenticated, service_role; -alter default privileges in schema graphql_public grant all on sequences to postgres, anon, authenticated, service_role; - -alter default privileges for user supabase_admin in schema graphql_public grant all - on sequences to postgres, anon, authenticated, service_role; -alter default privileges for user supabase_admin in schema graphql_public grant all - on tables to postgres, anon, authenticated, service_role; -alter default privileges for user supabase_admin in schema graphql_public grant all - on functions to postgres, anon, authenticated, service_role; - --- Trigger upon enabling pg_graphql -create or replace function extensions.grant_pg_graphql_access() - returns event_trigger - language plpgsql -AS $func$ -DECLARE - func_is_graphql_resolve bool; -BEGIN - func_is_graphql_resolve = ( - SELECT n.proname = 'resolve' - FROM pg_event_trigger_ddl_commands() AS ev - LEFT JOIN pg_catalog.pg_proc AS n - ON ev.objid = n.oid - ); - - IF func_is_graphql_resolve - THEN - grant usage on schema graphql to postgres, anon, authenticated, service_role; - grant all on function graphql.resolve to postgres, anon, authenticated, service_role; - - alter default privileges in schema graphql grant all on tables to postgres, anon, authenticated, service_role; - alter default privileges in schema graphql grant all on functions to postgres, anon, authenticated, service_role; - alter default privileges in schema graphql grant all on sequences to postgres, anon, authenticated, service_role; - - -- Update public wrapper to pass all arguments through to the pg_graphql resolve func - create or replace function graphql_public.graphql( - "operationName" text default null, - query text default null, - variables jsonb default null, - extensions jsonb default null - ) - returns jsonb - language sql - as $$ - select graphql.resolve( - query := query, - variables := coalesce(variables, '{}'), - "operationName" := "operationName", - extensions := extensions - ); - $$; - - grant select on graphql.field, graphql.type, graphql.enum_value to postgres, anon, authenticated, service_role; - grant execute on function graphql.resolve to postgres, anon, authenticated, service_role; - END IF; - -END; -$func$; - -CREATE EVENT TRIGGER issue_pg_graphql_access ON ddl_command_end WHEN TAG in ('CREATE FUNCTION') -EXECUTE PROCEDURE extensions.grant_pg_graphql_access(); -COMMENT ON FUNCTION extensions.grant_pg_graphql_access IS 'Grants access to pg_graphql'; - --- Trigger upon dropping the pg_graphql extension -CREATE OR REPLACE FUNCTION extensions.set_graphql_placeholder() -RETURNS event_trigger -LANGUAGE plpgsql -AS $func$ - DECLARE - graphql_is_dropped bool; - BEGIN - graphql_is_dropped = ( - SELECT ev.schema_name = 'graphql_public' - FROM pg_event_trigger_dropped_objects() AS ev - WHERE ev.schema_name = 'graphql_public' - ); - - IF graphql_is_dropped - THEN - create or replace function graphql_public.graphql( - "operationName" text default null, - query text default null, - variables jsonb default null, - extensions jsonb default null - ) - returns jsonb - language plpgsql - as $$ - DECLARE - server_version float; - BEGIN - server_version = (SELECT (SPLIT_PART((select version()), ' ', 2))::float); - - IF server_version >= 14 THEN - RETURN jsonb_build_object( - 'errors', jsonb_build_array( - jsonb_build_object( - 'message', 'pg_graphql extension is not enabled.' - ) - ) - ); - ELSE - RETURN jsonb_build_object( - 'errors', jsonb_build_array( - jsonb_build_object( - 'message', 'pg_graphql is only available on projects running Postgres 14 onwards.' - ) - ) - ); - END IF; - END; - $$; - END IF; - - END; -$func$; - -CREATE EVENT TRIGGER issue_graphql_placeholder ON sql_drop WHEN TAG in ('DROP EXTENSION') -EXECUTE PROCEDURE extensions.set_graphql_placeholder(); -COMMENT ON FUNCTION extensions.set_graphql_placeholder IS 'Reintroduces placeholder function for graphql_public.graphql'; - -drop extension if exists pg_graphql; -create extension if not exists pg_graphql; \ No newline at end of file diff --git a/docker/volumes/db/roles.sql b/docker/volumes/db/roles.sql new file mode 100644 index 00000000000..b369bf5af99 --- /dev/null +++ b/docker/volumes/db/roles.sql @@ -0,0 +1,7 @@ +-- NOTE: change to your own passwords for production environments +\set pgpass `echo "$PGPASSWORD"` + +ALTER USER authenticator WITH PASSWORD :'pgpass'; +ALTER USER pgbouncer WITH PASSWORD :'pgpass'; +ALTER USER supabase_auth_admin WITH PASSWORD :'pgpass'; +ALTER USER supabase_storage_admin WITH PASSWORD :'pgpass';