Supabase Complete Setup Guide
Status: Complete
Overview
This guide provides comprehensive instructions for setting up Supabase as a complete backend-as-a-service solution, including authentication, database, real-time subscriptions, and storage. This guide is designed to be used independently from any specific application implementation.
Table of Contents
- What is Supabase?
- Architecture Overview
- Setup Options
- Quick Start
- Detailed Service Configuration
- Migration Strategy
- Security Configuration
- Testing and Verification
- Troubleshooting
- Next Steps
What is Supabase?
Supabase is an open-source Firebase alternative that provides:
- PostgreSQL Database: Full PostgreSQL database with extensions
- Authentication: User management and authentication service
- Real-time Subscriptions: Live database changes via websockets
- Storage: File storage with CDN
- Edge Functions: Serverless functions (Deno)
- Vector Embeddings: AI/ML capabilities with pgvector
Key Differences from Plain PostgreSQL
| Feature | PostgreSQL | Supabase |
|---|---|---|
| Database | Core database | PostgreSQL + extensions |
| REST API | Requires custom backend | Auto-generated via PostgREST |
| Authentication | Custom implementation | Built-in auth service (GoTrue) |
| Real-time | Requires polling/websockets | Built-in real-time subscriptions |
| File Storage | Custom solution needed | S3-compatible storage |
| Admin UI | pgAdmin or similar | Supabase Studio |
| Row Level Security | Available but complex | Simplified RLS policies |
Architecture Overview
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Application β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Kong API Gateway β
β (Port 8000/54321) β
ββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββββββββββ
β β β β
βΌ βΌ βΌ βΌ
ββββββββββββββββ ββββββββββββ ββββββββββ ββββββββββββββββ
β PostgREST β β GoTrue β βStorage β β Realtime β
β (REST API) β β (Auth) β β (S3) β β(WebSockets) β
ββββββββ¬ββββββββ ββββββ¬ββββββ βββββ¬βββββ ββββββββ¬ββββββββ
β β β β
ββββββββββββββββ΄βββββββββββββ΄βββββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β PostgreSQL 15 β
β (Port 5432/54322) β
βββββββββββββββββββββββββ
Setup Options
Option 1: Local Development (Docker)
Best for development and testing. See local-development-guide.md
Option 2: Cloud Hosted (Supabase Platform)
Best for production. See cloud-setup-guide.md
Option 3: Self-Hosted Production
Best for enterprise requirements. See Supabase self-hosting documentation.
Quick Start
Prerequisites
- Docker and Docker Compose (for local setup)
- Node.js 18+ (for client applications)
- Git
1. Local Setup in 5 Minutes
# Clone the templates
git clone <your-repo>
cd docs/private/guides/deploy/supabase/templates
# Copy environment template
cp .env.example .env
# Generate secure keys
openssl rand -hex 32 # For JWT_SECRET
openssl rand -hex 32 # For ANON_KEY
openssl rand -hex 32 # For SERVICE_ROLE_KEY
# Start Supabase stack
docker-compose up -d
# Verify services are running
docker-compose ps
2. Access Points
- Supabase Studio: http://localhost:54323
- API Gateway: http://localhost:54321
- PostgreSQL: localhost:54322 (user: postgres, password: postgres)
- Inbucket (email testing): http://localhost:54324
3. Initialize Database
# Run migrations
docker exec -i supabase-db psql -U postgres -d postgres < migrations/001_initial_schema.sql
docker exec -i supabase-db psql -U postgres -d postgres < migrations/002_auth_setup.sql
docker exec -i supabase-db psql -U postgres -d postgres < migrations/003_rls_policies.sql
Detailed Service Configuration
PostgreSQL Database
The core of Supabase, running PostgreSQL 15 with extensions:
-- Essential extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generation
CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- Cryptographic functions
CREATE EXTENSION IF NOT EXISTS "pgjwt"; -- JWT tokens
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements"; -- Query performance
CREATE EXTENSION IF NOT EXISTS "pgvector"; -- Vector embeddings
CREATE EXTENSION IF NOT EXISTS "pg_net"; -- HTTP client
Authentication Service (GoTrue)
Handles user registration, login, and session management:
// Client-side authentication example
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
// Sign up
const { user, error } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'secure-password'
})
// Sign in
const { user, session } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'secure-password'
})
REST API (PostgREST)
Automatically generates RESTful API from your database schema:
// CRUD operations
const { data, error } = await supabase
.from('users')
.select('*')
.eq('organization_id', orgId)
.order('created_at', { ascending: false })
Real-time Subscriptions
Listen to database changes in real-time:
// Subscribe to changes
const subscription = supabase
.channel('room1')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'messages'
}, (payload) => {
console.log('Change received!', payload)
})
.subscribe()
Storage
S3-compatible object storage:
// Upload file
const { data, error } = await supabase.storage
.from('avatars')
.upload('public/avatar.png', file)
// Get public URL
const { data: url } = supabase.storage
.from('avatars')
.getPublicUrl('public/avatar.png')
Migration Strategy
Schema Design Principles
- Multi-tenancy: Use organization_id for data isolation
- Row Level Security: Implement RLS policies for all tables
- Audit trails: Add created_at, updated_at timestamps
- Soft deletes: Use deleted_at instead of hard deletes
- UUID primary keys: Use UUID for better distribution
Sample Migration Structure
-- 001_initial_schema.sql
CREATE SCHEMA IF NOT EXISTS public;
-- Enable RLS
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON TABLES TO postgres, anon, authenticated, service_role;
-- Create base tables
CREATE TABLE organizations (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 002_auth_setup.sql
-- Link auth.users to profiles
CREATE TABLE profiles (
id UUID REFERENCES auth.users PRIMARY KEY,
organization_id UUID REFERENCES organizations,
full_name TEXT,
avatar_url TEXT
);
-- 003_rls_policies.sql
-- Enable RLS
ALTER TABLE organizations ENABLE ROW LEVEL SECURITY;
-- Organization members can read their org
CREATE POLICY "Users can view own organization" ON organizations
FOR SELECT USING (
id IN (
SELECT organization_id FROM profiles
WHERE id = auth.uid()
)
);
Security Configuration
Row Level Security (RLS)
Essential for multi-tenant applications:
-- Enable RLS on table
ALTER TABLE contacts ENABLE ROW LEVEL SECURITY;
-- Policy: Users can only see contacts in their organization
CREATE POLICY "Organization contacts isolation" ON contacts
FOR ALL USING (
organization_id IN (
SELECT organization_id
FROM profiles
WHERE id = auth.uid()
)
);
API Key Types
- Anon Key: Public key for browser, limited permissions
- Service Role Key: Server-side only, bypasses RLS
- JWT Secret: For signing tokens, never expose
Security Best Practices
- Always enable RLS on public tables
- Use environment variables for sensitive keys
- Implement rate limiting via Kong
- Regular security audits with pg_stat_statements
- Use SSL/TLS in production
- Implement proper CORS policies
- Regular backups with point-in-time recovery
Testing and Verification
See verification-guide.md for detailed testing procedures.
Quick Health Check
# Check all services are running
curl http://localhost:54321/rest/v1/ \
-H "apikey: your-anon-key" \
-H "Authorization: Bearer your-anon-key"
# Test database connection
docker exec supabase-db psql -U postgres -c "SELECT version();"
# Check auth service
curl http://localhost:54321/auth/v1/health
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Cannot connect to database | Docker not running | docker-compose up -d |
| Auth emails not sending | Email provider not configured | Use Inbucket for local testing |
| RLS policies blocking access | Missing or incorrect policies | Check with service role key first |
| API returns 401 | Invalid or expired token | Refresh auth token |
| Migrations fail | Schema conflicts | Drop and recreate database |
Debug Commands
# View logs
docker-compose logs -f [service-name]
# Check database logs
docker logs supabase-db
# Inspect running containers
docker ps
# Database console
docker exec -it supabase-db psql -U postgres
Next Steps
- Local Development: Continue with local-development-guide.md
- Production Setup: See cloud-setup-guide.md
- Multi-tenancy: Review multi-tenant-architecture-guide.md
- Testing: Follow verification-guide.md
Additional Resources
- Official Supabase Documentation
- Supabase GitHub Repository
- PostgreSQL Documentation
- PostgREST Documentation
- GoTrue Documentation
Support
For issues specific to this setup:
- Check the troubleshooting section
- Review Docker logs
- Consult the verification guide
- Check Supabase Discord/GitHub Discussions