Ringkasan
Supabase CLI menjalankan tumpukan Supabase lengkap di mesin 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 mengirim ke produksi. Ini adalah cara tercepat untuk membangun dan menguji backend Supabase tanpa menyentuh cloud.
Pendahuluan
73% dari bug backend ditemukan di produksi karena pengembang melewatkan pengujian lokal. Dengan Supabase CLI, itu bukan lagi alasan. Anda mendapatkan lingkungan yang setara dengan produksi penuh yang berjalan di mesin Anda dalam waktu kurang dari 5 menit.
Inilah masalah sebenarnya: sebagian besar pengembang menguji langsung di produksi (berisiko) atau menghabiskan waktu berjam-jam mengonfigurasi lingkungan lokal yang tidak pernah sepenuhnya cocok dengan cloud (frustrasi). Supabase CLI memecahkan keduanya. Ini memberi Anda tumpukan lokal berbasis Docker yang mencerminkan produksi persis, sehingga apa yang berfungsi secara lokal akan berfungsi di produksi.
Uji API Supabase Anda dengan Apidog - gratis
Pada akhir panduan ini, Anda akan dapat:
- Menyiapkan lingkungan Supabase lokal lengkap dalam hitungan menit
- Mengelola perubahan skema database dengan migrasi yang terkontrol versi
- Membangun dan menguji Edge Functions secara lokal sebelum menerapkan
- Menerapkan ke produksi dengan satu perintah
Mengapa pengembangan Supabase lokal terhambat tanpa CLI
Jika Anda pernah mencoba membangun aplikasi Supabase tanpa CLI, Anda tahu betapa sulitnya. Berikut adalah tiga skenario yang sering terjadi.
Jebakan "uji di produksi". Anda melakukan perubahan skema langsung di dashboard Supabase. Berhasil. Anda mendorong frontend Anda. Tiga hari kemudian, rekan tim menarik repo dan aplikasi mereka rusak karena database mereka tidak memiliki kolom baru.
Ketidakcocokan lingkungan. Anda menyiapkan instans PostgreSQL lokal, secara manual membuat ulang skema Supabase Anda, dan menghabiskan dua jam untuk men-debug mengapa kebijakan Keamanan Tingkat Baris (Row Level Security) berperilaku berbeda secara lokal. Mereka tidak berperilaku berbeda. Anda melewatkan satu kebijakan.
Masalah "berfungsi di mesin saya". Edge Function Anda berfungsi di editor dashboard Supabase tetapi gagal di produksi karena Anda menguji dengan nilai-nilai yang dikodekan secara langsung (hardcoded) alih-alih variabel lingkungan yang sebenarnya.
Ini bukan kasus-kasus langka. Pergeseran skema (database lokal dan jarak jauh tidak sinkron) adalah masalah #1 yang dilaporkan untuk tim yang menggunakan Supabase. CLI memperbaiki ketiga masalah ini:
- Migrasi menjaga perubahan skema tetap terkontrol versi dan dapat direproduksi
- Tumpukan Docker lokal mencerminkan produksi dengan tepat, versi PostgreSQL yang sama, mesin RLS yang sama
- Penyajian fungsi lokal menguji Edge Functions dengan variabel lingkungan yang sebenarnya
Bagaimana Supabase CLI bekerja
Tumpukan lokal
Saat Anda menjalankan supabase start, CLI akan menjalankan tumpukan Docker Compose dengan layanan-layanan berikut:
| Layanan | Port | Tujuan |
|---|---|---|
| PostgreSQL | 54322 | Database Anda |
| PostgREST | 54321 | API REST yang dibuat secara otomatis |
| GoTrue | 54321/auth | Layanan autentikasi |
| Realtime | 54321/realtime | Langganan WebSocket |
| Storage | 54321/storage | Penyimpanan file |
| Studio | 54323 | Dasbor visual |
| Inbucket | 54324 | Pengujian email (menangkap semua email secara lokal) |
| Edge Runtime | 54321/functions | Penjalankan fungsi berbasis Deno |
Ini adalah tumpukan yang sama yang berjalan di Supabase Cloud. Di mesin 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 berhasil:
supabase --version
# supabase 1.x.x
supabase startPenyiapan Proyek
mkdir my-project && cd my-project
supabase init
Ini akan membuat:
supabase/
├── config.toml # Port, pengaturan otentikasi, konfigurasi penyimpanan
├── seed.sql # Data pengembangan yang dimuat pada setiap reset db
└── migrations/ # Riwayat versi skema
Memulai tumpukan lokal
supabase start
Jalankan pertama kali akan mengunduh sekitar 1GB image Docker. Setelah itu, proses start membutuhkan waktu sekitar 10 detik.
API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio: http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Salin anon key ke dalam file .env.local Anda. Anda akan membutuhkannya untuk frontend Anda.
Manajemen database dengan migrasi
Migrasi adalah inti dari alur kerja CLI. Setiap perubahan skema menjadi file SQL yang diberi versi dan dilacak di Git. Tidak ada lagi pertanyaan "siapa yang mengubah database dan kapan."
Membuat migrasi pertama Anda
supabase migration new create_posts_table
# Creates: supabase/migrations/20260324120000_create_posts_table.sql
Edit file tersebut:
-- Buat tabel posts dengan RLS sejak 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()
);
-- Aktifkan Row Level Security
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Siapa pun dapat membaca postingan yang diterbitkan
CREATE POLICY "Anyone can read published posts"
ON posts FOR SELECT
USING (published = true);
-- Pengguna mengelola postingan mereka sendiri
CREATE POLICY "Users manage own posts"
ON posts FOR ALL
USING (auth.uid() = user_id);
-- Perbarui updated_at secara otomatis pada setiap perubahan
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:
supabase migration up
Membuat tipe TypeScript
Setelah setiap perubahan skema, buat ulang tipe Anda:
supabase gen types typescript --local > src/types/database.ts
Frontend Anda mendapatkan keamanan tipe penuh:
import { Database } from '@/types/database'
type Post = Database['public']['Tables']['posts']['Row']
type NewPost = Database['public']['Tables']['posts']['Insert']
// Sekarang editor Anda menangkap kesalahan tipe sebelum runtime
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 (melewati otentikasi untuk pengembangan 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 siapkan ulang kapan saja:
supabase db reset
Ini akan menghapus semuanya, menjalankan ulang semua migrasi, dan memuat data awal Anda. Jalankan setiap pagi untuk memulai dari awal.
Menguji API Supabase dengan Apidog
Setelah Supabase lokal Anda berjalan, Anda memiliki REST API yang berfungsi penuh di http://localhost:54321. Supabase secara otomatis membuat endpoint untuk setiap tabel melalui PostgREST. Menguji ini secara manual dengan curl akan cepat membosankan, terutama ketika Anda perlu menguji kebijakan RLS dengan token pengguna yang berbeda.
Apidog terhubung langsung ke instans Supabase lokal Anda. Anda dapat:
- Menyimpan permintaan sebagai koleksi yang dapat digunakan kembali
- Menguji endpoint yang sama sebagai pengguna yang berbeda dengan beralih lingkungan
- Menambahkan afirmasi ("respons berisi setidaknya 1 postingan") dan menjalankannya sebagai rangkaian pengujian
- Berbagi dokumentasi API dengan tim Anda secara otomatis
Menyiapkan Apidog dengan Supabase lokal:
- Buat proyek baru di Apidog
- Atur URL dasar:
http://localhost:54321 - Tambahkan variabel lingkungan:
anon_key = your-local-anon-key - Tambahkan header Otentikasi:
Bearer {{anon_key}}
Menguji endpoint posts:
GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}
Simpan ini sebagai permintaan, tambahkan afirmasi bahwa respons berisi setidaknya satu postingan, dan jalankan setiap kali Anda mengubah kebijakan RLS Anda. Anda akan menangkap kebijakan yang rusak sebelum mencapai produksi.
Mulai uji API Supabase Anda dengan Apidog - gratis
Edge functions: bangun dan uji secara lokal
Edge Functions berjalan di Deno di sisi edge, dekat dengan pengguna Anda. Mereka sempurna untuk webhook, background job, dan endpoint API yang membutuhkan logika sisi server.
Buat fungsi
supabase functions new send-welcome-email
Ini membuat 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 layanan melewati RLS - gunakan dengan 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 Anda di sini
console.log(`Mengirim email selamat datang ke ${profile?.email}`)
return new Response(
JSON.stringify({ success: true }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
Uji secara lokal dengan hot reload
supabase functions serve
Server fungsi memantau perubahan file dan memuat ulang secara otomatis. Uji:
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"}'
Terapkan ke produksi
# Terapkan satu fungsi
supabase functions deploy send-welcome-email
# Terapkan semua fungsi
supabase functions deploy
Teknik lanjutan dan pendekatan yang terbukti
Manajemen rahasia
Jangan pernah mengkodekan kunci API secara langsung (hardcode) dalam fungsi Anda. Gunakan rahasia:
# Atur rahasia produksi
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx
# Daftar semua rahasia
supabase secrets list
# Hapus rahasia
supabase secrets unset STRIPE_KEY
Akses mereka dalam fungsi:
const resendKey = Deno.env.get('RESEND_API_KEY')
// Jangan pernah: const resendKey = 're_xxx'
Pencabangan database (Database branching)
Sedang mengerjakan perubahan skema besar? Buat cabang terisolasi:
supabase branches create feature-payments
supabase branches switch feature-payments
# Lakukan perubahan, uji, lalu gabungkan
supabase branches merge feature-payments
Ini menjaga database pengembangan utama Anda tetap bersih saat Anda bereksperimen.
Kesalahan umum yang harus dihindari
Mengedit database langsung di Studio. Selalu gunakan migrasi. Editan langsung tidak dilacak dan rekan tim Anda tidak akan memilikinya.
Melakukan commit file .env. Gunakan supabase secrets set untuk produksi. Tambahkan .env* ke .gitignore Anda.
Melewatkan supabase db reset setelah menarik perubahan (pull). Ketika Anda menarik perubahan rekan tim, migrasi baru mereka perlu dijalankan secara lokal. Reset untuk menerapkannya.
Tidak membuat ulang tipe setelah perubahan skema. Tipe TypeScript Anda akan menjadi usang saat Anda menambahkan kolom. Jadikan pembuatan tipe sebagai bagian dari alur kerja migrasi Anda.
Menerapkan fungsi tanpa pengujian lokal. Selalu jalankan supabase functions serve dan uji dengan permintaan nyata sebelum menerapkan.
Menggunakan kunci peran layanan (service role key) dalam kode frontend. Kunci peran layanan melewati RLS. Kunci ini hanya boleh berada di Edge Functions dan kode sisi server, tidak pernah di browser Anda.
Tips kinerja
# Lewati layanan yang tidak Anda butuhkan untuk menghemat memori
supabase start --exclude-studio --exclude-inbucket
# Periksa apa yang menggunakan sumber daya
docker stats
Alternatif dan 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 |
Emulator lokal Firebase bagus untuk prototipe cepat tetapi tidak memberi Anda instans PostgreSQL yang nyata. Model pencabangan PlanetScale sangat baik untuk perubahan skema tetapi Anda selalu bekerja melawan cloud. Supabase CLI menang bagi tim yang menginginkan pengalaman pengembangan lokal yang sepenuhnya sumber terbuka dan PostgreSQL-native.
Kasus penggunaan dunia nyata
Aplikasi SaaS dengan data multi-tenant. Startup fintech mengelola 47 migrasi di tiga lingkungan (dev, staging, prod). Kebijakan RLS diuji secara lokal dengan peran pengguna yang berbeda sebelum kode apa pun mencapai produksi. Hasil: nol insiden produksi terkait skema dalam enam bulan.
Pemrosesan pesanan E-commerce. Tim e-commerce menggunakan Edge Functions untuk pemrosesan webhook Stripe. Mereka menguji payload webhook secara lokal menggunakan supabase functions serve dengan peristiwa uji Stripe yang nyata. Waktu penerapan turun dari 2 jam menjadi 15 menit.
Backend aplikasi seluler. Tim React Native menghasilkan tipe TypeScript setelah setiap migrasi dan membagikannya sebagai paket npm internal. Frontend dan backend tetap sinkron secara otomatis. Tidak ada lagi pertanyaan "bidang apa yang dikembalikan endpoint ini?" di Slack.
Kesimpulan
Berikut adalah apa yang dapat Anda lakukan sekarang:
- Menyiapkan lingkungan Supabase lokal lengkap dalam hitungan menit
- Menggunakan migrasi untuk mengontrol versi setiap perubahan skema
- Menguji Edge Functions secara lokal dengan hot reload
- Membuat tipe TypeScript secara otomatis dari skema Anda
- Menerapkan dengan
supabase db pushdansupabase functions deploy - Menguji API Anda dengan Apidog sebelum dikirim ke produksi
Alur kerja ini segera membuahkan hasil. Tim Anda merilis lebih cepat, menangkap bug lebih awal, dan tidak pernah lagi berurusan dengan pergeseran skema.
Langkah selanjutnya:
- Instal:
brew install supabase/tap/supabase - Jalankan
supabase initdi proyek Anda - Buat migrasi pertama Anda
- Siapkan Apidog untuk menguji endpoint lokal Anda
- Terapkan 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 secara lokal. Jika Docker tidak berjalan, Anda akan mendapatkan pesan error "Cannot connect to Docker daemon".
Bagaimana cara menyinkronkan database lokal saya dengan produksi?Gunakan supabase db pull untuk membuat migrasi dari skema jarak jauh Anda, lalu supabase db push untuk menerapkan migrasi lokal ke produksi. Jalankan supabase db reset secara lokal setelah menarik perubahan untuk memastikan lingkungan Anda cocok.
Bisakah saya menggunakan Supabase CLI tanpa akun Supabase Cloud?Ya. Anda dapat menggunakan CLI sepenuhnya secara lokal untuk pengembangan tanpa akun cloud. Anda hanya memerlukan supabase login dan supabase link saat Anda siap untuk menerapkan ke produksi.
Bagaimana cara menangani konflik migrasi dalam sebuah tim?Tarik perubahan Git terbaru dan jalankan supabase db reset sebelum membuat migrasi baru. Gunakan nama migrasi yang deskriptif dan berkomunikasi dengan tim Anda saat membuat perubahan skema yang merusak.
Apa perbedaan antara supabase db push dan supabase migration up?supabase migration up menerapkan migrasi yang tertunda ke database lokal Anda. supabase db push menerapkannya ke proyek jarak jauh (produksi) Anda. Selalu uji secara lokal terlebih dahulu.
Bisakah saya menggunakan Supabase CLI dengan proyek yang sudah ada?Ya. Jalankan supabase link --project-ref YOUR_PROJECT_ID untuk menautkan ke proyek yang sudah ada, lalu supabase db pull untuk membuat migrasi dari skema jarak jauh Anda saat ini.
Bagaimana cara menguji kebijakan RLS secara lokal?Gunakan Supabase Studio di http://localhost:54323 untuk beralih antara peran pengguna, atau uji melalui API dengan token JWT yang berbeda. Apidog memudahkan ini: buat beberapa lingkungan dengan token pengguna yang berbeda dan jalankan permintaan yang sama sebagai pengguna yang berbeda.
Apakah Supabase CLI gratis?Ya. CLI ini gratis dan open source. Pengembangan lokal tidak dikenakan biaya. Anda hanya membayar untuk sumber daya Supabase Cloud saat Anda menerapkan ke produksi.
