mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: update self-host setup
This commit is contained in:
1 parent
2bcbf04129
commit
0e036d4948
13 files changed
+374
-284
No files matched your search
-29
@@ -1,29 +0,0 @@
|
||||
# fill with random passwords
|
||||
OPERATOR_TOKEN=your-super-secret-operator-token
|
||||
|
||||
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
|
||||
|
||||
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
|
||||
# some SMTP server to send your auth-mails with
|
||||
SMTP_HOST=smtp.mailgun.org
|
||||
SMTP_PORT=25
|
||||
SMTP_USER=
|
||||
SMTP_PASS=
|
||||
SMTP_ADMIN_EMAIL=
|
||||
|
||||
# storage config
|
||||
STORAGE_BACKEND=file # file | s3
|
||||
STORAGE_S3_BUCKET=supa-storage-testing # name of s3 bucket where you want to store objects
|
||||
STORAGE_REGION=us-east-1 # region where your bucket is located
|
||||
# STORAGE_AWS_ACCESS_KEY_ID=XXXX # replace-with-your-aws-key and don't commit this to github
|
||||
# STORAGE_AWS_SECRET_ACCESS_KEY=XXXX # replace-with-your-aws-key and don't commit this to github
|
||||
FILE_SIZE_LIMIT=52428800 # max file size (in bytes)
|
||||
|
||||
# predefined; don't change these unless you know what you're doing
|
||||
POSTGRES_PORT=5432
|
||||
AUTH_PORT=9999
|
||||
REST_PORT=3000
|
||||
REALTIME_PORT=4000
|
||||
KONG_PORT=8000
|
||||
KONG_PORT_TLS=8443
|
||||
@@ -0,0 +1,35 @@
|
||||
# Secrets
|
||||
|
||||
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
|
||||
|
||||
# Auth
|
||||
|
||||
## General
|
||||
SITE_URL=http://localhost:3000
|
||||
ADDITIONAL_REDIRECT_URLS=
|
||||
JWT_EXPIRY=3600
|
||||
DISABLE_SIGNUP=false
|
||||
|
||||
## Email auth
|
||||
ENABLE_EMAIL_SIGNUP=true
|
||||
ENABLE_EMAIL_AUTOCONFIRM=false
|
||||
SMTP_ADMIN_EMAIL=
|
||||
SMTP_HOST=
|
||||
SMTP_PORT=
|
||||
SMTP_USER=
|
||||
SMTP_PASS=
|
||||
SMTP_SENDER_NAME=
|
||||
|
||||
## Phone auth
|
||||
ENABLE_PHONE_SIGNUP=false
|
||||
ENABLE_PHONE_AUTOCONFIRM=false
|
||||
|
||||
# Ports
|
||||
|
||||
## API endpoint ports
|
||||
KONG_HTTP_PORT=8000
|
||||
KONG_HTTPS_PORT=8443
|
||||
|
||||
## DB port
|
||||
POSTGRES_PORT=5432
|
||||
@@ -0,0 +1,3 @@
|
||||
volumes/db/data
|
||||
volumes/storage
|
||||
.env
|
||||
+70
-73
@@ -1,118 +1,115 @@
|
||||
version: '3.6'
|
||||
services:
|
||||
kong:
|
||||
container_name: supabase-kong
|
||||
build:
|
||||
context: ./dockerfiles/kong
|
||||
environment:
|
||||
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
|
||||
KONG_PLUGINS: request-transformer,cors,key-auth,http-log
|
||||
image: kong:2.1
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${KONG_PORT}:8000/tcp
|
||||
- ${KONG_PORT_TLS}:8443/tcp
|
||||
- ${KONG_HTTP_PORT}:8000/tcp
|
||||
- ${KONG_HTTPS_PORT}:8443/tcp
|
||||
volumes:
|
||||
- ./volumes/kong.yml:/var/lib/kong/kong.yml
|
||||
environment:
|
||||
KONG_DATABASE: "off"
|
||||
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
|
||||
# https://github.com/supabase/cli/issues/14
|
||||
KONG_DNS_ORDER: LAST,A,CNAME
|
||||
KONG_PLUGINS: request-transformer,cors,key-auth
|
||||
auth:
|
||||
container_name: supabase-auth
|
||||
image: supabase/gotrue:latest
|
||||
ports:
|
||||
- ${AUTH_PORT}
|
||||
image: supabase/gotrue:v2.1.8
|
||||
depends_on:
|
||||
- db
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GOTRUE_JWT_SECRET: ${JWT_SECRET}
|
||||
GOTRUE_JWT_EXP: 3600
|
||||
GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
|
||||
GOTRUE_DB_DRIVER: postgres
|
||||
DB_NAMESPACE: auth
|
||||
API_EXTERNAL_URL: http://localhost:8000
|
||||
GOTRUE_API_HOST: 0.0.0.0
|
||||
PORT: ${AUTH_PORT}
|
||||
GOTRUE_API_PORT: 9999
|
||||
|
||||
GOTRUE_DB_DRIVER: postgres
|
||||
GOTRUE_DB_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres?sslmode=disable&search_path=auth
|
||||
|
||||
GOTRUE_SITE_URL: ${SITE_URL}
|
||||
GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS}
|
||||
GOTRUE_DISABLE_SIGNUP: ${DISABLE_SIGNUP}
|
||||
|
||||
GOTRUE_JWT_SECRET: ${JWT_SECRET}
|
||||
GOTRUE_JWT_EXP: ${JWT_EXPIRY}
|
||||
GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
|
||||
|
||||
GOTRUE_EXTERNAL_EMAIL_ENABLED: ${ENABLE_EMAIL_SIGNUP}
|
||||
GOTRUE_MAILER_AUTOCONFIRM: ${ENABLE_EMAIL_AUTOCONFIRM}
|
||||
GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL}
|
||||
GOTRUE_SMTP_HOST: ${SMTP_HOST}
|
||||
GOTRUE_SMTP_PORT: ${SMTP_PORT}
|
||||
GOTRUE_SMTP_USER: ${SMTP_USER}
|
||||
GOTRUE_SMTP_PASS: ${SMTP_PASS}
|
||||
GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL}
|
||||
|
||||
GOTRUE_DISABLE_SIGNUP: 'false'
|
||||
GOTRUE_SITE_URL: http://localhost:8000
|
||||
GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME}
|
||||
GOTRUE_MAILER_URLPATHS_INVITE: /auth/v1/verify
|
||||
GOTRUE_MAILER_URLPATHS_CONFIRMATION: /auth/v1/verify
|
||||
GOTRUE_MAILER_URLPATHS_RECOVERY: /auth/v1/verify
|
||||
GOTRUE_MAILER_AUTOCONFIRM: 'true'
|
||||
GOTRUE_LOG_LEVEL: DEBUG
|
||||
GOTRUE_OPERATOR_TOKEN: ${OPERATOR_TOKEN}
|
||||
DATABASE_URL: 'postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres?sslmode=disable&search_path=auth'
|
||||
GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: /auth/v1/verify
|
||||
|
||||
GOTRUE_EXTERNAL_PHONE_ENABLED: ${ENABLE_PHONE_SIGNUP}
|
||||
GOTRUE_SMS_AUTOCONFIRM: ${ENABLE_PHONE_AUTOCONFIRM}
|
||||
rest:
|
||||
container_name: supabase-rest
|
||||
image: postgrest/postgrest:latest
|
||||
ports:
|
||||
- ${REST_PORT}:3000
|
||||
image: postgrest/postgrest:v8.0.0
|
||||
depends_on:
|
||||
- db
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres
|
||||
PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres
|
||||
PGRST_DB_SCHEMA: public, storage
|
||||
PGRST_DB_ANON_ROLE: anon
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
|
||||
realtime:
|
||||
container_name: supabase-realtime
|
||||
image: supabase/realtime:latest
|
||||
ports:
|
||||
- ${REALTIME_PORT}
|
||||
image: supabase/realtime:v0.15.0
|
||||
depends_on:
|
||||
- db
|
||||
restart: on-failure
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: 5432
|
||||
DB_NAME: postgres
|
||||
DB_USER: postgres
|
||||
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DB_PORT: ${POSTGRES_PORT}
|
||||
PORT: ${REALTIME_PORT}
|
||||
HOSTNAME: localhost
|
||||
# Disable JWT Auth locally. The JWT_SECRET will be ignored.
|
||||
SECURE_CHANNELS: 'false'
|
||||
SLOT_NAME: supabase_realtime
|
||||
PORT: 4000
|
||||
SECURE_CHANNELS: "true"
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
|
||||
storage:
|
||||
image: supabase/storage-api:v0.9.1
|
||||
ports:
|
||||
- '5000:5000'
|
||||
container_name: supabase-storage
|
||||
image: supabase/storage-api:v0.9.3
|
||||
depends_on:
|
||||
- db
|
||||
- rest
|
||||
restart: always
|
||||
- db
|
||||
- rest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/storage:/var/lib/storage
|
||||
environment:
|
||||
ANON_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwLCJhdWQiOiIiLCJzdWIiOiIiLCJyb2xlIjoiYW5vbiJ9.sUHErUOiKZ3nHQIxy-7jND6B80Uzf9G4NtMLmL6HXPQ
|
||||
SERVICE_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYyNzIwNzUzMiwiZXhwIjoxNjkwMjc5NTMyLCJhdWQiOiIiLCJzdWIiOiIiLCJyb2xlIjoic2VydmljZV9yb2xlIn0.hfdXFZV5PdvUdo2xK0vStb1i97GJukSkRqfwd4YIh2M
|
||||
PROJECT_REF: bjwdssmqcnupljrqypxz # can be any random string
|
||||
POSTGREST_URL: http://rest:3000
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres
|
||||
PGOPTIONS: "-c search_path=storage"
|
||||
FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT}
|
||||
REGION: ${STORAGE_REGION} # region where your bucket is located
|
||||
GLOBAL_S3_BUCKET: ${STORAGE_S3_BUCKET} # name of s3 bucket where you want to store objects
|
||||
# AWS_ACCESS_KEY_ID: replace-with-your-aws-key
|
||||
# AWS_SECRET_ACCESS_KEY: replace-with-your-aws-secret
|
||||
STORAGE_BACKEND: ${STORAGE_BACKEND}
|
||||
FILE_STORAGE_BACKEND_PATH: /var/data/storage
|
||||
ANON_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY
|
||||
SERVICE_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU
|
||||
POSTGREST_URL: http://rest:3000
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres
|
||||
PGOPTIONS: -c search_path=storage
|
||||
FILE_SIZE_LIMIT: 52428800
|
||||
STORAGE_BACKEND: file
|
||||
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||
# TODO: https://github.com/supabase/storage-api/commit/a836fc9666c2434d89ca4b31402f74772d50fb6d
|
||||
PROJECT_REF: stub
|
||||
# TODO: https://github.com/supabase/storage-api/issues/55
|
||||
REGION: stub
|
||||
GLOBAL_S3_BUCKET: stub
|
||||
db:
|
||||
container_name: supabase-db
|
||||
build:
|
||||
context: ./dockerfiles/postgres
|
||||
image: supabase/postgres:13.3.0
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${POSTGRES_PORT}:${POSTGRES_PORT}
|
||||
command:
|
||||
- postgres
|
||||
- -c
|
||||
- wal_level=logical
|
||||
- ${POSTGRES_PORT}:5432
|
||||
volumes:
|
||||
- ./volumes/db/data:/var/lib/postgresql/data
|
||||
- ./volumes/db/init:/docker-entrypoint-initdb.d
|
||||
environment:
|
||||
POSTGRES_DB: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_PORT: ${POSTGRES_PORT}
|
||||
command: postgres -c wal_level=logical
|
||||
@@ -1,15 +0,0 @@
|
||||
FROM kong:2.1
|
||||
|
||||
COPY --chown=kong:nogroup kong.yml /var/lib/kong/kong.yml
|
||||
|
||||
# Build time defaults
|
||||
ARG build_KONG_DATABASE=off
|
||||
ARG build_KONG_PLUGINS=request-transformer,cors,key-auth
|
||||
ARG build_KONG_DECLARATIVE_CONFIG=/var/lib/kong/kong.yml
|
||||
|
||||
# Run time values
|
||||
ENV KONG_DATABASE=$build_KONG_DATABASE
|
||||
ENV KONG_PLUGINS=$build_KONG_PLUGINS
|
||||
ENV KONG_DECLARATIVE_CONFIG=$build_KONG_DECLARATIVE_CONFIG
|
||||
|
||||
EXPOSE 8000
|
||||
@@ -1,85 +0,0 @@
|
||||
_format_version: "1.1"
|
||||
services:
|
||||
- name: auth-v1-open
|
||||
url: http://auth:9999/verify
|
||||
routes:
|
||||
- name: auth-v1-open
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/verify
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1-open-callback
|
||||
url: http://auth:9999/callback
|
||||
routes:
|
||||
- name: auth-v1-open-callback
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/callback
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1-open-authorize
|
||||
url: http://auth:9999/authorize
|
||||
routes:
|
||||
- name: auth-v1-open-authorize
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/authorize
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1
|
||||
_comment: 'GoTrue: /auth/v1/* -> http://auth:9999/*'
|
||||
url: http://auth:9999/
|
||||
routes:
|
||||
- name: auth-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: true
|
||||
- name: rest-v1
|
||||
_comment: 'PostgREST: /rest/v1/* -> http://rest:3000/*'
|
||||
url: http://rest:3000/
|
||||
routes:
|
||||
- name: rest-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /rest/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: true
|
||||
- name: realtime-v1
|
||||
_comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*'
|
||||
url: http://realtime:4000/socket/
|
||||
routes:
|
||||
- name: realtime-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /realtime/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: true
|
||||
- name: storage-v1
|
||||
_comment: 'Storage: /storage/v1/* -> http://storage-api:5000/*'
|
||||
url: http://storage:5000/
|
||||
routes:
|
||||
- name: storage-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /storage/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
consumers:
|
||||
- username: 'anon-key'
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwLCJhdWQiOiIiLCJzdWIiOiIiLCJyb2xlIjoiYW5vbiJ9.sUHErUOiKZ3nHQIxy-7jND6B80Uzf9G4NtMLmL6HXPQ
|
||||
- username: 'service-key'
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYyNzIwNzUzMiwiZXhwIjoxNjkwMjc5NTMyLCJhdWQiOiIiLCJzdWIiOiIiLCJyb2xlIjoic2VydmljZV9yb2xlIn0.hfdXFZV5PdvUdo2xK0vStb1i97GJukSkRqfwd4YIh2M
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
-- Set up reatime
|
||||
create publication supabase_realtime for all tables;
|
||||
|
||||
-- Extension namespacing
|
||||
create schema 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;
|
||||
|
||||
-- Developer roles
|
||||
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 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;
|
||||
|
||||
alter role anon set statement_timeout = '3s';
|
||||
alter role authenticated set statement_timeout = '8s';
|
||||
|
||||
ALTER ROLE postgres SET search_path = "$user", public, auth, extensions;
|
||||
@@ -1,19 +0,0 @@
|
||||
FROM supabase/postgres:13.3.0
|
||||
|
||||
COPY --chown=postgres 00-initial-schema.sql /docker-entrypoint-initdb.d/00-initial-schema.sql
|
||||
COPY --chown=postgres auth-schema.sql /docker-entrypoint-initdb.d/auth-schema.sql
|
||||
COPY --chown=postgres storage-schema.sql /docker-entrypoint-initdb.d/storage-schema.sql
|
||||
|
||||
# Build time defaults
|
||||
ARG build_POSTGRES_DB=postgres
|
||||
ARG build_POSTGRES_USER=postgres
|
||||
ARG build_POSTGRES_PASSWORD=postgres
|
||||
ARG build_POSTGRES_PORT=5432
|
||||
|
||||
# Run time values
|
||||
ENV POSTGRES_DB=$build_POSTGRES_DB
|
||||
ENV POSTGRES_USER=$build_POSTGRES_USER
|
||||
ENV POSTGRES_PASSWORD=$build_POSTGRES_PASSWORD
|
||||
ENV POSTGRES_PORT=$build_POSTGRES_PORT
|
||||
|
||||
EXPOSE 5432
|
||||
@@ -0,0 +1,47 @@
|
||||
-- Set up reatime
|
||||
-- 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';
|
||||
+36
-8
@@ -1,13 +1,14 @@
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION postgres;
|
||||
CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_admin;
|
||||
|
||||
-- auth.users definition
|
||||
|
||||
CREATE TABLE auth.users (
|
||||
instance_id uuid NULL,
|
||||
id uuid NOT NULL,
|
||||
id uuid NOT NULL UNIQUE,
|
||||
aud varchar(255) NULL,
|
||||
"role" varchar(255) NULL,
|
||||
email varchar(255) NULL,
|
||||
email varchar(255) NULL UNIQUE,
|
||||
encrypted_password varchar(255) NULL,
|
||||
confirmed_at timestamptz NULL,
|
||||
invited_at timestamptz NULL,
|
||||
@@ -28,7 +29,10 @@ CREATE TABLE auth.users (
|
||||
);
|
||||
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,
|
||||
@@ -42,7 +46,10 @@ CREATE TABLE auth.refresh_tokens (
|
||||
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,
|
||||
@@ -51,7 +58,10 @@ CREATE TABLE auth.instances (
|
||||
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,
|
||||
@@ -60,11 +70,16 @@ CREATE TABLE auth.audit_log_entries (
|
||||
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'),
|
||||
@@ -73,20 +88,33 @@ VALUES ('20171026211738'),
|
||||
('20180108183307'),
|
||||
('20180119214651'),
|
||||
('20180125194653');
|
||||
|
||||
-- Gets the User ID from the request cookie
|
||||
create or replace function auth.uid() returns uuid as $$
|
||||
select nullif(current_setting('request.jwt.claim.sub', true), '')::uuid;
|
||||
$$ language sql stable;
|
||||
-- Gets the User Role from the request cookie
|
||||
|
||||
-- Gets the User ID from the request cookie
|
||||
create or replace function auth.role() returns text as $$
|
||||
select nullif(current_setting('request.jwt.claim.role', true), '')::text;
|
||||
$$ language sql stable;
|
||||
-- Gets the User Email from the request cookie
|
||||
|
||||
-- Gets the User email
|
||||
create or replace function auth.email() returns text as $$
|
||||
select nullif(current_setting('request.jwt.claim.email', true), '')::text;
|
||||
$$ language sql stable;
|
||||
GRANT ALL PRIVILEGES ON SCHEMA auth TO postgres;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA auth TO postgres;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA auth TO postgres;
|
||||
|
||||
-- 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;
|
||||
+30
-25
@@ -1,11 +1,10 @@
|
||||
CREATE SCHEMA IF NOT EXISTS storage AUTHORIZATION postgres;
|
||||
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;
|
||||
|
||||
DROP TABLE IF EXISTS "storage"."buckets";
|
||||
CREATE TABLE "storage"."buckets" (
|
||||
"id" text not NULL,
|
||||
"name" text NOT NULL,
|
||||
@@ -17,7 +16,6 @@ CREATE TABLE "storage"."buckets" (
|
||||
);
|
||||
CREATE UNIQUE INDEX "bname" ON "storage"."buckets" USING BTREE ("name");
|
||||
|
||||
DROP TABLE IF EXISTS "storage"."objects";
|
||||
CREATE TABLE "storage"."objects" (
|
||||
"id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(),
|
||||
"bucket_id" text,
|
||||
@@ -36,7 +34,7 @@ CREATE INDEX name_prefix_search ON storage.objects(name text_pattern_ops);
|
||||
|
||||
ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE OR REPLACE FUNCTION storage.foldername(name text)
|
||||
CREATE FUNCTION storage.foldername(name text)
|
||||
RETURNS text[]
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
@@ -48,7 +46,7 @@ BEGIN
|
||||
END
|
||||
$function$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION storage.filename(name text)
|
||||
CREATE FUNCTION storage.filename(name text)
|
||||
RETURNS text
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
@@ -60,7 +58,7 @@ BEGIN
|
||||
END
|
||||
$function$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION storage.extension(name text)
|
||||
CREATE FUNCTION storage.extension(name text)
|
||||
RETURNS text
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
@@ -70,11 +68,12 @@ _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 OR REPLACE FUNCTION storage.search(prefix text, bucketname text, limits int DEFAULT 100, levels int DEFAULT 1, offsets int DEFAULT 0)
|
||||
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,
|
||||
@@ -88,24 +87,30 @@ AS $function$
|
||||
DECLARE
|
||||
_bucketId text;
|
||||
BEGIN
|
||||
select buckets."id" from buckets where buckets.name=bucketname limit 1 into _bucketId;
|
||||
return query
|
||||
with files_folders as (
|
||||
select ((string_to_array(objects.name, '/'))[levels]) as folder
|
||||
from objects
|
||||
where objects.name ilike prefix || '%'
|
||||
and bucket_id = _bucketId
|
||||
GROUP by folder
|
||||
limit limits
|
||||
offset offsets
|
||||
)
|
||||
select files_folders.folder as name, objects.id, objects.updated_at, objects.created_at, objects.last_accessed_at, objects.metadata from files_folders
|
||||
left join objects
|
||||
on prefix || files_folders.folder = objects.name
|
||||
where objects.id is null or objects.bucket_id=_bucketId;
|
||||
-- will be replaced by migrations when server starts
|
||||
-- saving space for cloud-init
|
||||
END
|
||||
$function$;
|
||||
|
||||
GRANT ALL PRIVILEGES ON SCHEMA storage TO postgres;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA storage TO postgres;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA storage TO postgres;
|
||||
-- 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;
|
||||
@@ -0,0 +1,68 @@
|
||||
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 ddl_command_end;
|
||||
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;
|
||||
@@ -0,0 +1,85 @@
|
||||
_format_version: "1.1"
|
||||
services:
|
||||
- name: auth-v1-open
|
||||
url: http://auth:9999/verify
|
||||
routes:
|
||||
- name: auth-v1-open
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/verify
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1-open-callback
|
||||
url: http://auth:9999/callback
|
||||
routes:
|
||||
- name: auth-v1-open-callback
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/callback
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1-open-authorize
|
||||
url: http://auth:9999/authorize
|
||||
routes:
|
||||
- name: auth-v1-open-authorize
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/authorize
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: auth-v1
|
||||
_comment: "GoTrue: /auth/v1/* -> http://auth:9999/*"
|
||||
url: http://auth:9999/
|
||||
routes:
|
||||
- name: auth-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /auth/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: false
|
||||
- name: rest-v1
|
||||
_comment: "PostgREST: /rest/v1/* -> http://rest:3000/*"
|
||||
url: http://rest:3000/
|
||||
routes:
|
||||
- name: rest-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /rest/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: true
|
||||
- name: realtime-v1
|
||||
_comment: "Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*"
|
||||
url: http://realtime:4000/socket/
|
||||
routes:
|
||||
- name: realtime-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /realtime/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
- name: key-auth
|
||||
config:
|
||||
hide_credentials: false
|
||||
- name: storage-v1
|
||||
_comment: "Storage: /storage/v1/* -> http://storage-api:5000/*"
|
||||
url: http://storage:5000/
|
||||
routes:
|
||||
- name: storage-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /storage/v1/
|
||||
plugins:
|
||||
- name: cors
|
||||
consumers:
|
||||
- username: anon
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY
|
||||
- username: service_role
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU
|
||||
Reference in new issue
Block a user