สรุปสั้นๆ (TL;DR)
Supabase CLI ช่วยให้คุณรัน Supabase stack (PostgreSQL, Authentication, Storage, Edge Functions) บนเครื่องด้วย Docker ได้อย่างครบถ้วน ติดตั้งด้วย brew install supabase/tap/supabase จากนั้นรัน supabase init และ supabase start เพื่อเริ่มใช้งานในเครื่อง ใช้ supabase db push และ supabase functions deploy สำหรับนำขึ้น Production เหมาะสำหรับการสร้างและทดสอบแบ็กเอนด์ Supabase โดยไม่ต้องพึ่งคลาวด์
บทนำ
73% ของข้อผิดพลาดฝั่งแบ็กเอนด์ถูกพบใน Production เพราะนักพัฒนาข้ามการทดสอบบนเครื่อง ด้วย Supabase CLI คุณจะได้สภาพแวดล้อมทดสอบที่เหมือน Production จริงภายใน 5 นาที
ปัญหาหลักคือ นักพัฒนามักทดสอบใน Production (เสี่ยง) หรือเสียเวลาตั้งค่าบนเครื่องที่ไม่เหมือนระบบคลาวด์ (น่าหงุดหงิด) Supabase CLI ให้คุณได้สแต็ก Docker บนเครื่องที่จำลอง Production อย่างแม่นยำ โค้ดที่รันบนเครื่องจะรันได้เหมือนกันใน Production
💡 หากคุณสร้าง API บน Supabase คุณต้องใช้เครื่องมือสำหรับออกแบบ ทดสอบ และทำเอกสาร Apidog เชื่อมต่อกับ REST/GraphQL API ของ Supabase ทำให้คุณทดสอบแบ็กเอนด์ได้ขณะพัฒนา
ทดสอบ Supabase API ของคุณด้วย Apidog - ฟรี
เมื่อจบคู่มือนี้ คุณจะสามารถ:
- ตั้งค่า Supabase ในเครื่องในไม่กี่นาที
- จัดการ schema ด้วย migrations ที่ version control ได้
- สร้าง/ทดสอบ Edge Functions บนเครื่อง
- นำขึ้น Production ด้วยคำสั่งเดียว
ทำไมการพัฒนา Supabase บนเครื่องถึงมีปัญหาหากไม่มี CLI
ถ้าคุณเคยสร้างแอป Supabase โดยไม่มี CLI จะเจอปัญหาเหล่านี้:
- ทดสอบใน Production: เปลี่ยน schema ใน dashboard แล้ว push frontend สามวันต่อมา เพื่อนร่วมทีมดึง repo แล้วแอปพัง เพราะ schema ไม่ sync
- สภาพแวดล้อมไม่ตรงกัน: ตั้งค่า PostgreSQL เอง บาง feature เช่น RLS ไม่ทำงานเหมือน Production เพราะ config ไม่เหมือนกัน
- "It works on my machine": Edge Function รันผ่าน dashboard แต่ล้มเหลวใน Production เพราะทดสอบด้วยค่าฮาร์ดโค้ด
Schema drift คือปัญหาอันดับ 1 สำหรับทีม Supabase CLI ช่วยเรื่องนี้โดย:
- ใช้ migrations สำหรับ schema changes ที่ version control ได้
- Docker stack ในเครื่องเหมือน Production ทุกประการ
- Edge Functions ใช้ env variable จริงในการทดสอบ
Supabase CLI ทำงานอย่างไร
สแต็กในเครื่อง
เมื่อรัน supabase start จะได้ Docker Compose stack ดังนี้:
| บริการ | พอร์ต | วัตถุประสงค์ |
|---|---|---|
| PostgreSQL | 54322 | ฐานข้อมูล |
| PostgREST | 54321 | REST API อัตโนมัติ |
| GoTrue | 54321/auth | ยืนยันตัวตน |
| Realtime | 54321/realtime | WebSocket |
| Storage | 54321/storage | ที่เก็บไฟล์ |
| Studio | 54323 | Dashboard |
| Inbucket | 54324 | ทดสอบอีเมล |
| Edge Runtime | 54321/functions | รันฟังก์ชัน (Deno) |
นี่คือสแต็กเดียวกับที่ใช้บน Supabase Cloud
การติดตั้ง
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
ตรวจสอบเวอร์ชัน
supabase --version
# supabase 1.x.x
การตั้งค่าโปรเจกต์
mkdir my-project && cd my-project
supabase init
จะได้โฟลเดอร์:
supabase/
├── config.toml
├── seed.sql
└── migrations/
การเริ่มต้นสแต็กในเครื่อง
supabase start
ครั้งแรกจะดาวน์โหลด Docker image (~1GB) หลังจากนั้นใช้เวลาแค่ ~10 วินาที
API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio: http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
คัดลอก anon key ลงไฟล์ .env.local สำหรับ frontend
การจัดการฐานข้อมูลด้วย Migrations
Migrations คือหัวใจของ workflow — ทุก schema change จะกลายเป็นไฟล์ SQL ที่ version control ได้ใน Git
สร้าง Migration แรก
supabase migration new create_posts_table
# สร้าง: supabase/migrations/20260324120000_create_posts_table.sql
แก้ไขไฟล์ migration:
-- สร้างตาราง posts พร้อม RLS ตั้งแต่เริ่มต้น
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();
นำ migration ไปใช้:
supabase migration up
การสร้าง TypeScript types
หลังทุก schema change สร้าง type ใหม่:
supabase gen types typescript --local > src/types/database.ts
ตัวอย่างใช้งาน:
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
}
การใส่ข้อมูลสำหรับการพัฒนา
แก้ไข supabase/seed.sql:
INSERT INTO auth.users (id, email) VALUES
('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
('00000000-0000-0000-0000-000000000002', 'bob@example.com');
INSERT INTO posts (user_id, title, content, published) VALUES
('00000000-0000-0000-0000-000000000001', 'เริ่มต้นใช้งาน Supabase', 'นี่คือสิ่งที่ฉันได้เรียนรู้...', true),
('00000000-0000-0000-0000-000000000002', 'ฉบับร่าง: รูปแบบการออกแบบ API', 'อยู่ระหว่างการดำเนินการ...', false);
รีเซ็ตและใส่ seed ใหม่:
supabase db reset
การทดสอบ Supabase API ด้วย Apidog
เมื่อรัน Supabase ในเครื่อง จะมี REST API ที่ http://localhost:54321 ทุกตารางจะได้ endpoint อัตโนมัติผ่าน PostgREST
Apidog สามารถ:
- บันทึกคำขอเป็นคอลเล็กชัน
- ทดสอบ endpoint ในฐานะ user ต่างๆ (สลับ environment)
- เพิ่มการยืนยันผลลัพธ์และรันเป็นชุดทดสอบ
- แชร์เอกสาร API อัตโนมัติ
วิธีตั้งค่า Apidog กับ Supabase ในเครื่อง:
- สร้างโปรเจกต์ใหม่ใน Apidog
- Base URL:
http://localhost:54321 - เพิ่ม env variable:
anon_key = your-local-anon-key - Header:
Authorization: Bearer {{anon_key}}
ทดสอบ endpoint posts:
GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
เพิ่ม assertion และรันทดสอบทุกครั้งที่เปลี่ยน RLS คุณจะจับ policy ที่ผิดได้ก่อนขึ้น Production
ฟังก์ชัน Edge: สร้างและทดสอบบนเครื่อง
Edge Functions รันบน Deno เหมาะสำหรับ webhooks, background jobs, และ endpoint ที่ต้องการ logic ฝั่ง server
สร้างฟังก์ชัน
supabase functions new send-welcome-email
ตัวอย่างโค้ด:
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()
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(`กำลังส่งอีเมลต้อนรับไปยัง ${profile?.email}`)
return new Response(
JSON.stringify({ success: true }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
ทดสอบบนเครื่องด้วย Hot Reload
supabase functions serve
ทดสอบด้วย curl:
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"}'
นำขึ้นสู่ Production
# นำฟังก์ชันเดียวขึ้นไป
supabase functions deploy send-welcome-email
# นำฟังก์ชันทั้งหมดขึ้นไป
supabase functions deploy
เทคนิคขั้นสูงและแนวทางที่ได้รับการพิสูจน์แล้ว
การจัดการความลับ
อย่าฮาร์ดโค้ด API Key ในโค้ด ใช้ secrets:
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx
supabase secrets list
supabase secrets unset STRIPE_KEY
ในฟังก์ชัน:
const resendKey = Deno.env.get('RESEND_API_KEY')
การแยกสาขาฐานข้อมูล
สำหรับงาน schema ที่ใหญ่:
supabase branches create feature-payments
supabase branches switch feature-payments
# ทำการเปลี่ยนแปลง, ทดสอบ, จากนั้นผสาน
supabase branches merge feature-payments
ข้อผิดพลาดที่ควรหลีกเลี่ยง
- แก้ไขฐานข้อมูลใน Studio ตรงๆ: ควรใช้ migrations
-
commit
.env: ใช้supabase secrets setสำหรับ Production และเพิ่ม.env*ใน.gitignore -
ข้าม
supabase db resetหลังดึงโค้ด: reset ทุกครั้งหลัง pull - ไม่สร้าง types ใหม่หลัง schema change: สร้าง types ทุกครั้งหลัง migration
-
deploy function โดยไม่ทดสอบ: ทดสอบด้วย
supabase functions serveเสมอ - ใช้ service role key ใน frontend: ใช้เฉพาะฝั่ง server/Edge Functions เท่านั้น
เคล็ดลับประสิทธิภาพ
# ข้าม service ที่ไม่ใช้
supabase start --exclude-studio --exclude-inbucket
# ดู resource usage
docker stats
ทางเลือกและการเปรียบเทียบ
| คุณสมบัติ | Supabase CLI | Firebase CLI | PlanetScale CLI |
|---|---|---|---|
| ฐานข้อมูลในเครื่อง | PostgreSQL เต็มรูปแบบ | Emulator | คลาวด์เท่านั้น |
| Migrations | SQL ใน Git | ไม่มี native | การแยกสาขา |
| ฟังก์ชัน Edge | Deno runtime | Cloud Functions | ไม่รวม |
| การยืนยันตัวตนในเครื่อง | GoTrue เต็มรูปแบบ | Emulator | ไม่รวม |
| โอเพนซอร์ส | เปิด | กรรมสิทธิ์ | กรรมสิทธิ์ |
| การสร้างประเภทข้อมูล | มีในตัว | ด้วยตนเอง | ด้วยตนเอง |
Firebase Emulator เหมาะกับ rapid prototyping แต่ไม่มี PostgreSQL จริง PlanetScale branch ดีสำหรับ schema change แต่ทำงานบนคลาวด์เท่านั้น Supabase CLI เหมาะกับทีมที่ต้องการ local dev แบบโอเพนซอร์สและ PostgreSQL-native จริง
กรณีการใช้งานจริง
SaaS หลายผู้เช่า: ทีม fintech จัดการ 47 migrations ใน 3 env (dev, staging, prod) ทุก policy RLS ทดสอบบนเครื่องก่อน deploy ไม่พบ schema issue ใน Production นาน 6 เดือน
E-commerce: ทีมใช้ Edge Functions รับ Stripe webhook ทดสอบ payload จริงบนเครื่อง เวลาจาก dev → prod ลดจาก 2 ชม. เหลือ 15 นาที
Mobile backend: ทีม React Native สร้าง TypeScript types หลังทุก migration และแชร์เป็น npm package ฟรอนต์/แบ็กเอนด์ sync กันหมด
สรุป
สิ่งที่นำไปใช้ได้ทันที:
- ตั้งค่า Supabase ในเครื่องในไม่กี่นาที
- ใช้ migrations ควบคุม schema
- ทดสอบ Edge Functions ในเครื่องแบบ hot reload
- สร้าง TypeScript types อัตโนมัติจาก schema
- Deploy ขึ้น Production ด้วย
supabase db pushและsupabase functions deploy - ทดสอบ API ด้วย Apidog ก่อนขึ้น Production
workflow นี้เพิ่ม productivity, ลด bug, หายห่วงเรื่อง schema drift
ขั้นตอนถัดไปของคุณ:
- ติดตั้ง:
brew install supabase/tap/supabase - รัน
supabase initในโปรเจกต์ - สร้าง migration แรก
- ตั้งค่า Apidog เพื่อทดสอบ endpoint
- Deploy ขึ้น Production อย่างมั่นใจ
ทดสอบ Supabase API ของคุณด้วย Apidog - ฟรี
คำถามที่พบบ่อย
Q: จำเป็นต้องใช้ Docker สำหรับ Supabase CLI ไหม?
A: ต้องใช้ Docker Desktop ก่อนรัน supabase start CLI ใช้ Docker Compose ในการรัน stack ถ้า Docker ไม่ทำงานจะ error "Cannot connect to Docker daemon"
Q: จะ sync database local กับ Production อย่างไร?
A: ใช้ supabase db pull จาก remote schema แล้ว supabase db push สำหรับ deploy local migrations ไป Production เสร็จแล้วให้ supabase db reset บนเครื่อง
Q: ใช้ Supabase CLI โดยไม่มีบัญชี Supabase Cloud ได้ไหม?
A: ใช้ CLI พัฒนา local ได้เต็มที่โดยไม่ต้องมีบัญชี cloud ต้องใช้ supabase login และ supabase link แค่ตอน deploy
Q: จัดการ conflict migration ในทีมอย่างไร?
A: ดึง Git ล่าสุด + รัน supabase db reset ก่อนสร้าง migration ใหม่ ใช้ชื่อ migration ชัดเจน และสื่อสารกันเสมอ
Q: ต่างกันอย่างไรระหว่าง supabase db push กับ supabase migration up?
A: supabase migration up ใช้กับ local, supabase db push ใช้ deploy ไป remote (Production) ทดสอบทุก migration บน local ก่อนเสมอ
Q: ใช้ Supabase CLI กับโปรเจกต์ที่มีอยู่ได้ไหม?
A: ได้ รัน supabase link --project-ref YOUR_PROJECT_ID แล้ว supabase db pull เพื่อ sync migration
Q: ทดสอบ RLS policy ในเครื่องอย่างไร?
A: ใช้ Supabase Studio ที่ http://localhost:54323 หรือทดสอบ API ด้วย JWT ต่าง ๆ Apidog ช่วยทดสอบ multi-user ได้ง่าย
Q: Supabase CLI ฟรีไหม?
A: ฟรีและโอเพนซอร์ส การพัฒนา local ฟรี เสียเฉพาะ resource บน Supabase Cloud ตอน Production
Top comments (0)