Spaces:
Sleeping
Local Development with Supabase CLI
What You'll Learn
- How to run Supabase locally using Docker
- How to use the Supabase CLI
- How to sync your local database with production
- How to test changes before deploying
Why Develop Locally?
β
Faster Development - No network latency
β
Work Offline - No internet required
β
Free - No usage limits
β
Safe Testing - Don't break production
β
Version Control - Track schema changes in Git
Prerequisites
1. Install Docker Desktop
Windows/Mac:
- Download from https://www.docker.com/products/docker-desktop
- Install and start Docker Desktop
- Verify:
docker --version
Linux:
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Start Docker
sudo systemctl start docker
sudo systemctl enable docker
2. Install Supabase CLI
Windows (PowerShell as Administrator):
# Using Scoop
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
# Or download from GitHub releases
# https://github.com/supabase/cli/releases
Mac:
# Using Homebrew
brew install supabase/tap/supabase
# Or using npm
npm install -g supabase
Linux:
# Using npm
npm install -g supabase
# Or download binary
curl -L https://github.com/supabase/cli/releases/latest/download/supabase_linux_amd64.tar.gz | tar -xz
sudo mv supabase /usr/local/bin/
Verify installation:
supabase --version
# Should output: supabase 1.x.x
Step 1: Initialize Supabase in Your Project
Navigate to your project root:
cd swiftops-frontend
Initialize Supabase:
supabase init
This creates a supabase/ folder:
swiftops-frontend/
βββ supabase/
β βββ config.toml # Supabase configuration
β βββ seed.sql # Sample data for testing
β βββ migrations/ # Database schema versions
β βββ (empty for now)
Step 2: Start Local Supabase
Start all Supabase services locally:
supabase start
First run takes 5-10 minutes to download Docker images (~2GB).
Once started, you'll see:
Started supabase local development setup.
API URL: http://localhost:54321
GraphQL URL: http://localhost:54321/graphql/v1
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio URL: http://localhost:54323
Inbucket URL: http://localhost:54324
JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Save these values! You'll need them for local development.
Step 3: Configure Local Environment
Create .env.local for local development:
# .env.local (for local development)
# Local Supabase
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# Copy the anon key from `supabase start` output
Pro Tip: Create separate env files:
# .env.local - Local development
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=local-anon-key
# .env.production - Production
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=production-anon-key
Step 4: Access Local Supabase Studio
Open http://localhost:54323 in your browser.
This is your local Supabase Dashboard where you can:
- View tables and data
- Run SQL queries
- Test RLS policies
- Manage storage buckets
- View logs
No login required for local Studio!
Step 5: Link to Remote Project (Optional)
If you want to sync with your production Supabase project:
# Login to Supabase
supabase login
# Link to your project
supabase link --project-ref your-project-id
Find your project ID:
- Go to https://supabase.com/dashboard
- Select your project
- Project ID is in the URL:
https://supabase.com/dashboard/project/YOUR-PROJECT-ID
Step 6: Deploy Your Schema Locally
Copy your schema.sql to migrations:
# Create a new migration
supabase migration new initial_schema
# This creates: supabase/migrations/20231105120000_initial_schema.sql
Copy your schema content:
# Copy your schema.sql content to the migration file
cp data/schema.sql supabase/migrations/20231105120000_initial_schema.sql
Apply the migration:
supabase db reset
This will:
- Drop the local database
- Apply all migrations
- Run seed data (if any)
Common CLI Commands
Start/Stop Supabase
# Start all services
supabase start
# Stop all services
supabase stop
# Stop and remove all data
supabase stop --no-backup
# Check status
supabase status
Database Management
# Reset database (drop + recreate + apply migrations)
supabase db reset
# Create a new migration
supabase migration new migration_name
# Apply migrations
supabase db push
# Generate types from database schema
supabase gen types typescript --local > types/supabase.ts
Schema Diff
# Compare local schema with remote
supabase db diff
# Generate migration from differences
supabase db diff --schema public | supabase migration new schema_changes
Testing
# Run database tests
supabase test db
# Seed database with test data
supabase db seed
Workflow: Making Schema Changes
Method 1: SQL Migrations (Recommended)
- Create a migration:
supabase migration new add_customer_phone
- Edit the migration file:
-- supabase/migrations/20231105130000_add_customer_phone.sql
ALTER TABLE customers ADD COLUMN phone_alternate TEXT;
CREATE INDEX idx_customers_phone_alternate ON customers(phone_alternate);
- Apply locally:
supabase db reset
Test your changes in local Studio
Commit to Git:
git add supabase/migrations/
git commit -m "Add alternate phone to customers"
- Deploy to production (see
06_MIGRATIONS.md)
Method 2: Studio + Diff (Easier for Beginners)
Make changes in local Studio (http://localhost:54323)
- Create tables
- Add columns
- Create indexes
Generate migration from changes:
supabase db diff --schema public | supabase migration new studio_changes
Review the generated migration
Test by resetting:
supabase db reset
- Commit to Git
Seed Data for Testing
Create supabase/seed.sql for test data:
-- supabase/seed.sql
-- Create test client
INSERT INTO clients (id, name, main_email) VALUES
('11111111-1111-1111-1111-111111111111', 'Test Telecom', 'test@telecom.com');
-- Create test contractor
INSERT INTO contractors (id, name, main_email) VALUES
('22222222-2222-2222-2222-222222222222', 'Test Contractor', 'test@contractor.com');
-- Create test users (must exist in auth.users first)
-- Note: In local dev, you can create auth users via Studio or API
-- Create test project
INSERT INTO projects (
id,
client_id,
contractor_id,
project_name,
status
) VALUES (
'33333333-3333-3333-3333-333333333333',
'11111111-1111-1111-1111-111111111111',
'22222222-2222-2222-2222-222222222222',
'Test Fiber Rollout',
'active'
);
-- Add more test data as needed...
Load seed data:
supabase db reset # This automatically runs seed.sql
Local Email Testing
Supabase local includes Inbucket for email testing:
- Open http://localhost:54324
- Send a magic link or OTP from your app
- View the email in Inbucket
- Click the link or copy the OTP
No real emails are sent in local development!
Environment Switching
Use different env files for different environments:
# Development (local)
npm run dev # Uses .env.local
# Staging
npm run build && npm run start # Uses .env.staging
# Production
npm run build && npm run start # Uses .env.production
Or use a script:
// package.json
{
"scripts": {
"dev": "next dev",
"dev:local": "cp .env.local .env && next dev",
"dev:staging": "cp .env.staging .env && next dev",
"build:prod": "cp .env.production .env && next build"
}
}
Troubleshooting
Issue: "Docker is not running"
Solution:
- Start Docker Desktop
- Wait for it to fully start (green icon)
- Run
docker psto verify
Issue: "Port already in use"
Solution:
# Stop Supabase
supabase stop
# Check what's using the port
# Windows
netstat -ano | findstr :54321
# Mac/Linux
lsof -i :54321
# Kill the process or change Supabase ports in config.toml
Issue: "Migration failed"
Solution:
# Check migration syntax
cat supabase/migrations/your_migration.sql
# Reset and try again
supabase db reset
# If still failing, check logs
supabase status
docker logs supabase_db_swiftops-frontend
Issue: "Can't connect to local Supabase"
Solution:
# Check if services are running
supabase status
# Restart services
supabase stop
supabase start
# Check Docker containers
docker ps
Best Practices
β DO
- Commit migrations to Git
- Test locally before deploying
- Use seed data for consistent testing
- Reset database frequently during development
- Generate TypeScript types from schema
β DON'T
- Edit production database directly
- Skip migrations and change schema manually
- Commit
.env.localto Git - Use production data locally (privacy/security risk)
- Forget to stop Supabase when done (uses resources)
Docker Containers
Supabase local runs these containers:
# View running containers
docker ps
# You'll see:
# - supabase_db_* (PostgreSQL)
# - supabase_kong_* (API Gateway)
# - supabase_auth_* (Auth service)
# - supabase_rest_* (PostgREST)
# - supabase_realtime_* (Realtime service)
# - supabase_storage_* (Storage service)
# - supabase_studio_* (Studio UI)
# - supabase_inbucket_* (Email testing)
Storage location:
- Mac/Linux:
~/.supabase/ - Windows:
%USERPROFILE%\.supabase\
Next Steps
β You now have a local Supabase environment!
π Next: Read 06_MIGRATIONS.md to learn how to deploy your schema
π Or: Read 03_AUTHENTICATION.md to implement user login locally