Tự xây backend thay Supabase: PostgreSQL, Auth, Storage miễn phí

16/05/2026 · P T P · Chung

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:

– PostgreSQL
– Auth
– Storage
– API backend
– Migration
– Observability
– Backup

Realtime, dashboard, edge functions → thêm sau nếu thật sự cần.


2. Kiến trúc đề xuất

Một kiến trúc tự host gọn, bền:

Client App
  ↓
API Gateway / Backend
  ↓
PostgreSQL
  ↓
Auth Provider
  ↓
S3-compatible Storage

Cụ thể:

PostgreSQL: database chính.
Keycloak / Ory Kratos / Authentik / Lucia Auth: auth.
MinIO / Garage / SeaweedFS / Ceph: object storage.
Node.js/NestJS, FastAPI, Go, Laravel, Django: backend API.
Prisma / Drizzle / SQLAlchemy / Diesel: DB access.
Flyway / Liquibase / Atlas / Prisma Migrate: migration.
Caddy / Nginx / Traefik: reverse proxy + TLS.
Docker Compose / Kubernetes: deploy.

Khuyến nghị thực dụng:

– 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.

Tool hợp lý:

– TypeScript → Prisma Migrate, Drizzle Kit, Atlas.
– Java → Flyway, Liquibase.
– Python → Alembic.
– Go → golang-migrate, Atlas.

Backup

Backup là phần nhiều team quên nhất.

Tối thiểu:

– Backup hằng ngày.
– WAL archiving nếu cần point-in-time recovery.
– Test restore định kỳ.
– Backup encrypt.
– Backup lưu ngoài server chính.

DB chết mà không restore được → không có backup.


4. Auth mã nguồn mở: chọn theo nhu cầu

Auth là vùng dễ tự tin sai. Login không chỉ là email/password. Cần:

– Password hashing.
– Email verification.
– Reset password.
– Session/JWT.
– OAuth.
– MFA.
– Device/session management.
– Rate limit.
– Audit log.

Các lựa chọn phổ biến

Keycloak

Phù hợp enterprise:

– OAuth2/OIDC/SAML.
– Social login.
– MFA.
– User federation.
– Admin UI mạnh.
– Realm/client/role đầy đủ.

Nhược:

– Nặng.
– Cấu hình phức tạp.
– UX cần custom nhiều.

Ory Kratos + Hydra

Phù hợp hệ thống cần auth cực linh hoạt:

– Identity management.
– Login/registration flow.
– OAuth2 server qua Hydra.
– Headless, API-first.

Nhược:

– Learning curve cao.
– Cần tự ghép UI, flow.

Authentik

Dễ dùng hơn Keycloak trong nhiều case:

– SSO.
– OAuth/OIDC/SAML.
– Admin UI tốt.
– Self-host thuận tiện.

Lucia Auth / Auth.js

Phù hợp app tự code backend:

– Nhẹ.
– Dễ tích hợp framework.
– Kiểm soát session tốt.

Nhược:

– Không phải identity platform đầy đủ.
– Nhiều tính năng phải tự làm.

JWT hay session?

– App SPA/mobile → access token + refresh token.
– Web app truyền thống → httpOnly cookie session.
– Microservices → JWT/OIDC.
– Bảo mật cao → session server-side dễ revoke hơn.

Đừng lưu token trong localStorage nếu có thể tránh. Ưu tiên httpOnly, Secure, SameSite cookie.


5. Storage: thay thế Supabase Storage

Supabase Storage thực chất là object storage + metadata + access policy. Tự xây có thể dùng:

MinIO: phổ biến, S3-compatible, dễ self-host.
Garage: nhẹ, distributed, hợp homelab/small infra.
SeaweedFS: mạnh cho lượng file lớn.
Ceph: enterprise, phức tạp.
AWS S3 / Cloudflare R2 / Backblaze B2: managed, vẫn dùng chuẩn mở S3 API.

Kiến trúc storage nên có

Client
  ↓ request upload URL
Backend
  ↓ tạo presigned URL
Object Storage

Flow tốt:

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.

Stack gợi ý:

NestJS + Prisma/Drizzle → TypeScript mạnh.
FastAPI + SQLAlchemy → Python nhanh.
Go + sqlc/ent → performance, deploy nhẹ.
Django/Laravel → full-stack backend ổn định.

Pattern nên dùng:

Controller → Service → Repository/DB

Không bắt buộc quá enterprise, nhưng tách lớp giúp code sống lâu.

Validation

Luôn validate input:

– Type.
– Length.
– Format.
– Ownership.
– Business constraints.

Dùng:

– Zod / Valibot cho TypeScript.
– Pydantic cho Python.
– Joi / class-validator.
– Request schema trong OpenAPI.


7. Phân quyền: app-level hay RLS?

Supabase nổi bật nhờ Row Level Security. Tự xây có 2 hướng.

App-level authorization

Backend kiểm tra quyền trước khi query:

where: {
  id: projectId,
  ownerId: currentUser.id
}

Ưu:

– Dễ hiểu.
– Dễ debug.
– Phù hợp đa số app.

Nhược:

– Dev quên filter → leak data.
– Logic phân quyền rải rác.

PostgreSQL RLS

DB tự chặn row không hợp lệ.

Ưu:

– Bảo vệ tầng sâu.
– Hợp multi-tenant.
– Giảm rủi ro query sai.

Nhược:

– Khó debug.
– Cần quản lý DB role/session variable tốt.
– ORM đôi khi gây rối.

Thực tế: bắt đầu app-level. Nếu SaaS multi-tenant lớn → cân nhắc RLS cho bảng nhạy cảm.


8. Docker Compose mẫu tối giản

Một setup local:

services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app_password
      POSTGRES_DB: appdb
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

minio: image: minio/minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: minio_password ports: - "9000:9000" - "9001:9001" volumes: - miniodata:/data

volumes: pgdata: miniodata:

Auth có thể thêm Keycloak:

keycloak:
    image: quay.io/keycloak/keycloak:25.0
    command: start-dev
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin_password
    ports:
      - "8080:8080"

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.

#auth #backend #postgresql #supabase #thay
Chia sẻ:
← Trước
Thay Supabase bằng Firebase: Khi nào nên chuyển an toàn

Bài viết tương tự

Bình luận

Chưa có bình luận. Hãy là người đầu tiên!