Last updated: Aug 4, 2025, 11:26 AM UTC

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

  1. What is Supabase?
  2. Architecture Overview
  3. Setup Options
  4. Quick Start
  5. Detailed Service Configuration
  6. Migration Strategy
  7. Security Configuration
  8. Testing and Verification
  9. Troubleshooting
  10. 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

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

  1. Multi-tenancy: Use organization_id for data isolation
  2. Row Level Security: Implement RLS policies for all tables
  3. Audit trails: Add created_at, updated_at timestamps
  4. Soft deletes: Use deleted_at instead of hard deletes
  5. 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

  1. Anon Key: Public key for browser, limited permissions
  2. Service Role Key: Server-side only, bypasses RLS
  3. JWT Secret: For signing tokens, never expose

Security Best Practices

  1. Always enable RLS on public tables
  2. Use environment variables for sensitive keys
  3. Implement rate limiting via Kong
  4. Regular security audits with pg_stat_statements
  5. Use SSL/TLS in production
  6. Implement proper CORS policies
  7. 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

  1. Local Development: Continue with local-development-guide.md
  2. Production Setup: See cloud-setup-guide.md
  3. Multi-tenancy: Review multi-tenant-architecture-guide.md
  4. Testing: Follow verification-guide.md

Additional Resources

Support

For issues specific to this setup:

  1. Check the troubleshooting section
  2. Review Docker logs
  3. Consult the verification guide
  4. Check Supabase Discord/GitHub Discussions