mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-06-04 04:22:57 +00:00
10 KiB
10 KiB
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
# Create docker-compose.yml with the content below
docker-compose up -d
Docker Compose
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)
_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
# 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
-
Generate Secrets:
# Run the commands above to generate secure passwords -
Create Directories:
mkdir -p volumes/{db,storage,functions,kong} mkdir -p volumes/db/init -
Deploy:
docker-compose up -d -
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
-- 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/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
# 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
# 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