Supabase
Supabase
Supabase 는 Firebase 의 대안을 표방하며 등장한 오픈소스 백엔드 묶음입니다. 핵심에 PostgreSQL 을 두고 인증·스토리지·실시간·서버리스 함수를 그 주위에 쌓았습니다.
1. Supabase 에 대한 이야기
Supabase 는 2020 년에 시작된 프로젝트입니다. 창립자 (Paul Copplestone · Ant Wilson) 는 "PostgreSQL 위에 Firebase 같은 개발자 경험을 얹는다" 는 방향을 명시해 왔습니다. 코드는 Apache 2.0 으로 공개돼 있고, 매니지드 클라우드 서비스와 셀프호스팅을 모두 지원합니다.
| 사건 | 시기 |
|---|---|
| 프로젝트 시작 | 2020 |
| GA | 2021 |
| Storage 추가 | 2021 |
| Edge Functions (Deno) | 2022 |
| pgvector 기본 지원 | 2023 |
| Branching · Realtime 개선 | 2023 ~ 2024 |
2. Database (PostgreSQL)
핵심 자체가 PostgreSQL 입니다. 사용자는 일반 PostgreSQL 클라이언트 (psql · JDBC · ORM) 로도 접속 가능합니다. extension 이 풍부히 켜져 있어 pgvector · pg_cron · postgis 같은 확장을 콘솔에서 활성화합니다.
스키마는 public 외에 auth · storage · realtime 같은 시스템 스키마가 같은 DB 안에 같이 삽니다. 이로 인해 RLS·정책이 이 시스템 테이블을 함께 봅니다.
3. Auth (GoTrue)
GoTrue 는 Netlify 가 시작한 오픈소스 인증 서버입니다. Supabase 가 포크해 자체 발전을 이어갑니다. 이메일·비밀번호·매직 링크·OTP·OAuth·phone 인증을 지원합니다. 발급되는 JWT 는 auth.users 의 사용자 ID(sub) 를 담고 RLS 정책이 이 정보를 활용합니다.
4. Storage · Edge Functions · Realtime
Storage — S3 호환 객체 저장소를 자체 구현합니다. 백엔드는 S3 API 를 통한 다른 객체 저장소와도 결합 가능합니다. 메타데이터는 PostgreSQL 의 storage.objects 테이블에 저장돼 RLS 로 권한을 다룹니다.
Edge Functions — Deno 런타임 위에서 실행되는 서버리스 함수입니다. TypeScript 코드를 배포하면 글로벌 엣지에서 응답합니다. 데이터베이스 연결은 같은 프로젝트의 PostgreSQL 로 이어집니다.
Realtime — PostgreSQL 의 논리적 복제 (logical replication) 를 구독해 변경 이벤트를 WebSocket 으로 흘려보냅니다. 클라이언트가 특정 테이블·필터의 변경을 실시간으로 받습니다. 별도로 broadcast · presence 채널도 제공합니다.
5. supabase-js 클라이언트
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(URL, ANON_KEY);
// 읽기
const { data, error } = await supabase
.from('posts')
.select('id, title, author:users(name)')
.eq('published', true)
.order('created_at', { ascending: false })
.limit(10);
// 쓰기
await supabase.from('posts').insert({ title: 'hi' });
// 인증
await supabase.auth.signInWithPassword({ email, password });
// 실시간
supabase.channel('posts')
.on('postgres_changes', { event: '*', schema: 'public', table: 'posts' }, (p) => console.log(p))
.subscribe();
특징.
- 쿼리는 PostgREST 가 변환합니다 (RESTful 관계형 SQL 매핑).
anon키와service_role키가 있습니다. 후자는 서버에서만 사용해야 합니다.- 응답이
{ data, error }모양이라 throw 가 아닌 분기 처리.
6. RLS — Row Level Security
PostgreSQL 은 9.5 (2016) 부터 행 단위 보안을 제공합니다. Supabase 는 이 위에 자체 모델을 쌓았습니다.
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "own posts read" ON posts
FOR SELECT
USING (author_id = auth.uid());
CREATE POLICY "insert own" ON posts
FOR INSERT
WITH CHECK (author_id = auth.uid());
auth.uid()함수가 현재 JWT 의 사용자 ID 를 돌려줍니다.- 정책이
USING(읽기·UPDATE 의 매칭) 과WITH CHECK(INSERT·UPDATE 후 모양) 으로 갈립니다. service_role키는 RLS 를 우회합니다 — 백엔드 자리에서만.
장점은 권한 규칙이 DB 안에 표현된다는 점입니다. 어떤 클라이언트가 와도 같은 규칙이 적용됩니다. 한계는 정책이 늘면 디버깅이 어려워지고 복잡한 조인은 정책 평가 비용을 늘릴 수 있다는 점입니다.
7. 셀프호스팅
Supabase 의 모든 구성 요소는 docker compose 로 배포 가능한 컨테이너로 공개돼 있습니다. 한 호스트에 다음 컨테이너가 함께 뜹니다.
db (Postgres) · gotrue · storage-api · realtime
kong (게이트웨이) · studio (UI) · meta · imgproxy
자가 운영의 장단:
- 장점: 데이터 주권·비용 통제·private 네트워크 통합.
- 한계: 백업·확장·업그레이드의 책임이 운영자에게 옵니다.
매니지드 vs 셀프호스팅 결정의 기준은 데이터 양·민감도·운영 인력입니다.
8. Firebase · Appwrite · PocketBase 비교
| 항목 | Supabase | Firebase | Appwrite | PocketBase |
|---|---|---|---|---|
| 코어 DB | PostgreSQL | Firestore (NoSQL) · RTDB | MariaDB | SQLite (단일 바이너리) |
| 라이선스 | Apache 2.0 | proprietary | BSD-3 | MIT |
| 셀프호스팅 | 가능 | 불가 | 가능 | 가능 (단일 실행 파일) |
| Auth | GoTrue | Firebase Auth | 자체 | 자체 |
| 실시간 | logical replication | 자체 (Firestore 리스너) | 자체 | 자체 |
| Functions | Deno | Cloud Functions (Node) | Functions (다언어) | (Go 미들웨어로) |
| SDK | js · py · dart · swift | 다언어 · 다플랫폼 | js · flutter · py 등 | js · dart |
Firebase 의 강점은 모바일 SDK 의 성숙·Google Cloud 통합. Supabase 의 강점은 SQL · 관계형 모델 · 데이터 이식성. PocketBase 는 매우 작은 운영 표면 (단일 바이너리·SQLite) 으로 작은 프로젝트에 자주 거론됩니다. Appwrite 는 Firebase 와 유사한 API 모델을 오픈소스로 제공합니다.
9. 키 분리와 마이그레이션
anon 키는 공개 클라이언트용입니다. RLS 가 권한 규칙을 정합니다. service_role 키는 서버 전용이고 RLS 를 우회합니다.
빌드된 클라이언트 번들에 service_role 이 들어가지 않도록 환경 변수 분리·CI 검사가 권장됩니다.
supabase CLI 가 SQL 마이그레이션 파일과 로컬 개발 환경 (docker compose 기반) 을 다룹니다. supabase db push · supabase db diff 같은 명령으로 스키마 변경을 적용·확인합니다.
10. 자주 걸리는 자리
RLS 비활성 테이블 — 새로 만든 테이블에 RLS 를 안 켜면 anon 키로 모든 행이 읽힙니다. 기본값이 disabled 라는 점이 자주 지적됩니다.
service_role 키 노출 — 클라이언트 번들에 들어가면 모든 데이터 접근이 가능해집니다.
정책의 함수 호출 비용 — auth.uid() 외에 무거운 함수를 정책 안에서 호출하면 행마다 평가됩니다.
무료 티어 일시 정지 — 매니지드 무료 프로젝트는 일정 기간 비활동이면 일시 중지될 수 있습니다 (계획·요금이 시기에 따라 변동).
Storage 의 RLS 와 메타데이터 — 객체 권한이 메타데이터 테이블의 정책을 따릅니다. 정책 누락 시 의도와 다른 접근이 발생합니다.
마이그레이션 도구 혼용 — Prisma · TypeORM 등으로 만든 스키마 변경과 supabase CLI 를 같은 DB 에 섞으면 추적이 흐트러집니다. 한 가지를 SSOT 로 정합니다.
하고픈 말
Supabase 는 작은 팀이 많은 일을 빠르게 하기 좋은 도구입니다. 운영 규모가 커지면 셀프호스팅의 운영 부담이 보이기 시작하고, 매니지드의 비용이 보이기 시작합니다. 그 시점에서 PostgreSQL 한 가지로 갈지 Supabase 풀스택을 유지할지 결정하는 자리가 옵니다.
Next
- fcm-push
- image-pipeline
Supabase 공식 문서 · Supabase 아키텍처 · Postgres RLS 문서 · PostgREST 문서 · Supabase 셀프호스팅 · PocketBase 공식 를 참고합니다.