Tự xây backend thay Supabase: stack mã nguồn mở cho MVP trong 7 ngày
Supabase quá tiện: database PostgreSQL, auth, storage, realtime, dashboard, API tự sinh. Với MVP, đó là đường tắt mạnh. Nhưng không phải đội nào cũng muốn phụ thuộc nền tảng hosted, chi phí tăng theo scale, giới hạn tuỳ biến, hoặc ràng buộc hạ tầng.
Tin tốt: có thể tự dựng stack mã nguồn mở gần giống Supabase trong 7 ngày, đủ chạy MVP thật. Không cần tái tạo mọi thứ. Cần chọn đúng mảnh ghép: PostgreSQL, PostgREST hoặc Hasura, Keycloak hoặc Stack Auth, MinIO, Realtime, Docker Compose, Caddy/Nginx, Coolify hoặc Dokploy.
Mục tiêu không phải xây “Supabase clone”. Mục tiêu: có backend ổn, tự host, dễ thay, đủ nhanh để validate sản phẩm.
Supabase gồm gì, cần thay bằng gì?
Supabase mạnh vì gom nhiều phần khó thành một trải nghiệm liền mạch:
– PostgreSQL: database chính.
– Auth: đăng ký, đăng nhập, OAuth, JWT, phân quyền.
– Auto API: REST/GraphQL từ database.
– Storage: upload file, bucket, policy.
– Realtime: listen thay đổi database.
– Dashboard: quản lý bảng, user, logs.
– Edge Functions: logic backend nhỏ.
– CLI + migration: quản lý schema.
Khi tự xây, đừng cố copy 1:1. Hãy map sang stack mở:
| Nhu cầu | Công cụ đề xuất |
|—|—|
| Database | PostgreSQL |
| API tự sinh | PostgREST hoặc Hasura |
| Auth | Keycloak, Stack Auth, Lucia/Auth.js tuỳ app |
| Storage | MinIO |
| Realtime | ElectricSQL, Centrifugo, Hasura subscriptions, hoặc trigger + websocket |
| Admin DB | pgAdmin, CloudBeaver, Adminer |
| Deploy | Docker Compose, Coolify, Dokploy |
| Reverse proxy | Caddy hoặc Traefik |
| Monitoring | Uptime Kuma, Grafana, Loki |
| Backup | pg_dump, WAL-G, Litestream-like pattern cho object |
Stack gợi ý cho MVP 7 ngày
Phương án cân bằng: PostgreSQL + PostgREST + Keycloak + MinIO
Stack này hợp nếu muốn đơn giản, ít magic, dễ hiểu.
Thành phần:
– PostgreSQL: nguồn dữ liệu duy nhất.
– PostgREST: sinh REST API trực tiếp từ schema, view, function.
– Keycloak: quản lý user, OAuth, JWT.
– MinIO: S3-compatible object storage.
– Caddy: HTTPS tự động.
– Docker Compose: chạy toàn bộ service.
– pgAdmin hoặc CloudBeaver: dashboard database.
Điểm mạnh:
– Tất cả open-source.
– Tự host dễ.
– PostgreSQL làm trung tâm.
– PostgREST rất nhanh, ít code.
– Keycloak mạnh, hỗ trợ enterprise use case.
Điểm yếu:
– Keycloak nặng với MVP nhỏ.
– Phân quyền Row Level Security cần hiểu PostgreSQL kỹ.
– Dashboard không mượt như Supabase.
– Realtime phải tự ghép thêm.
Phương án nhanh hơn: PostgreSQL + Hasura + Auth.js + MinIO
Nếu team thích GraphQL, Hasura giúp đi nhanh hơn PostgREST.
Điểm mạnh:
– GraphQL API tự sinh.
– Subscription realtime có sẵn.
– Permission theo role khá trực quan.
– Console quản lý schema tốt.
Điểm yếu:
– Metadata Hasura cần quản lý nghiêm.
– Logic phức tạp có thể lệ thuộc Hasura.
– REST client phải thêm layer hoặc dùng GraphQL trực tiếp.
Phương án “backend truyền thống”: NestJS/Fastify + Prisma + PostgreSQL
Nếu MVP cần logic nghiệp vụ nhiều, tự sinh API không đủ.
Điểm mạnh:
– Kiểm soát tuyệt đối.
– Dễ test business logic.
– Team backend truyền thống dễ làm.
– Auth, storage, job queue dễ gom vào codebase.
Điểm yếu:
– Chậm hơn trong 7 ngày.
– Phải viết CRUD, validation, policy.
– Dễ over-engineer.
Kiến trúc đề xuất
Với MVP 7 ngày, kiến trúc nên thẳng:
Client Web/Mobile
|
v
Caddy HTTPS
|
+--> PostgREST / Hasura API
+--> Auth Service
+--> MinIO API
+--> App Functions/API custom
|
v
PostgreSQL
Database vẫn là lõi. Auth phát JWT. API layer đọc JWT, map claim sang role. PostgreSQL dùng RLS nếu cần bảo mật theo từng dòng.
Với stack PostgREST, nên dùng SQL migration thuần. Dễ đọc, dễ debug.
Ngày 3: Auth
Auth là phần dễ đánh giá thấp. MVP vẫn cần chắc.
Lựa chọn:
– Keycloak: mạnh, nhiều tính năng, hợp B2B.
– Stack Auth: nhẹ hơn, dev experience tốt.
– Auth.js: hợp app Next.js.
– Lucia: hợp nếu muốn kiểm soát session.
Nếu dùng JWT:
– Access token ngắn hạn.
– Refresh token an toàn.
– Không nhét dữ liệu nhạy cảm vào token.
– Có cơ chế revoke nếu cần.
MVP nên hỗ trợ:
– Email/password hoặc magic link.
– Google OAuth nếu khách hàng mục tiêu dùng Google.
– Role cơ bản.
– Trang quản lý user tối thiểu.
Ngày 4: API tự sinh
Nếu dùng PostgREST:
– Expose schema api, không expose toàn database.
– Tạo view cho response.
– Tạo function cho action phức tạp.
– Dùng RLS cho phân quyền.
Ví dụ pattern:
create schema api;
create view api.projects as
select id, name, owner_id, created_at
from public.projects;
Không để client gọi trực tiếp bảng nhạy cảm. View là hợp đồng API.
Nếu dùng Hasura:
– Track table cần dùng.
– Cấu hình permission theo role.
– Bật allow-list query nếu app public.
– Quản lý metadata trong git.
Ngày này mục tiêu: frontend có thể CRUD dữ liệu chính.
Ngày 5: Storage file
Supabase Storage tiện vì gắn policy với bucket. Khi tự build, dùng MinIO.
Cách an toàn:
– Client không upload trực tiếp bằng credential chính.
– Backend tạo presigned URL.
– Lưu metadata file vào PostgreSQL.
– Validate MIME type, size, owner.
– Tách bucket public/private.
Luồng upload:
1. Client gọi API xin upload URL.
2. Backend kiểm tra user và quyền.
3. Backend trả presigned URL.
4. Client upload lên MinIO.
5. Client gọi API xác nhận.
6. Backend lưu record file.
Không tin metadata từ client. File action cần kiểm tra lại ở server nếu quan trọng.
Ngày 6: Realtime, jobs, email
Không phải MVP nào cũng cần realtime. Nếu chỉ cần refresh sau action, bỏ realtime. Nếu cần chat, dashboard live, collaboration, chọn một:
– Hasura subscriptions nếu đã dùng Hasura.
– Centrifugo cho websocket pub/sub.
– ElectricSQL nếu cần sync local-first.
– PostgreSQL LISTEN/NOTIFY + service nhỏ nếu nhu cầu hẹp.
Background jobs:
– pg-boss nếu dùng Node + PostgreSQL.
– Graphile Worker ổn, đơn giản.
– BullMQ + Redis nếu đã có Redis.
Email:
– Dùng Resend, Postmark, Amazon SES.
– Self-host mail server không đáng cho MVP.
Ngày này cũng thêm:
– Uptime Kuma check endpoint.
– Log tập trung tối thiểu.
– Error tracking bằng Sentry hoặc GlitchTip.
Ngày 7: Backup, bảo mật, deploy thật
Ngày cuối không thêm feature lớn. Chỉ harden và kiểm tra.
Backup PostgreSQL:
– pg_dump hằng ngày cho MVP nhỏ.
– Lưu ra object storage khác server.
– Test restore.
– Mã hoá backup nếu có dữ liệu nhạy cảm.
Backup MinIO:
– Mirror sang bucket khác bằng mc mirror.
– Versioning nếu cần.
Bảo mật tối thiểu:
– Chỉ mở port 80/443/22.
– SSH key, tắt password login.
– Tách secret khỏi git.
– Dùng .env an toàn.
– Rate limit auth endpoint.
– CORS chặt.
– Không expose admin dashboard public nếu không có auth mạnh.
Kiểm thử cuối:
– User mới đăng ký được.
– User chỉ thấy data của mình.
– Upload/download đúng quyền.
– Backup chạy.
– Restore thử trên máy khác.
– Logs đủ debug lỗi.
Keycloak có thể cần RAM hơn. Nếu VPS nhỏ, cân nhắc Auth.js hoặc Stack Auth. PostgreSQL nên có RAM ổn, disk SSD, backup đều.
Chi phí rẻ không có nghĩa miễn phí. Tự host đổi tiền nền tảng lấy công vận hành. Team cần người chịu trách nhiệm khi server chết lúc 2 giờ sáng.
Khi nào nên tự xây, khi nào nên dùng Supabase?
Nên tự xây nếu:
– Cần kiểm soát hạ tầng.
– Có yêu cầu dữ liệu riêng.
– Team biết Docker, PostgreSQL, auth.
– Muốn tránh vendor lock-in.
– MVP có khả năng thành sản phẩm dài hạn.
Nên dùng Supabase nếu:
– Team nhỏ, thiếu backend/devops.
– Cần ra thị trường cực nhanh.
– Auth/realtime/storage chuẩn Supabase đã đủ.
– Chưa chắc sản phẩm có người dùng.
– Không muốn ôm backup, security, monitoring.
Lựa chọn thực tế: bắt đầu bằng Supabase cũng không sai. Nhưng nếu đã biết từ đầu cần self-host, hãy xây stack mở từ sớm để tránh migration đau.
Kết luận thực tế
Tự xây backend thay Supabase trong 7 ngày làm được, nếu phạm vi rõ và không tham. Stack tốt cho MVP: PostgreSQL + PostgREST hoặc Hasura + Auth phù hợp + MinIO + Docker Compose + Caddy + backup nghiêm túc.
Đừng cố xây nền tảng hoàn hảo. Hãy xây backend đủ dùng, có auth đúng, phân quyền đúng, backup restore được, deploy lặp lại được. MVP thắng nhờ tốc độ học từ người dùng, không phải vì kiến trúc đẹp.
Supabase là sản phẩm tuyệt vời. Stack mã nguồn mở tự host là lựa chọn mạnh. Khác biệt nằm ở trách nhiệm: dùng Supabase, nền tảng gánh nhiều việc. Tự xây, team phải gánh. Nếu chấp nhận điều đó, 7 ngày đủ để có backend sạch, rẻ, kiểm soát tốt, sẵn sàng cho vòng thử nghiệm đầu tiên.