Tóm tắt
Supabase CLI giúp bạn khởi chạy một ngăn xếp Supabase hoàn chỉnh trên máy tính bằng Docker: PostgreSQL, Auth, Storage và Edge Functions. Cài đặt nhanh qua brew install supabase/tap/supabase, sau đó chạy supabase init và supabase start để thiết lập môi trường cục bộ. Sử dụng supabase db push và supabase functions deploy để triển khai các thay đổi lên sản xuất. Đây là giải pháp hiệu quả nhất để phát triển và kiểm thử backend Supabase mà không cần phụ thuộc vào cloud.
Giới thiệu
73% lỗi backend thường chỉ được phát hiện khi đã lên production vì thiếu kiểm thử cục bộ. Supabase CLI giải quyết triệt để vấn đề này bằng cách cung cấp một môi trường mô phỏng production đầy đủ, khởi động trên máy bạn chỉ trong 5 phút.
Nếu bạn từng kiểm thử trực tiếp trên production hoặc tốn hàng giờ để cấu hình môi trường cục bộ không đồng nhất với cloud, Supabase CLI sẽ giúp bạn loại bỏ hoàn toàn các rắc rối này. Mọi thứ bạn xây dựng, kiểm thử cục bộ đều hoạt động nhất quán khi lên production.
💡 Nếu bạn phát triển API trên Supabase, hãy sử dụng Apidog để thiết kế, kiểm thử và tạo tài liệu endpoint trong quá trình làm việc. Apidog kết nối trực tiếp với REST & GraphQL API của Supabase, giúp bạn kiểm thử backend khi phát triển cục bộ.
Kiểm thử API Supabase của bạn với Apidog - miễn phí.
Sau bài viết này, bạn sẽ biết cách:
- Thiết lập môi trường Supabase cục bộ trong vài phút
- Quản lý schema DB bằng migration kiểm soát phiên bản
- Xây dựng và test Edge Functions cục bộ trước khi deploy
- Triển khai production chỉ với một lệnh
Tại sao phát triển Supabase cục bộ sẽ gặp lỗi nếu không có CLI
Nếu từng tự thiết lập Supabase mà bỏ qua CLI, bạn sẽ gặp ít nhất một trong các vấn đề sau:
- Kiểm thử trên production: Thay đổi schema trực tiếp trên Supabase Console hoạt động với bạn nhưng đồng đội kéo repo về lại lỗi vì thiếu cột mới.
- Môi trường không đồng nhất: Tự cài PostgreSQL, dựng schema thủ công, debug hàng giờ vì RLS hoạt động khác nhau (thực tế là bạn thiếu policy).
- “Chạy được trên máy tôi”: Edge Function ổn trong Console nhưng fail trên production do kiểm thử với giá trị hard-code thay vì biến môi trường.
Supabase CLI xử lý triệt để:
- Migration kiểm soát mọi thay đổi schema, version hóa rõ ràng
- Docker stack cục bộ mô phỏng production hoàn chỉnh (đúng version PostgreSQL, đúng RLS)
- Chạy Edge Function cục bộ, kiểm thử với biến môi trường thực tế
Supabase CLI hoạt động như thế nào
Ngăn xếp cục bộ
Chạy supabase start, CLI khởi tạo một Docker Compose stack gồm các dịch vụ:
| Dịch vụ | Cổng | Mục đích |
|---|---|---|
| PostgreSQL | 54322 | Cơ sở dữ liệu của bạn |
| PostgREST | 54321 | API REST tự động tạo |
| GoTrue | 54321/auth | Dịch vụ xác thực |
| Realtime | 54321/realtime | Các gói đăng ký WebSocket |
| Storage | 54321/storage | Lưu trữ tệp |
| Studio | 54323 | Bảng điều khiển trực quan |
| Inbucket | 54324 | Kiểm thử email (nhận tất cả email cục bộ) |
| Edge Runtime | 54321/functions | Trình chạy hàm dựa trên Deno |
Đây chính là ngăn xếp Supabase Cloud ngay trên máy bạn.
Cài đặt
macOS:
brew install supabase/tap/supabase
Windows (Scoop):
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
Linux / npm:
npm install -g supabase
Xác minh:
supabase --version
# supabase 1.x.x
Khởi động stack:
supabase start
Thiết lập dự án
mkdir my-project && cd my-project
supabase init
Sinh ra thư mục cấu hình:
supabase/
├── config.toml # Cài đặt cổng, auth, storage
├── seed.sql # Dữ liệu mẫu tự động nạp khi reset db
└── migrations/ # Lịch sử schema (migration)
Khởi động ngăn xếp cục bộ
supabase start
Lần đầu tải Docker image (~1GB). Các lần sau chỉ mất ~10 giây.
Kết quả:
API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio: http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Copy anon key vào .env.local để dùng cho frontend.
Quản lý cơ sở dữ liệu với migration
Migration là trung tâm quy trình làm việc: mọi thay đổi schema đều version hóa, lưu vào Git, đồng bộ team.
Tạo migration đầu tiên
supabase migration new create_posts_table
# Tạo: supabase/migrations/20260324120000_create_posts_table.sql
Chỉnh sửa file:
-- Tạo bảng posts với RLS ngay từ đầu
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
title TEXT NOT NULL,
content TEXT,
published BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Anyone can read published posts"
ON posts FOR SELECT
USING (published = true);
CREATE POLICY "Users manage own posts"
ON posts FOR ALL
USING (auth.uid() = user_id);
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER posts_updated_at
BEFORE UPDATE ON posts
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
Áp dụng migration:
supabase migration up
Sinh các kiểu TypeScript
Sau mỗi thay đổi schema, chạy:
supabase gen types typescript --local > src/types/database.ts
Ví dụ sử dụng:
import { Database } from '@/types/database'
type Post = Database['public']['Tables']['posts']['Row']
type NewPost = Database['public']['Tables']['posts']['Insert']
const createPost = async (post: NewPost) => {
const { data, error } = await supabase
.from('posts')
.insert(post)
.select()
.single()
return data
}
Gieo dữ liệu phát triển
Chỉnh sửa supabase/seed.sql:
-- Người dùng thử nghiệm
INSERT INTO auth.users (id, email) VALUES
('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
('00000000-0000-0000-0000-000000000002', 'bob@example.com');
-- Bài viết thử nghiệm
INSERT INTO posts (user_id, title, content, published) VALUES
('00000000-0000-0000-0000-000000000001', 'Bắt đầu với Supabase', 'Đây là những gì tôi đã học...', true),
('00000000-0000-0000-0000-000000000002', 'Bản nháp: Các mẫu thiết kế API', 'Đang trong quá trình...', false);
Reset mọi thứ và nạp dữ liệu mẫu:
supabase db reset
Kiểm thử API Supabase với Apidog
Khi Supabase cục bộ đang chạy, API REST đầy đủ có sẵn tại http://localhost:54321. Supabase tự sinh endpoint cho mọi bảng qua PostgREST. Kiểm thử thủ công bằng curl rất bất tiện, nhất là khi cần test RLS với nhiều user token.
Apidog kết nối trực tiếp Supabase cục bộ, hỗ trợ:
- Lưu request thành collection tái sử dụng
- Test cùng endpoint với nhiều user bằng chuyển environment
- Thêm xác nhận (ví dụ: response trả về ít nhất 1 bài viết), chạy thành test suite
- Chia sẻ tài liệu API tự động cho team
Thiết lập Apidog với Supabase cục bộ:
- Tạo project mới trong Apidog
- Đặt base URL:
http://localhost:54321 - Thêm biến môi trường:
anon_key = your-local-anon-key - Thêm header Authorization:
Bearer {{anon_key}}
Test endpoint posts:
GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
Lưu request này, thêm xác nhận (response chứa ít nhất 1 bài viết), chạy lại mỗi khi sửa policy RLS.
Kiểm thử API Supabase với Apidog - miễn phí
Edge Functions: xây dựng và kiểm thử cục bộ
Edge Functions chạy trên Deno, gần user, lý tưởng cho webhook, job nền hoặc custom API endpoint.
Tạo một hàm mới
supabase functions new send-welcome-email
Sinh ra file: supabase/functions/send-welcome-email/index.ts:
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
serve(async (req) => {
const { user_id } = await req.json()
// Service role bỏ qua RLS - chỉ dùng phía server
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
const { data: profile } = await supabase
.from('profiles')
.select('email, full_name')
.eq('id', user_id)
.single()
console.log(`Đang gửi email chào mừng tới ${profile?.email}`)
return new Response(
JSON.stringify({ success: true }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
Kiểm thử cục bộ với hot reload
supabase functions serve
Chạy thử:
curl -X POST http://localhost:54321/functions/v1/send-welcome-email \
-H "Authorization: Bearer YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
-d '{"user_id": "00000000-0000-0000-0000-000000000001"}'
Triển khai lên production
# Deploy một hàm
supabase functions deploy send-welcome-email
# Deploy toàn bộ hàm
supabase functions deploy
Kỹ thuật nâng cao và quy trình thực chiến
Quản lý bí mật
Không hard-code API key trong code. Sử dụng secret:
# Đặt secret production
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx
# Xem secret
supabase secrets list
# Xóa secret
supabase secrets unset STRIPE_KEY
Truy cập trong hàm:
const resendKey = Deno.env.get('RESEND_API_KEY')
// Không hard-code: const resendKey = 're_xxx'
Phân nhánh cơ sở dữ liệu
Làm việc với thay đổi lớn? Dùng branch DB:
supabase branches create feature-payments
supabase branches switch feature-payments
# Test xong, hợp nhất về main
supabase branches merge feature-payments
Những lỗi thường gặp cần tránh
- Chỉnh sửa DB trên Studio: Luôn dùng migration, không chỉnh trực tiếp.
-
Commit file
.env: Dùngsupabase secrets setcho production, thêm.env*vào.gitignore. -
Không reset DB khi pull về: Sau khi pull, chạy
supabase db resetđể sync migration mới của team. - Không sinh lại kiểu TypeScript: Sau mỗi thay đổi schema, luôn tạo lại types.
-
Deploy function khi chưa test cục bộ: Luôn test với
supabase functions servetrước khi deploy. - Dùng service role key ở frontend: Không bao giờ để key này ở client, chỉ dùng cho server hoặc Edge Functions.
Mẹo tối ưu hiệu suất
# Bỏ qua dịch vụ không dùng để tiết kiệm RAM
supabase start --exclude-studio --exclude-inbucket
# Kiểm tra tài nguyên Docker
docker stats
So sánh với các lựa chọn thay thế
| Tính năng | Supabase CLI | Firebase CLI | PlanetScale CLI |
|---|---|---|---|
| Cơ sở dữ liệu cục bộ | PostgreSQL đầy đủ | Chỉ trình giả lập | Chỉ đám mây |
| Migration | Tệp SQL trong Git | Không hỗ trợ gốc | Phân nhánh |
| Edge Functions | Thời gian chạy Deno | Cloud Functions | Không bao gồm |
| Xác thực cục bộ | GoTrue đầy đủ | Trình giả lập | Không bao gồm |
| Mã nguồn mở | Hoàn toàn mở | Độc quyền | Độc quyền |
| Tạo kiểu | Tích hợp sẵn | Thủ công | Thủ công |
Firebase CLI chỉ giả lập, không có PostgreSQL thực. PlanetScale CLI ưu việt ở phân nhánh schema nhưng mọi thứ đều trên cloud. Supabase CLI phù hợp nhất cho team cần phát triển cục bộ, mã nguồn mở, native PostgreSQL.
Trường hợp sử dụng thực tế
- SaaS đa tenant: Startup fintech quản lý 47 migration trên 3 môi trường, kiểm thử RLS cục bộ với nhiều vai trò user. 6 tháng không có lỗi schema production.
-
Xử lý đơn hàng ecommerce: Dùng Edge Function nhận webhook Stripe, kiểm thử payload cục bộ với
supabase functions serve. Thời gian deploy giảm từ 2h → 15 phút. - Backend app mobile: Team React Native sinh TypeScript types sau mỗi migration, chia sẻ qua npm package, frontend/backend đồng bộ tuyệt đối.
Tổng kết
Bạn có thể triển khai ngay quy trình:
- Thiết lập Supabase cục bộ trong vài phút
- Dùng migration để version hóa mọi thay đổi DB
- Kiểm thử Edge Functions cục bộ với hot reload
- Tự động sinh TypeScript type từ schema
- Triển khai với
supabase db push&supabase functions deploy - Kiểm thử API với Apidog trước khi lên production
Quy trình này tăng hiệu quả, giảm lỗi, loại bỏ hoàn toàn vấn đề lệch schema giữa team.
Các bước hành động:
- Cài đặt:
brew install supabase/tap/supabase - Chạy
supabase inittrong thư mục dự án - Tạo migration đầu tiên
- Thiết lập Apidog kiểm thử endpoint cục bộ
- Triển khai production tự tin
Kiểm thử API Supabase với Apidog - miễn phí
Câu hỏi thường gặp
Tôi có cần Docker để dùng Supabase CLI không?
Có. Docker Desktop phải chạy trước khi supabase start. CLI dùng Docker Compose để chạy full stack cục bộ.
Làm sao đồng bộ DB cục bộ với production?
Dùng supabase db pull để lấy migration từ schema production, rồi supabase db push để đẩy migration cục bộ lên cloud. Sau khi pull, luôn supabase db reset để cục bộ khớp schema.
Dùng Supabase CLI mà không cần tài khoản cloud được không?
Được. Bạn chỉ cần đăng nhập khi muốn deploy lên production.
Xử lý conflict migration trong team thế nào?
Pull code mới nhất, reset DB (supabase db reset) trước khi tạo migration mới. Đặt tên migration rõ ràng, trao đổi khi có thay đổi phá vỡ schema.
Khác biệt giữa supabase db push và supabase migration up?
supabase migration up chạy migration lên DB cục bộ. supabase db push đẩy migration lên production. Luôn test cục bộ trước.
Dùng CLI cho dự án Supabase đã có sẵn được không?
Được. Chạy supabase link --project-ref YOUR_PROJECT_ID để liên kết, sau đó supabase db pull để tạo migration từ schema hiện tại.
Kiểm thử RLS cục bộ thế nào?
Dùng Studio (http://localhost:54323) chuyển vai trò user hoặc test qua API với nhiều JWT khác nhau. Apidog hỗ trợ tạo nhiều environment với token người dùng riêng, test giống production.
Supabase CLI có miễn phí không?
Có. CLI miễn phí, mã nguồn mở. Phát triển cục bộ không tốn phí, chỉ trả cho cloud khi deploy production.
Top comments (0)