Local Development
Tại sao cần Local Development?
Vấn đề với cloud-only development
- Phụ thuộc internet connection
- Chậm khi test migrations
- Khó debug database issues
- Tốn tiền (nếu vượt free tier)
- Conflicts khi nhiều người cùng dev
Local development giải quyết
- Offline development
- Fast iteration
- Safe testing
- Isolated environment
- Consistent với CI/CD
Cài đặt Supabase CLI
macOS
brew install supabase/tap/supabase
Windows (npm)
Linux
# Download binary
curl -fsSL https://supabase.com/install.sh | sh
Verify installation
supabase --version
# Supabase CLI 1.x.x
Khởi tạo Local Project
Step 1: Init Supabase
# Trong thư mục project
supabase init
# Tạo folder structure:
# supabase/
# ├── config.toml
# ├── migrations/
# └── seed.sql
Step 2: Start services
supabase start
# Output:
# Started supabase local development setup.
#
# API URL: http://127.0.0.1:54321
# GraphQL URL: http://127.0.0.1:54321/graphql/v1
# DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
# Studio URL: http://127.0.0.1:54323
# Inbucket URL: http://127.0.0.1:54324
# anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Local Services
┌─────────────────────────────────────────────────────────────┐
│ SUPABASE LOCAL │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ Port 54323 │
│ │ Studio │ Database GUI (like pgAdmin) │
│ └─────────────┘ │
│ │
│ ┌─────────────┐ Port 54321 │
│ │ REST API │ PostgREST endpoints │
│ └─────────────┘ │
│ │
│ ┌─────────────┐ Port 54322 │
│ │ PostgreSQL │ Direct database access │
│ └─────────────┘ │
│ │
│ ┌─────────────┐ Port 54324 │
│ │ Inbucket │ Email testing (catches all emails) │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Environment Variables cho Local
# .env.local (cho local development)
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# .env.production (cho production)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Script để switch environments
// package.json
{
"scripts": {
"dev": "next dev",
"dev:local": "supabase start && next dev",
"db:reset": "supabase db reset",
"db:push": "supabase db push",
"db:pull": "supabase db pull"
}
}
Migrations
Tạo migration mới
supabase migration new create_users_table
# Tạo file: supabase/migrations/20240101000000_create_users_table.sql
Viết migration
-- supabase/migrations/20240101000000_create_users_table.sql
-- Create table
CREATE TABLE public.users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
full_name TEXT,
avatar_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Enable RLS
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
-- Create policy
CREATE POLICY "Users can view own profile"
ON public.users FOR SELECT
USING (auth.uid() = id);
-- Create updated_at trigger
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON public.users
FOR EACH ROW
EXECUTE FUNCTION extensions.moddatetime(updated_at);
Apply migrations
# Apply to local
supabase db reset # Reset và apply tất cả migrations
# Apply to remote (production)
supabase db push
Seed Data
-- supabase/seed.sql
-- Insert test users
INSERT INTO public.users (id, email, full_name)
VALUES
('00000000-0000-0000-0000-000000000001', 'admin@test.com', 'Admin User'),
('00000000-0000-0000-0000-000000000002', 'user@test.com', 'Test User');
-- Insert test posts
INSERT INTO public.posts (title, content, author_id)
VALUES
('First Post', 'Hello World!', '00000000-0000-0000-0000-000000000001'),
('Second Post', 'Testing...', '00000000-0000-0000-0000-000000000002');
Apply seed
# Reset database và apply seed
supabase db reset
# Seed chỉ chạy khi reset, không chạy khi push
Studio (Local GUI)
Truy cập Studio
Features
- Table Editor - GUI cho CRUD operations
- SQL Editor - Chạy SQL queries
- Authentication - Quản lý users
- Storage - Upload files
- API Docs - Auto-generated docs
- Logs - View database logs
Inbucket (Email Testing)
Truy cập Inbucket
Use cases
- Test password reset emails
- Test email verification
- Test magic link login
- Debug email templates
Common Commands
# Start all services
supabase start
# Stop all services
supabase stop
# Reset database (apply migrations + seed)
supabase db reset
# View status
supabase status
# View logs
supabase db logs
# Generate types
supabase gen types typescript --local > types/supabase.ts
# Link to remote project
supabase link --project-ref your-project-ref
# Pull remote schema to local
supabase db pull
# Push local migrations to remote
supabase db push
# Diff local vs remote
supabase db diff
Workflow Development
┌─────────────────────────────────────────────────────────────┐
│ DEVELOPMENT WORKFLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. supabase start │
│ └─▶ Start local services │
│ │
│ 2. Develop features │
│ └─▶ Use local URL in .env.local │
│ │
│ 3. Create migrations │
│ └─▶ supabase migration new feature_name │
│ │
│ 4. Test locally │
│ └─▶ supabase db reset │
│ │
│ 5. Commit & Push │
│ └─▶ git add supabase/migrations && git commit │
│ │
│ 6. Deploy to staging │
│ └─▶ supabase db push --linked │
│ │
│ 7. Deploy to production │
│ └─▶ CI/CD pipeline │
│ │
└─────────────────────────────────────────────────────────────┘
Hands-on Exercise
Setup local development
# 1. Init supabase
supabase init
# 2. Start services
supabase start
# 3. Create first migration
supabase migration new create_tasks_table
# 4. Edit migration file
cat > supabase/migrations/*_create_tasks_table.sql << 'EOF'
CREATE TABLE public.tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
completed BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY;
EOF
# 5. Apply migration
supabase db reset
# 6. Open Studio
open http://127.0.0.1:54323
# 7. Generate types
supabase gen types typescript --local > types/supabase.ts
Tổng kết
Local Development Checklist
- [ ] Install Supabase CLI
- [ ] Init supabase trong project
- [ ] Start local services
- [ ] Update .env.local với local URLs
- [ ] Create và test migrations locally
- [ ] Seed data cho testing
- [ ] Use Studio cho database management
Key Commands
| Command |
Purpose |
supabase start |
Start local services |
supabase stop |
Stop services |
supabase db reset |
Reset + migrate + seed |
supabase db push |
Push to remote |
supabase gen types |
Generate TypeScript |
Q&A
- Docker đã cài đặt chưa? (Required for local dev)
- Có vấn đề gì khi start không?
- Studio hoạt động tốt không?