Tự xây backend thay thế Supabase với PostgreSQL, Auth và Storage mã nguồn mở
Supabase hấp dẫn vì giải quyết nhanh 3 bài toán cốt lõi: database, authentication, storage. Tạo project, có PostgreSQL, API realtime, auth email/password, OAuth, bucket upload file — mọi thứ gần như dùng ngay. Nhưng khi sản phẩm lớn dần, câu hỏi xuất hiện: có nên tự xây backend tương tự Supabase bằng mã nguồn mở không?
Câu trả lời: có, nếu bạn cần kiểm soát sâu hơn về chi phí, bảo mật, dữ liệu, hạ tầng, tuỳ biến nghiệp vụ. Không, nếu team nhỏ cần ship nhanh, ít DevOps, chưa có nhu cầu đặc biệt.
Bài viết này đi vào kiến trúc thực tế: dùng PostgreSQL, Auth mã nguồn mở, Object Storage tương thích S3, API layer, migration, phân quyền, triển khai. Mục tiêu: xây backend “kiểu Supabase”, nhưng tự chủ hơn.
1. Supabase thật sự gồm những gì?
Supabase không chỉ là PostgreSQL. Nó là tổ hợp nhiều thành phần:
– PostgreSQL → DB chính.
– PostgREST → tự sinh REST API từ schema PostgreSQL.
– GoTrue / Supabase Auth → auth, JWT, OAuth.
– Realtime server → subscribe thay đổi DB.
– Storage API → quản lý file/object.
– Dashboard → quản trị.
– Edge Functions → logic serverless.
– Row Level Security (RLS) → phân quyền ở tầng DB.
Khi tự xây, không nhất thiết clone 100%. Nên bắt đầu từ lõi:
– Team nhỏ → Docker Compose + PostgreSQL managed/self-host + MinIO.
– Team trung bình → Kubernetes + managed PostgreSQL + S3-compatible storage.
– Sản phẩm production nghiêm túc → managed PostgreSQL nếu không có DBA.
3. PostgreSQL: trung tâm của hệ thống
PostgreSQL vẫn là lựa chọn tốt nhất cho backend hiện đại:
– Quan hệ dữ liệu mạnh.
– Transaction chuẩn.
– Index đa dạng.
– JSONB linh hoạt.
– Full-text search.
– Extension phong phú.
– RLS hỗ trợ phân quyền sâu.
Thiết kế schema
Ví dụ cơ bản:
create table users (
id uuid primary key,
email text unique not null,
display_name text,
created_at timestamptz default now()
);
create table projects (
id uuid primary key default gen_random_uuid(),
owner_id uuid not null references users(id),
name text not null,
created_at timestamptz default now()
);
Nếu dùng external auth, bảng users trong DB thường chỉ là profile mirror, không lưu password.
Migration
Không sửa DB thủ công trên production. Luôn dùng migration:
– Dev tạo migration.
– CI test migration.
– Staging chạy trước.
– Production chạy sau.
1. Client gọi backend xin upload.
2. Backend kiểm tra auth/quota/permission.
3. Backend tạo presigned URL.
4. Client upload trực tiếp lên storage.
5. Backend lưu metadata vào PostgreSQL.
Ví dụ bảng metadata:
create table files (
id uuid primary key default gen_random_uuid(),
owner_id uuid not null references users(id),
bucket text not null,
object_key text not null,
mime_type text,
size_bytes bigint,
created_at timestamptz default now()
);
Ưu điểm:
– Backend không phải stream file lớn.
– Dễ kiểm soát quyền.
– Dễ audit.
– DB biết file thuộc user/project nào.
Public/private file
– File public → dùng CDN/cache.
– File private → luôn cấp signed URL ngắn hạn.
– Không để bucket private bị public nhầm.
– Không tin client gửi owner_id.
6. API layer: không nên bỏ qua
Supabase tiện vì tự sinh API. Nhưng khi tự xây, nên có backend rõ ràng. Lý do:
– Business logic phức tạp.
– Validation.
– Permission.
– Rate limit.
– Audit.
– Integration thanh toán/email/webhook.
– Không expose DB schema trực tiếp.
Production cần secret manager, TLS, backup, monitoring. Không dùng password mẫu.
9. Observability, bảo mật, vận hành
Backend tự xây → bạn chịu trách nhiệm vận hành.
Checklist tối thiểu:
– HTTPS bắt buộc.
– Secret không commit Git.
– Rate limit login/upload/API.
– Audit log hành động quan trọng.
– DB connection pool.
– Migration có rollback plan.
– Log structured JSON.
– Metrics: CPU, RAM, disk, DB connections, slow queries.
– Alert khi disk đầy, DB down, backup fail.
– Sentry/OpenTelemetry cho lỗi app.
– pg_stat_statements để xem query chậm.
Bảo mật file:
– Scan virus nếu user upload file công khai.
– Giới hạn size.
– Kiểm tra MIME thật, không chỉ tin header.
– Random object key.
– Không dùng filename gốc làm path trực tiếp.
10. Khi nào nên tự xây?
Nên tự xây nếu:
– Cần kiểm soát dữ liệu/hạ tầng.
– Chi phí Supabase tăng khó dự đoán.
– Cần auth/storage flow đặc thù.
– Có DevOps/backend đủ mạnh.
– Sản phẩm cần compliance riêng.
– Muốn tránh vendor lock-in.
Không nên nếu:
– MVP cần ra nhanh.
– Team không có người vận hành DB.
– Chưa rõ product-market fit.
– Auth/storage đơn giản.
– Downtime/backup chưa ai chịu trách nhiệm.
Một chiến lược tốt: bắt đầu với Supabase hoặc managed service, sau đó tách dần. Hoặc tự xây từ đầu nhưng dùng managed PostgreSQL/S3 để giảm gánh nặng.
Kết luận thực tế
Tự xây backend thay thế Supabase hoàn toàn khả thi. Lõi kỹ thuật không quá bí ẩn: PostgreSQL cho dữ liệu, Keycloak/Ory/Authentik hoặc auth tự code cho định danh, MinIO/S3 cho storage, backend API cho nghiệp vụ.
Nhưng cái khó không nằm ở việc chạy container. Cái khó là vận hành an toàn lâu dài: migration, backup, restore, monitoring, bảo mật, phân quyền, scale, incident response.
Nếu bạn cần tốc độ → Supabase rất đáng dùng. Nếu bạn cần tự chủ, tuỳ biến sâu, kiểm soát chi phí dài hạn → backend mã nguồn mở là hướng bền vững. Cách khôn ngoan nhất: xây theo từng lớp, giữ kiến trúc đơn giản, dùng chuẩn mở như PostgreSQL, OIDC, S3. Khi đó, dù không dùng Supabase, bạn vẫn có một nền tảng backend hiện đại, linh hoạt, dễ mở rộng.