SUPABASE ARCHITECTURE
Local Supabase Architecture
Section titled “Local Supabase Architecture”This document explains how the local Supabase services work together.
System Architecture
Section titled “System Architecture”┌─────────────────────────────────────────────────────────────┐│ Your Application ││ (React App - localhost:5173) ││ ││ VITE_SUPABASE_URL=http://localhost:54321 ││ VITE_SUPABASE_ANON_KEY=eyJ... │└──────────────────────┬───────────────────────────────────────┘ │ HTTP/WebSocket │┌──────────────────────▼───────────────────────────────────────┐│ Kong API Gateway (54321) ││ ││ • Routes requests to correct service ││ • Validates JWT tokens ││ • Enforces CORS policies ││ • Rate limiting & auth middleware │└──┬────────┬────────┬────────┬───────────────────────────────┘ │ │ │ │ │ /rest │ /auth │ /realtime │ /storage │ │ │ │┌──▼───┐ ┌─▼────┐ ┌─▼──────┐ ┌──▼─────┐│PostgR│ │GoTrue│ │Realtime│ │Storage ││ EST │ │ │ │ │ │ API ││ │ │ │ │ │ │ ││REST │ │Auth │ │WebSock │ │Objects ││API │ │Mgmt │ │Server │ │Files │└──┬───┘ └─┬────┘ └──┬─────┘ └──┬─────┘ │ │ │ │ └───────┴─────────┴──────────┘ │ ┌─────▼──────────────────────────────────────┐ │ PostgreSQL Database │ │ (localhost:5432) │ │ │ │ • Main data storage │ │ • Extensions: pgvector, postgis, etc. │ │ • Schemas: public, auth, storage, etc. │ │ • Row Level Security (RLS) enabled │ └─────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐│ Supabase Studio (54323) ││ ││ Web UI for: ││ • Database schema management ││ • Table editor & SQL editor ││ • Auth user management ││ • Storage bucket management ││ • API documentation │└─────────────────────────────────────────────────────────────┘Request Flow
Section titled “Request Flow”1. REST API Request
Section titled “1. REST API Request”Your App │ │ GET /rest/v1/users │ Authorization: Bearer <JWT> ▼Kong Gateway │ │ • Validates JWT │ • Checks role (anon/authenticated/service_role) │ • Routes to PostgREST ▼PostgREST │ │ • Connects to database as appropriate role │ • Executes SQL query │ • Applies RLS policies │ • Returns JSON ▼PostgreSQL │ │ • Checks RLS policies │ • Executes query │ • Returns results ▼Response flows back through Kong to Your App2. Authentication Flow
Section titled “2. Authentication Flow”Your App │ │ POST /auth/v1/signup │ { email, password } ▼Kong Gateway │ │ • Routes to GoTrue ▼GoTrue │ │ • Validates input │ • Hashes password │ • Creates user in auth.users │ • Sends confirmation email (auto-confirmed in dev) │ • Generates JWT ▼PostgreSQL (auth schema) │ │ • Stores user credentials │ • Triggers user_profiles creation ▼Response with JWT │ │ { access_token, refresh_token, user } ▼Your App stores tokens3. Real-time Subscription
Section titled “3. Real-time Subscription”Your App │ │ WebSocket: /realtime/v1/websocket │ Subscribe to: public.messages ▼Kong Gateway │ │ • Validates JWT │ • Upgrades to WebSocket │ • Routes to Realtime server ▼Realtime Server │ │ • Establishes WebSocket connection │ • Subscribes to PostgreSQL changes │ • Filters by RLS policies ▼PostgreSQL (logical replication) │ │ • Streams changes via WAL │ • Applies RLS filters ▼Changes stream to Your App via WebSocket4. File Upload
Section titled “4. File Upload”Your App │ │ POST /storage/v1/object/avatars/user.jpg │ Authorization: Bearer <JWT> │ Content-Type: image/jpeg ▼Kong Gateway │ │ • Validates JWT │ • Routes to Storage API ▼Storage API │ │ • Checks bucket policies │ • Validates file type/size │ • Saves to filesystem │ • Creates database record ▼Filesystem (docker/volumes/storage/) │ │ • File stored at path ▼PostgreSQL (storage schema) │ │ • Metadata stored │ • RLS applied ▼Response with file URLService Roles
Section titled “Service Roles”Database Roles Hierarchy
Section titled “Database Roles Hierarchy”postgres (superuser) │ ├─ supabase_admin (admin operations) │ ├─ authenticator (connection pooler) │ │ │ ├─ anon (unauthenticated users) │ │ └─ SELECT public tables (if allowed by RLS) │ │ │ ├─ authenticated (logged-in users) │ │ └─ SELECT/INSERT/UPDATE/DELETE (per RLS) │ │ │ └─ service_role (backend/admin) │ └─ BYPASS RLS (full access) │ ├─ supabase_auth_admin (GoTrue) │ └─ Full access to auth schema │ └─ supabase_storage_admin (Storage) └─ Full access to storage schemaNetwork Communication
Section titled “Network Communication”Internal Docker Network
Section titled “Internal Docker Network”supabase-network (Docker bridge network) │ ├─ db:5432 (PostgreSQL) ├─ rest:3000 (PostgREST) ├─ auth:9999 (GoTrue) ├─ realtime:4000 (Realtime) ├─ storage:5000 (Storage) ├─ kong:8000 (Kong internal) ├─ studio:3000 (Studio) ├─ meta:8080 (PostgreSQL Meta) ├─ analytics:4000 (Logflare) ├─ imgproxy:5001 (Image Proxy) └─ vector:9001 (Log Router)
All services communicate using service names (e.g., http://db:5432)External Access
Section titled “External Access”localhost:54321 → Kong → All API serviceslocalhost:54323 → Studio UIlocalhost:5432 → PostgreSQL (direct connection)localhost:54324 → Analytics dashboardData Flow
Section titled “Data Flow”Write Operation
Section titled “Write Operation”1. Client sends INSERT request2. Kong validates JWT and routes to PostgREST3. PostgREST connects as appropriate role4. PostgreSQL applies RLS policies5. Row inserted if policies pass6. PostgreSQL triggers fire (if any)7. Change logged to Write-Ahead Log (WAL)8. Realtime server reads WAL9. Realtime broadcasts to subscribed clients10. Response sent back to original clientRead Operation
Section titled “Read Operation”1. Client sends SELECT request2. Kong validates JWT and routes to PostgREST3. PostgREST connects as appropriate role4. PostgreSQL applies RLS policies5. Only visible rows returned6. Response formatted as JSON7. Sent back through Kong to clientSecurity Layers
Section titled “Security Layers”1. Network Layer
Section titled “1. Network Layer”- Docker internal network isolation
- Only necessary ports exposed
- Kong acts as single entry point
2. Authentication Layer
Section titled “2. Authentication Layer”- JWT validation on every request
- Token expiry (default 1 hour)
- Refresh token rotation
3. Authorization Layer
Section titled “3. Authorization Layer”- Role-based access (anon/authenticated/service_role)
- Row Level Security (RLS) policies
- Column-level permissions
4. Data Layer
Section titled “4. Data Layer”- Encrypted connections (in production)
- Password hashing (bcrypt)
- SQL injection prevention (parameterized queries)
Configuration Files
Section titled “Configuration Files”Environment Variables (.env.local)
Section titled “Environment Variables (.env.local)”Configures:- Database credentials- JWT secrets- API endpoints- Service ports- Email settingsKong Configuration (kong.yml)
Section titled “Kong Configuration (kong.yml)”Defines:- Service routes- Authentication rules- CORS policies- Rate limitsDatabase Init Scripts (volumes/db/*.sql)
Section titled “Database Init Scripts (volumes/db/*.sql)”Sets up:- Database roles- Schemas (_realtime, _analytics, etc.)- Permissions- ExtensionsHealth Checks
Section titled “Health Checks”Each service has health checks:
PostgreSQL: pg_isreadyPostgREST: Health endpointGoTrue: /health endpointRealtime: /health endpointStorage: /status endpointKong: Admin APIStudio: HTTP requestAnalytics: /health endpointImgProxy: health commandVector: /health endpointView status: make supabase-status
Logs and Monitoring
Section titled “Logs and Monitoring”Vector (Log Router) │ │ Collects logs from all containers ▼Logflare (Analytics) │ │ Aggregates and stores logs ▼Studio Dashboard │ │ Displays logs in UIAccess logs: make supabase-logs
Backup and Recovery
Section titled “Backup and Recovery”Automatic Backups
Section titled “Automatic Backups”Database → pg_dump → backups/local-backup-YYYYMMDD.sqlRecovery
Section titled “Recovery”backups/backup.sql → psql → PostgreSQLCommands:
make supabase-backup- Create backupmake supabase-restore FILE=backup.sql- Restore
Development vs Production
Section titled “Development vs Production”| Aspect | Local | Production |
|---|---|---|
| Network | Docker internal | Internet |
| HTTPS | No (HTTP only) | Yes (required) |
| Emails | Auto-confirmed | Real delivery |
| Storage | Local files | S3/GCS |
| Scaling | Single node | Distributed |
| Backups | Manual | Automated |
| Monitoring | Basic logs | Full observability |
Troubleshooting
Section titled “Troubleshooting”Check Service Health
Section titled “Check Service Health”make supabase-statusdocker-compose psView Logs
Section titled “View Logs”make supabase-logsdocker-compose logs <service>Test Connectivity
Section titled “Test Connectivity”# Databasemake supabase-db
# APIcurl http://localhost:54321/rest/v1/
# Studioopen http://localhost:54323Reset Everything
Section titled “Reset Everything”make supabase-resetmake supabase-startmake supabase-migratePerformance Tuning
Section titled “Performance Tuning”Database Connections
Section titled “Database Connections”- Max connections: 100 (default)
- Pooling via authenticator role
- Connection timeout: 30s
API Rate Limits
Section titled “API Rate Limits”- Default: Unlimited in local
- Configure in kong.yml if needed
Resource Limits
Section titled “Resource Limits”- Adjust in docker-compose.yml
- Default: Docker desktop limits
Best Practices
Section titled “Best Practices”- Use RLS Everywhere: Always enable Row Level Security
- Test Migrations Locally: Before production deploy
- Backup Regularly: Before major changes
- Monitor Logs: Keep
make supabase-logsrunning - Reset Often: Test fresh installation
- Version Lock: Pin service versions in docker-compose.yml
- Secure Secrets: Never commit .env.local to git