mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-06-04 04:22:57 +00:00
391 lines
10 KiB
Markdown
391 lines
10 KiB
Markdown
# Supabase Open Source Firebase Alternative Template
|
|
|
|
## Overview
|
|
Supabase is an open source Firebase alternative that provides a complete backend-as-a-service platform.
|
|
|
|
## Quick Start
|
|
```bash
|
|
# Create docker-compose.yml with the content below
|
|
docker-compose up -d
|
|
```
|
|
|
|
## Docker Compose
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
db:
|
|
image: supabase/postgres:15.1.0.117
|
|
container_name: supabase-db
|
|
restart: always
|
|
environment:
|
|
POSTGRES_PASSWORD: your-super-secret-and-long-postgres-password
|
|
POSTGRES_DB: postgres
|
|
POSTGRES_INITDB_ARGS: --auth-host=scram
|
|
volumes:
|
|
- ./volumes/db:/var/lib/postgresql/data
|
|
- ./volumes/db/init:/docker-entrypoint-initdb.d
|
|
ports:
|
|
- "54322:5432"
|
|
command:
|
|
- postgres
|
|
- -c
|
|
- config_file=/etc/postgresql/postgresql.conf
|
|
- -c
|
|
- log_min_messages=warning
|
|
networks:
|
|
- supabase-network
|
|
|
|
auth:
|
|
image: supabase/gotrue:v2.91.3
|
|
container_name: supabase-auth
|
|
restart: always
|
|
environment:
|
|
GOTRUE_API_HOST: 0.0.0.0
|
|
GOTRUE_API_PORT: 9999
|
|
GOTRUE_DB_DRIVER: postgres
|
|
GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:your-super-secret-and-long-postgres-password@db:5432/auth
|
|
GOTRUE_JWT_SECRET: your-super-secret-jwt-token-with-at-least-32-characters-long
|
|
GOTRUE_JWT_EXP: 3600
|
|
GOTRUE_JWT_AUD: authenticated
|
|
GOTRUE_SITE_URL: http://localhost:3000
|
|
GOTRUE_URI_ALLOW_LIST: "*"
|
|
GOTRUE_DISABLE_SIGNUP: false
|
|
GOTRUE_EXTERNAL_EMAIL_ENABLED: true
|
|
GOTRUE_MAILER_AUTOCONFIRM: true
|
|
GOTRUE_EXTERNAL_PHONE_ENABLED: true
|
|
ports:
|
|
- "9999:9999"
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- supabase-network
|
|
|
|
rest:
|
|
image: postgrest/postgrest:v12.0.1
|
|
container_name: supabase-rest
|
|
restart: always
|
|
environment:
|
|
PGRST_DB_URI: postgres://authenticator:your-super-secret-and-long-postgres-password@db:5432/postgres
|
|
PGRST_DB_SCHEMA: public,storage
|
|
PGRST_DB_ANON_ROLE: anon
|
|
PGRST_DB_SEARCH_PATH: public
|
|
PGRST_SERVER_HOST: 0.0.0.0
|
|
PGRST_SERVER_PORT: 3000
|
|
PGRST_JWT_SECRET: your-super-secret-jwt-token-with-at-least-32-characters-long
|
|
ports:
|
|
- "3000:3000"
|
|
depends_on:
|
|
- db
|
|
- auth
|
|
networks:
|
|
- supabase-network
|
|
|
|
realtime:
|
|
image: supabase/realtime:v2.25.73
|
|
container_name: supabase-realtime
|
|
restart: always
|
|
environment:
|
|
PORT: 4000
|
|
DB_HOST: db
|
|
DB_PORT: 5432
|
|
DB_USER: supabase_realtime_admin
|
|
DB_PASSWORD: your-super-secret-and-long-postgres-password
|
|
DB_NAME: postgres
|
|
DB_AFTER_CONNECT_QUERY: 'SET application_name = ''realtime'''
|
|
DB_ENC_KEY: supabaserealtimeprotected-please-replace-this
|
|
API_JWT_SECRET: your-super-secret-jwt-token-with-at-least-32-characters-long
|
|
SECURE_CHANNELS: true
|
|
ports:
|
|
- "4000:4000"
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- supabase-network
|
|
|
|
storage:
|
|
image: supabase/storage:v0.48.0
|
|
container_name: supabase-storage
|
|
restart: always
|
|
environment:
|
|
ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOoJeerx0ntWqyT4DPCXUGSktY8R8Qw2HtWo
|
|
SERVICE_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8HdpbfsT3JApj1JNFo
|
|
POSTGRES_PASSWORD: your-super-secret-and-long-postgres-password
|
|
PGOPTIONS: "-c search_path=storage,public"
|
|
FILE_SIZE_LIMIT: 52428800
|
|
STORAGE_BACKEND: file
|
|
STORAGE_FILE_PATH: /var/lib/storage
|
|
TENANT_ID: stub
|
|
REGION: stub
|
|
GLOBAL_S3_BUCKET: stub
|
|
volumes:
|
|
- ./volumes/storage:/var/lib/storage
|
|
ports:
|
|
- "5000:5000"
|
|
depends_on:
|
|
- db
|
|
- rest
|
|
networks:
|
|
- supabase-network
|
|
|
|
meta:
|
|
image: supabase/postgres-meta:v0.74.0
|
|
container_name: supabase-meta
|
|
restart: always
|
|
environment:
|
|
PG_META_PORT: 8080
|
|
PG_META_DB_HOST: db
|
|
PG_META_DB_PORT: 5432
|
|
PG_META_DB_NAME: postgres
|
|
PG_META_DB_USER: supabase_admin
|
|
PG_META_DB_PASSWORD: your-super-secret-and-long-postgres-password
|
|
ports:
|
|
- "8080:8080"
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- supabase-network
|
|
|
|
functions:
|
|
image: supabase/edge-runtime:v1.47.4
|
|
container_name: supabase-functions
|
|
restart: always
|
|
environment:
|
|
JWT_SECRET: your-super-secret-jwt-token-with-at-least-32-characters-long
|
|
SUPABASE_URL: http://localhost:8000
|
|
SUPABASE_ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOoJeerx0ntWqyT4DPCXUGSktY8R8Qw2HtWo
|
|
SUPABASE_SERVICE_ROLE_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8HdpbfsT3JApj1JNFo
|
|
volumes:
|
|
- ./volumes/functions:/home/deno/functions
|
|
ports:
|
|
- "9000:9000"
|
|
networks:
|
|
- supabase-network
|
|
|
|
kong:
|
|
image: kong:3.4
|
|
container_name: supabase-kong
|
|
restart: always
|
|
environment:
|
|
KONG_DATABASE: "off"
|
|
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
|
|
KONG_PROXY_ACCESS_LOG: /dev/stdout
|
|
KONG_ADMIN_ACCESS_LOG: /dev/stdout
|
|
KONG_PROXY_ERROR_LOG: /dev/stderr
|
|
KONG_ADMIN_ERROR_LOG: /dev/stderr
|
|
KONG_ADMIN_LISTEN: 0.0.0.0:8001
|
|
KONG_ADMIN_GUI_URL: http://localhost:8002
|
|
volumes:
|
|
- ./volumes/kong:/var/lib/kong
|
|
- ./kong.yml:/var/lib/kong/kong.yml
|
|
ports:
|
|
- "8000:8000"
|
|
- "8001:8001"
|
|
- "8002:8002"
|
|
networks:
|
|
- supabase-network
|
|
|
|
networks:
|
|
supabase-network:
|
|
driver: bridge
|
|
```
|
|
|
|
## Kong Configuration (kong.yml)
|
|
```yaml
|
|
_format_version: "3.0"
|
|
_transform: true
|
|
|
|
services:
|
|
- name: auth
|
|
url: http://auth:9999
|
|
routes:
|
|
- name: auth
|
|
paths: ["/auth/v1/*"]
|
|
strip_path: false
|
|
|
|
- name: rest
|
|
url: http://rest:3000
|
|
routes:
|
|
- name: rest
|
|
paths: ["/rest/v1/*"]
|
|
strip_path: false
|
|
|
|
- name: realtime
|
|
url: http://realtime:4000/socket.io/
|
|
routes:
|
|
- name: realtime
|
|
paths: ["/realtime/v1/*"]
|
|
strip_path: false
|
|
|
|
- name: storage
|
|
url: http://storage:5000
|
|
routes:
|
|
- name: storage
|
|
paths: ["/storage/v1/*"]
|
|
strip_path: false
|
|
|
|
- name: functions
|
|
url: http://functions:9000
|
|
routes:
|
|
- name: functions
|
|
paths: ["/functions/v1/*"]
|
|
strip_path: false
|
|
|
|
- name: meta
|
|
url: http://meta:8080
|
|
routes:
|
|
- name: meta
|
|
paths: ["/pg-meta/*"]
|
|
strip_path: false
|
|
|
|
plugins:
|
|
- name: cors
|
|
service: auth
|
|
config:
|
|
origins: ["*"]
|
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
|
headers: ["accept", "authorization", "content-type", "apikey", "x-client-info"]
|
|
exposed_headers: ["content-length"]
|
|
max_age: 3600
|
|
credentials: true
|
|
|
|
- name: cors
|
|
service: rest
|
|
config:
|
|
origins: ["*"]
|
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"]
|
|
headers: ["accept", "authorization", "content-type", "apikey", "x-client-info"]
|
|
exposed_headers: ["content-length"]
|
|
max_age: 3600
|
|
credentials: true
|
|
|
|
- name: cors
|
|
service: storage
|
|
config:
|
|
origins: ["*"]
|
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"]
|
|
headers: ["accept", "authorization", "content-type", "apikey", "x-client-info"]
|
|
exposed_headers: ["content-length"]
|
|
max_age: 3600
|
|
credentials: true
|
|
|
|
- name: cors
|
|
service: functions
|
|
config:
|
|
origins: ["*"]
|
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"]
|
|
headers: ["accept", "authorization", "content-type", "apikey", "x-client-info"]
|
|
exposed_headers: ["content-length"]
|
|
max_age: 3600
|
|
credentials: true
|
|
```
|
|
|
|
## Environment Variables Setup
|
|
```bash
|
|
# Generate secure passwords and tokens
|
|
POSTGRES_PASSWORD=$(openssl rand -base64 32)
|
|
JWT_SECRET=$(openssl rand -base64 32)
|
|
DB_ENC_KEY=$(openssl rand -base64 32)
|
|
|
|
# Replace in docker-compose.yml
|
|
sed -i "s/your-super-secret-and-long-postgres-password/$POSTGRES_PASSWORD/g" docker-compose.yml
|
|
sed -i "s/your-super-secret-jwt-token-with-at-least-32-characters-long/$JWT_SECRET/g" docker-compose.yml
|
|
sed -i "s/supabaserealtimeprotected-please-replace-this/$DB_ENC_KEY/g" docker-compose.yml
|
|
```
|
|
|
|
## Setup Guide
|
|
1. **Generate Secrets**:
|
|
```bash
|
|
# Run the commands above to generate secure passwords
|
|
```
|
|
|
|
2. **Create Directories**:
|
|
```bash
|
|
mkdir -p volumes/{db,storage,functions,kong}
|
|
mkdir -p volumes/db/init
|
|
```
|
|
|
|
3. **Deploy**:
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
4. **Access Points**:
|
|
- **API Gateway**: http://localhost:8000
|
|
- **Studio**: http://localhost:8000 (via Kong)
|
|
- **Database**: localhost:54322
|
|
- **Kong Admin**: http://localhost:8002
|
|
|
|
## API Endpoints
|
|
- **Auth**: http://localhost:8000/auth/v1/
|
|
- **REST**: http://localhost:8000/rest/v1/
|
|
- **Realtime**: http://localhost:8000/realtime/v1/
|
|
- **Storage**: http://localhost:8000/storage/v1/
|
|
- **Functions**: http://localhost:8000/functions/v1/
|
|
- **Meta**: http://localhost:8000/pg-meta/
|
|
|
|
## Database Setup
|
|
```sql
|
|
-- Create initial schema
|
|
CREATE SCHEMA IF NOT EXISTS auth;
|
|
CREATE SCHEMA IF NOT EXISTS storage;
|
|
CREATE SCHEMA IF NOT EXISTS realtime;
|
|
CREATE SCHEMA IF NOT EXISTS extensions;
|
|
|
|
-- Enable required extensions
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
CREATE EXTENSION IF NOT EXISTS "pg_graphql";
|
|
```
|
|
|
|
## Client Libraries
|
|
```javascript
|
|
// JavaScript/TypeScript
|
|
import { createClient } from '@supabase/supabase-js'
|
|
|
|
const supabase = createClient(
|
|
'http://localhost:8000',
|
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOoJeerx0ntWqyT4DPCXUGSktY8R8Qw2HtWo'
|
|
)
|
|
|
|
// Example usage
|
|
const { data, error } = await supabase
|
|
.from('users')
|
|
.select('*')
|
|
```
|
|
|
|
## Backup Strategy
|
|
```bash
|
|
# Backup database
|
|
docker exec supabase-db pg_dump -U postgres > supabase-backup.sql
|
|
|
|
# Backup storage
|
|
tar czf storage-backup.tar.gz volumes/storage/
|
|
|
|
# Restore database
|
|
docker exec -i supabase-db psql -U postgres < supabase-backup.sql
|
|
```
|
|
|
|
## Performance Optimization
|
|
```yaml
|
|
# PostgreSQL tuning
|
|
environment:
|
|
POSTGRES_SHARED_PRELOAD_LIBRARIES: pg_stat_statements
|
|
POSTGRES_MAX_CONNECTIONS: 200
|
|
POSTGRES_SHARED_BUFFERS: 256MB
|
|
POSTGRES_EFFECTIVE_CACHE_SIZE: 1GB
|
|
```
|
|
|
|
## Security
|
|
- Change all default passwords
|
|
- Use HTTPS in production
|
|
- Enable RLS (Row Level Security)
|
|
- Regular database backups
|
|
- Monitor access logs
|
|
|
|
## Troubleshooting
|
|
- **Connection issues**: Check network and ports
|
|
- **Database errors**: Review PostgreSQL logs
|
|
- **Auth problems**: Verify JWT configuration
|
|
- **Storage failures**: Check disk permissions
|