Ringkasan
Supabase CLI menjalankan tumpukan Supabase lengkap di mesin lokal Anda menggunakan Docker: PostgreSQL, Auth, Storage, dan Edge Functions. Instal dengan brew install supabase/tap/supabase, jalankan supabase init dan supabase start untuk memulai lingkungan lokal, lalu gunakan supabase db push dan supabase functions deploy untuk mengirimkan ke produksi. Ini adalah cara tercepat untuk membangun dan menguji backend Supabase tanpa harus langsung ke cloud.
Pendahuluan
73% bug backend ditemukan di produksi karena pengujian lokal sering dilewati. Dengan Supabase CLI, alasan itu bisa dihilangkan. Anda mendapatkan lingkungan lokal yang identik dengan produksi dalam waktu kurang dari 5 menit.
Masalah utamanya: kebanyakan developer menguji langsung di produksi (berisiko tinggi) atau menghabiskan waktu lama menyiapkan lingkungan lokal yang tidak pernah benar-benar identik dengan cloud (sumber frustrasi). Supabase CLI mengatasi keduanya—memberikan tumpukan Docker lokal yang benar-benar mencerminkan produksi. Apa yang berjalan lokal, akan berjalan di produksi.
đź’ˇ Jika Anda membangun API di atas Supabase, Anda butuh alat untuk mendesain, menguji, dan mendokumentasikan endpoint saat proses development. Apidog terhubung langsung ke REST dan GraphQL API Supabase, memungkinkan Anda menguji backend secara lokal dari awal.
Uji API Supabase Anda dengan Apidog - gratis.
Setelah membaca panduan ini, Anda akan bisa:
- Menyiapkan lingkungan Supabase lokal lengkap dalam hitungan menit
- Mengelola perubahan skema database dengan migrasi versi
- Membangun & menguji Edge Functions secara lokal sebelum deploy
- Deploy ke produksi dengan satu perintah
Mengapa Pengembangan Supabase Lokal Terhambat Tanpa CLI
Jika Anda pernah membangun aplikasi Supabase tanpa CLI, Anda pasti pernah mengalami salah satu dari tiga masalah ini:
Jebakan "uji di produksi": Perubahan skema langsung di dashboard Supabase, lalu frontend didorong. Rekan tim menarik repo—aplikasi mereka rusak karena database tak sinkron.
Ketidakcocokan lingkungan: Setup PostgreSQL lokal manual, replikasi skema cloud, debugging RLS yang tak pernah cocok. Seringnya hanya karena satu kebijakan terlewat.
Masalah "berfungsi di mesin saya": Edge Function berhasil di dashboard tapi gagal di produksi karena pengujian dilakukan pakai value hardcoded, bukan environment variable.
Ini masalah nyata. Pergeseran skema adalah problem #1 di tim yang pakai Supabase. CLI menyelesaikan semua:
- Migrasi menjaga perubahan skema tetap terkontrol dan reproducible
- Tumpukan Docker lokal = produksi (versi PostgreSQL & mesin RLS identik)
- Fungsi edge diuji dengan env var nyata, bukan hardcoded
Bagaimana Supabase CLI Bekerja
Tumpukan Lokal
supabase start menjalankan Docker Compose dengan layanan berikut:
| Layanan | Port | Tujuan |
|---|---|---|
| PostgreSQL | 54322 | Database Anda |
| PostgREST | 54321 | API REST otomatis |
| GoTrue | 54321/auth | Layanan autentikasi |
| Realtime | 54321/realtime | Langganan WebSocket |
| Storage | 54321/storage | Penyimpanan file |
| Studio | 54323 | Dasbor visual |
| Inbucket | 54324 | Testing email lokal |
| Edge Runtime | 54321/functions | Menjalankan fungsi Deno |
Struktur ini identik dengan Supabase Cloud, tetapi berjalan di mesin lokal Anda.
Instalasi
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
Verifikasi:
supabase --version
# supabase 1.x.x
supabase start
Penyiapan Proyek
mkdir my-project && cd my-project
supabase init
Struktur yang dihasilkan:
supabase/
├── config.toml # Port, auth, storage config
├── seed.sql # Data dev (di-load setiap reset db)
└── migrations/ # Riwayat versi skema
Memulai Tumpukan Lokal
supabase start
Download pertama kali ±1GB image Docker, berikutnya hanya ±10 detik start.
API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio: http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Copy anon key ke file .env.local frontend Anda.
Manajemen Database dengan Migrasi
Migrasi membuat semua perubahan skema menjadi file SQL berurut & terlacak di Git.
Buat Migrasi Pertama
supabase migration new create_posts_table
# Creates: supabase/migrations/20260324120000_create_posts_table.sql
Edit file migrasi:
-- Buat tabel posts + RLS dari awal
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();
Terapkan migrasi:
supabase migration up
Generate Tipe TypeScript
Setiap perubahan skema, generate ulang tipe:
supabase gen types typescript --local > src/types/database.ts
Contoh penggunaan di frontend:
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
}
Menyiapkan Data Pengembangan
Edit supabase/seed.sql:
-- Pengguna uji (lewati auth lokal)
INSERT INTO auth.users (id, email) VALUES
('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
('00000000-0000-0000-0000-000000000002', 'bob@example.com');
-- Postingan uji
INSERT INTO posts (user_id, title, content, published) VALUES
('00000000-0000-0000-0000-000000000001', 'Memulai dengan Supabase', 'Inilah yang saya pelajari...', true),
('00000000-0000-0000-0000-000000000002', 'Draf: Pola desain API', 'Dalam pengerjaan...', false);
Reset dan seed ulang:
supabase db reset
Seluruh database dihapus, semua migrasi dijalankan ulang, seed dimuat—sangat cocok untuk start fresh tiap hari.
Menguji API Supabase dengan Apidog
Setelah Supabase lokal aktif, Anda punya endpoint REST penuh di http://localhost:54321. Endpoint dibuat otomatis untuk tiap tabel via PostgREST. Menguji manual (curl/postman) cepat melelahkan, terutama untuk RLS.
Apidog terhubung langsung ke Supabase lokal. Keuntungannya:
- Simpan request sebagai koleksi reusable
- Uji endpoint sebagai user berbeda lewat switching environment
- Tambahkan assertion (“response harus berisi minimal 1 postingan”) dan jalankan sebagai test suite
- Share dokumentasi API otomatis ke tim
Langkah setup Apidog untuk Supabase lokal:
- Buat project baru di Apidog
- Atur base URL:
http://localhost:54321 - Tambahkan variabel environment:
anon_key = your-local-anon-key - Tambahkan header Auth:
Bearer {{anon_key}}
Contoh uji endpoint posts:
GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
Simpan request, tambahkan assertion minimal 1 postingan, dan jalankan setiap kali ubah RLS policy. Anda akan tahu ada policy error sebelum sampai ke production.
Mulai uji API Supabase Anda dengan Apidog - gratis.
Edge Functions: Bangun dan Uji Secara Lokal
Edge Functions (runtime Deno) ideal untuk webhook, background job, atau endpoint API dengan logika sisi server.
Buat Fungsi
supabase functions new send-welcome-email
File baru: 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()
// Peran service melewati RLS - hati-hati
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()
// Logika pengiriman email
console.log(`Mengirim email selamat datang ke ${profile?.email}`)
return new Response(
JSON.stringify({ success: true }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
Uji Lokal dengan Hot Reload
supabase functions serve
Server fungsi akan auto reload tiap file berubah. Uji dengan:
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"}'
Deploy ke Produksi
# Deploy satu fungsi
supabase functions deploy send-welcome-email
# Deploy semua fungsi
supabase functions deploy
Teknik Lanjutan & Praktik Terbaik
Manajemen Rahasia
Jangan pernah hardcode API key di fungsi Anda. Gunakan secrets Supabase:
# Set secret produksi
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx
# List semua secrets
supabase secrets list
# Unset secret
supabase secrets unset STRIPE_KEY
Akses di kode:
const resendKey = Deno.env.get('RESEND_API_KEY')
// Jangan: const resendKey = 're_xxx'
Database Branching
Untuk perubahan skema besar, buat cabang database:
supabase branches create feature-payments
supabase branches switch feature-payments
# Edit, uji, merge kembali
supabase branches merge feature-payments
Ini menjaga database utama tetap bersih saat eksperimen.
Kesalahan Umum yang Harus Dihindari
- Edit langsung di Studio: Selalu gunakan migrasi, supaya semua perubahan tercatat.
-
Commit file
.env: Untuk produksi, gunakansupabase secrets set. Tambahkan.env*ke.gitignore. -
Lupa reset DB setelah pull: Selalu jalankan
supabase db resetsetelah tarik perubahan skema. - Tidak generate ulang tipe setelah migrasi: Pastikan selalu update tipe TypeScript.
-
Deploy fungsi tanpa uji lokal: Jalankan
supabase functions servedan uji request nyata sebelum deploy. - Expose service role key di frontend: Kunci ini hanya untuk backend/Edge Functions, tidak pernah di browser.
Tips Performa
# Skip service tidak perlu, hemat memori
supabase start --exclude-studio --exclude-inbucket
# Cek resource Docker
docker stats
Alternatif & Perbandingan
| Fitur | Supabase CLI | Firebase CLI | PlanetScale CLI |
|---|---|---|---|
| Database lokal | PostgreSQL Penuh | Hanya emulator | Hanya cloud |
| Migrasi | File SQL di Git | Tidak ada dukungan asli | Pencabangan |
| Edge Functions | Deno runtime | Cloud Functions | Tidak termasuk |
| Autentikasi lokal | GoTrue Penuh | Emulator | Tidak termasuk |
| Sumber terbuka | Sepenuhnya terbuka | Propieter | Propieter |
| Pembuatan tipe | Bawaan | Manual | Manual |
Firebase bagus untuk prototipe cepat, tapi tidak menyediakan PostgreSQL nyata. PlanetScale unggul di branching, tapi selalu cloud-based. Supabase CLI unggul untuk tim yang butuh development environment lokal, open source, dan PostgreSQL-native.
Studi Kasus Dunia Nyata
Aplikasi SaaS multi-tenant: Startup fintech mengelola 47 migrasi di 3 environment (dev, staging, prod). Semua RLS policy diuji lokal dengan berbagai role sebelum deploy. Hasil: nol insiden produksi terkait skema selama 6 bulan.
Proses order e-commerce: Tim e-commerce proses webhook Stripe lewat Edge Functions, diuji lokal pakai supabase functions serve & event Stripe asli. Waktu deploy dari 2 jam turun ke 15 menit.
Backend aplikasi mobile: Tim React Native generate tipe TypeScript tiap migrasi, publish sebagai npm internal. Frontend-backend selalu sinkron, tak ada lagi pertanyaan “bidang apa yang dikembalikan endpoint ini?”
Kesimpulan
Langkah-langkah yang bisa Anda lakukan sekarang:
- Setup environment Supabase lokal dalam hitungan menit
- Kontrol versi perubahan skema dengan migrasi
- Uji Edge Functions lokal dengan hot reload
- Generate tipe TypeScript otomatis dari skema
- Deploy dengan
supabase db push&supabase functions deploy - Uji API Anda dengan Apidog sebelum produksi
Alur kerja ini langsung memberi hasil: rilis lebih cepat, bug tertangkap lebih awal, pergeseran skema hilang.
Langkah selanjutnya:
- Install:
brew install supabase/tap/supabase - Jalankan
supabase initdi proyek Anda - Buat migrasi pertama
- Siapkan Apidog untuk uji endpoint lokal
- Deploy ke produksi dengan percaya diri
Uji API Supabase Anda dengan Apidog - gratis.
FAQ
Apakah saya perlu Docker untuk menggunakan Supabase CLI?
Ya, Docker Desktop harus berjalan sebelum supabase start. CLI menggunakan Docker Compose untuk menjalankan tumpukan penuh lokal. Tanpa Docker, akan muncul error "Cannot connect to Docker daemon".
Bagaimana cara menyinkronkan database lokal dengan produksi?
Gunakan supabase db pull untuk generate migrasi dari skema remote, lalu supabase db push untuk menerapkan ke produksi. Jalankan supabase db reset setelah menarik perubahan agar lingkungan lokal tetap sinkron.
Bisakah Supabase CLI dipakai tanpa akun Supabase Cloud?
Bisa, CLI sepenuhnya dapat digunakan lokal untuk development. Anda hanya butuh supabase login dan supabase link saat siap deploy ke produksi.
Bagaimana menangani konflik migrasi dalam tim?
Tarik perubahan Git terbaru, lalu supabase db reset sebelum membuat migrasi baru. Gunakan nama migrasi yang deskriptif dan koordinasikan perubahan skema besar dengan tim.
Perbedaan antara supabase db push dan supabase migration up?
supabase migration up menerapkan migrasi ke database lokal. supabase db push menerapkan ke proyek remote (produksi). Selalu uji lokal dulu.
Bisakah Supabase CLI digunakan dengan proyek existing?
Bisa. Jalankan supabase link --project-ref YOUR_PROJECT_ID untuk menautkan, lalu supabase db pull untuk generate migrasi dari skema remote.
Bagaimana cara menguji kebijakan RLS secara lokal?
Gunakan Supabase Studio (http://localhost:54323) untuk switch peran user, atau uji via API dengan token JWT berbeda. Apidog memudahkan: buat beberapa environment dengan token berbeda, jalankan request sebagai user berbeda.
Apakah Supabase CLI gratis?
Ya, CLI gratis & open source. Pengembangan lokal tidak dikenakan biaya, Anda hanya bayar resource Supabase Cloud saat deploy.
Top comments (0)