Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Self host Supabase service #2743

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ tasks:
eval $(gp env -e WEB_URL=$(gp url 8000))
eval $(gp env -e API_HOST=$(gp url 8443))
eval $(gp env -e SSO_LOGIN_URL=$(gp url 8081))
eval $(gp env -e SUPABASE_API=$(gp url 8911))
eval $(gp env -e SERVICES="status image sso search posts feed-discovery users redis elasticsearch login firebase")
sed -r \
-e "s@(.+=)http://localhost:8000(/[^ ]*)*@\1$WEB_URL\2@g" \
-e "s@(.+=)http://localhost:3000(/[^ ]*)*@\1$API_URL\2@g" \
-e "s@(.+=)http://localhost:8081(/[^ ]*)*@\1$SSO_LOGIN_URL\2@g" \
-e "s@(.+=)http://kong:8000(/[^ ]*)*@\1$SUPABASE_API\2@g" \
-e "s@(.+=)http://localhost([^:]*)@\1$API_HOST\2@g" \
-e "s@development\.yml@gitpod\.yml@" \
config/env.development > .env
Expand Down Expand Up @@ -45,38 +47,54 @@ tasks:
# Exposing service ports
# Overriding the default notification popup when a port is open
ports:
# NextJS frontend
- port: 8000
name: frontend
visibility: public
onOpen: open-preview
# Web API
- port: 3000
name: web-api
visibility: public
onOpen: ignore
# Microservice server
- port: 8443
name: micro-services
visibility: public
onOpen: ignore
# Redis server
- port: 6379
name: redis
onOpen: ignore
# Elasticsearch server
- port: 9200
name: elasticsearch
onOpen: ignore
# Firebase emulator
- port: 4000
name: firebase
onOpen: ignore
# Firestore emulator
- port: 8088
name: firestore
onOpen: ignore
# Traefik UI
- port: 8080
name: traefik
onOpen: ignore
# Login Page
- port: 8081
name: login
onOpen: ignore
# Static Web Content test
- port: 8888
name: test-web-content
onOpen: ignore
- port: 7777
name: auth
onOpen: ignore
# Supabase Services
- port: 8910
name: supabase-studio
onOpen: notify
- port: 8911
name: kong-http
onOpen: ignore
- port: 8912
name: kong-https
onOpen: ignore
- port: 8913
name: postgresql
onOpen: ignore

github:
Expand Down
55 changes: 53 additions & 2 deletions config/env.development
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ COMPOSE_PROJECT_NAME=telescope_api
# so it will work on Windows and Unix, see
# https://docs.docker.com/compose/reference/envvars/#compose_file
COMPOSE_PATH_SEPARATOR=;
COMPOSE_FILE=docker/docker-compose.yml;docker/development.yml
COMPOSE_FILE=docker/docker-compose.yml;docker/development.yml;docker/supabase/docker-compose.yml


# The host where the Telescope 1.0 front-end and back-end are run.
Expand Down Expand Up @@ -87,7 +87,6 @@ JWT_AUDIENCE=http://localhost
# How long should a JWT work before it expires
JWT_EXPIRES_IN=1h


################################################################################
# Image Service
################################################################################
Expand Down Expand Up @@ -260,3 +259,55 @@ FEED_QUEUE_PARALLEL_WORKERS=1

# Max number of posts per page
MAX_POSTS_PER_PAGE=5


################################################################################
# Supabase Services
################################################################################

SUPABASE_URL=http://kong:8000

# Secrets
# YOU MUST CHANGE THESE BEFORE GOING INTO PRODUCTION

POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
DukeManh marked this conversation as resolved.
Show resolved Hide resolved

# Auth

## General

### Telescope web URL, must match with WEB_URL
SITE_URL=http://localhost:8000

ADDITIONAL_REDIRECT_URLS=
JWT_EXPIRY=3600
DISABLE_SIGNUP=false
humphd marked this conversation as resolved.
Show resolved Hide resolved

## Email auth
ENABLE_EMAIL_SIGNUP=true
DukeManh marked this conversation as resolved.
Show resolved Hide resolved
ENABLE_EMAIL_AUTOCONFIRM=true
[email protected]
SMTP_HOST=mail
SMTP_PORT=2500
SMTP_USER=fake_mail_user
SMTP_PASS=fake_mail_password
SMTP_SENDER_NAME=fake_sender

## Phone auth
ENABLE_PHONE_SIGNUP=false
ENABLE_PHONE_AUTOCONFIRM=false

# Ports

## Studio port
STUDIO_PORT=8910

## API endpoint ports
KONG_HTTP_PORT=8911
KONG_HTTPS_PORT=8912

## DB port
POSTGRES_PORT=8913
3 changes: 3 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ services:
- ALLOWED_APP_ORIGINS
- JWT_EXPIRES_IN
- USERS_URL
# Supabase config
- SERVICE_ROLE_KEY
- SUPABASE_URL
# Satellite authentication/authorization support
- JWT_ISSUER
- JWT_AUDIENCE
Expand Down
5 changes: 5 additions & 0 deletions docker/supabase/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
volumes/db/data
volumes/db/init/data.sql
volumes/storage
.env
test.http
48 changes: 48 additions & 0 deletions docker/supabase/dev/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
create table profiles (
id uuid references auth.users not null,
updated_at timestamp with time zone,
username text unique,
avatar_url text,
website text,

primary key (id),
unique(username),
constraint username_length check (char_length(username) >= 3)
);

alter table profiles enable row level security;

create policy "Public profiles are viewable by the owner."
on profiles for select
using ( auth.uid() = id );

create policy "Users can insert their own profile."
on profiles for insert
with check ( auth.uid() = id );

create policy "Users can update own profile."
on profiles for update
using ( auth.uid() = id );

-- Set up Realtime
begin;
drop publication if exists supabase_realtime;
create publication supabase_realtime;
commit;
alter publication supabase_realtime add table profiles;

-- Set up Storage
insert into storage.buckets (id, name)
values ('avatars', 'avatars');

create policy "Avatar images are publicly accessible."
on storage.objects for select
using ( bucket_id = 'avatars' );

create policy "Anyone can upload an avatar."
on storage.objects for insert
with check ( bucket_id = 'avatars' );

create policy "Anyone can update an avatar."
on storage.objects for update
with check ( bucket_id = 'avatars' );
20 changes: 20 additions & 0 deletions docker/supabase/dev/docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '3.8'

services:
mail:
container_name: supabase-mail
image: inbucket/inbucket:stable
ports:
- '2500:2500' # SMTP
- '9000:9000' # web interface
- '1100:1100' # POP3
meta:
ports:
- 5555:8080
db:
volumes:
- /var/lib/postgresql/data
- ./supabase/dev/data.sql:/docker-entrypoint-initdb.d/data.sql
storage:
volumes:
- /var/lib/storage
156 changes: 156 additions & 0 deletions docker/supabase/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# 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

version: '3.8'

services:
studio:
container_name: supabase-studio
image: supabase/studio:latest
restart: unless-stopped
ports:
- ${STUDIO_PORT}:3000/tcp
humphd marked this conversation as resolved.
Show resolved Hide resolved
environment:
SUPABASE_URL: http://kong:8000
DukeManh marked this conversation as resolved.
Show resolved Hide resolved
STUDIO_PG_META_URL: http://meta:8080
SUPABASE_ANON_KEY: ${ANON_KEY}
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}

kong:
container_name: supabase-kong
image: kong:2.1
restart: unless-stopped
ports:
- ${KONG_HTTP_PORT}:8000/tcp
humphd marked this conversation as resolved.
Show resolved Hide resolved
- ${KONG_HTTPS_PORT}:8443/tcp
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,acl
volumes:
- ./supabase/volumes/api/kong.yml:/var/lib/kong/kong.yml

auth:
container_name: supabase-auth
image: supabase/gotrue:v2.2.12
depends_on:
- db
restart: unless-stopped
environment:
GOTRUE_API_HOST: 0.0.0.0
GOTRUE_API_PORT: 9999

GOTRUE_DB_DRIVER: postgres
GOTRUE_DB_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres?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_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_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:v9.0.0
depends_on:
- db
restart: unless-stopped
environment:
PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres
PGRST_DB_SCHEMAS: public,storage
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
PGRST_DB_USE_LEGACY_GUCS: 'false'

realtime:
container_name: supabase-realtime
image: supabase/realtime:v0.19.3
depends_on:
- db
restart: unless-stopped
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: postgres
DB_USER: postgres
DB_PASSWORD: ${POSTGRES_PASSWORD}
DB_SSL: 'false'
PORT: 4000
JWT_SECRET: ${JWT_SECRET}
REPLICATION_MODE: RLS
REPLICATION_POLL_INTERVAL: 100
SECURE_CHANNELS: 'true'
SLOT_NAME: supabase_realtime_rls
TEMPORARY_SLOT: 'true'
command: >
bash -c "./prod/rel/realtime/bin/realtime eval Realtime.Release.migrate
&& ./prod/rel/realtime/bin/realtime start"
storage:
container_name: supabase-storage
image: supabase/storage-api:v0.10.0
depends_on:
- db
- rest
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:${POSTGRES_PASSWORD}@db:5432/postgres
PGOPTIONS: -c search_path=storage,public
FILE_SIZE_LIMIT: 52428800
STORAGE_BACKEND: file
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
TENANT_ID: stub
# TODO: https://github.com/supabase/storage-api/issues/55
REGION: stub
GLOBAL_S3_BUCKET: stub
volumes:
- ./supabase/volumes/storage:/var/lib/storage

meta:
container_name: supabase-meta
image: supabase/postgres-meta:v0.29.0
depends_on:
- db
restart: unless-stopped
environment:
PG_META_PORT: 8080
PG_META_DB_HOST: db
PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}

db:
container_name: supabase-db
image: supabase/postgres:14.1.0
command: postgres -c config_file=/etc/postgresql/postgresql.conf
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
# - ./supbase/volumes/db/data:/var/lib/postgresql/data
- ./supabase/volumes/db/init:/docker-entrypoint-initdb.d
Loading