Supabase Local Development

Complete guide to run Supabase locally with Docker and connect it to your Next.js application

Prerequisites
Ensure you have the required tools installed
Docker Desktop
Node.js (LTS)
Supabase CLI v2+
Install Supabase CLI:
# macOS (Homebrew)
brew install supabase/tap/supabase
# Linux
curl -fsSL https://cli.supabase.com/install/linux | sh
# Windows (Scoop)
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
Step 1: Initialize
Set up Supabase in your project
# From project root
supabase init

Creates a supabase/ folder for migrations, seed, and config.

Step 2: Start Stack
Launch local Supabase services
supabase start

Pulls Docker images and boots Postgres, Auth, Realtime, Storage, and Studio.

Local Endpoints
Default connection information for local development
API URL
http://127.0.0.1:54321
Studio (Web UI)
http://127.0.0.1:54323
Postgres
127.0.0.1:54322
Environment Configuration
Set up your Next.js app to connect to local Supabase

Create .env.local in your project root:

# Supabase — Local
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=REPLACE_WITH_LOCAL_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY=REPLACE_WITH_LOCAL_SERVICE_ROLE_KEY
# server-only, never sent to client
Important:

Copy the actual keys from the supabase start output. Restart your dev server after adding these variables.

Database Management
Work with your local database schema and data

Create Migration

supabase migration new add_instruments

Apply Changes

supabase db push
supabase db reset
-- Example migration
create table if not exists public.instruments (
id bigint generated always as identity primary key,
name text not null
);
alter table public.instruments enable row level security;
Troubleshooting
Common issues and solutions
Port Conflicts

Stop old containers, then supabase stop docker ps -a

RLS Errors

Confirm table has a policy for anon when reading

Migration Failures

Ensure idempotent SQL; test with supabase db reset

Quick Actions
Common commands for development workflow
Advanced Configuration
Customize your local Supabase setup

Custom Ports

# supabase/config.toml
[api]
port = 54321
[db]
port = 54322
[studio]
port = 54323

Environment Variables

# supabase/config.toml
[auth]
site_url = "http://localhost:3000"
additional_redirect_urls = ["http://localhost:3000/auth/callback"]
Pro Tip:

You can customize database settings, enable/disable services, and configure authentication by editing the supabase/config.toml file.

Development Workflow
Best practices for working with local Supabase
1

Start Local Stack

Begin your development session with supabase start

2

Make Schema Changes

Create migrations for database changes: supabase migration new feature_name

3

Test Changes

Apply migrations and test your application locally

4

Commit & Push

Commit your migration files and push to your repository

Performance & Monitoring
Monitor your local Supabase performance

Resource Usage

• Monitor Docker container resources
• Check database connection limits
• Watch for memory leaks

Logs & Debugging

supabase logs - View service logs
docker logs - Container logs
• Studio dashboard for real-time metrics
Security Best Practices
Keep your local development secure
Never Commit Secrets

Keep all API keys in .env.local

Use RLS Policies

Implement proper row-level security

Security Checklist:
✓ Enable RLS on all tables
✓ Use environment variables
✓ Implement proper policies
✓ Regular security updates
Integration Examples
Code examples for common use cases

Client-Side Authentication

{/* components/auth-form.tsx */}
const { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'password'
})

Server-Side Data Fetching

{/* app/instruments/page.tsx */}
export async function getInstruments() {
const { data } = await supabase
.from('instruments')
.select('*')
return data
}