
Supabase là gì? Tự host bằng Docker và các giới hạn
Đăng 8 phút đọc
Mục lục · 16
Supabase là gì: một backend mã nguồn mở dựng trên Postgres, có sẵn đăng nhập, API, lưu file, realtime và edge function. Bài này tự host Supabase bằng Docker trên máy thật, đo thời gian cài, RAM từng container, ghi lại ba lỗi khi chạy và cái bẫy RLS làm lộ dữ liệu.
Supabase là một backend mã nguồn mở dựng quanh Postgres: tạo bảng là có ngay REST API, kèm đăng nhập người dùng, lưu file, realtime và edge function. Supabase từng tự giới thiệu là bản thay thế Firebase mã nguồn mở. Bạn dùng bản cloud của Supabase, hoặc tự host toàn bộ bằng Docker trên máy chủ của mình.
Mình thử tự host Supabase trên một máy Ubuntu 24.04 ngày 09/10/2026. Vài con số để hình dung:
Lệnh cài nhanh chạy xong trong 70 giây, tự sinh mọi mật khẩu và khóa, rồi khởi động 11 container.
Lúc rảnh cả bộ ăn 1,15GB RAM, 11 image chiếm khoảng 9,1GB đĩa.
Ba lỗi gặp ngay lần đầu: edge function không khởi động được vì jsr.io trả
403, đăng ký tài khoản báoError sending confirmation email, bảng mới chưa có trong API.Bảng tạo bằng SQL không bật RLS mặc định. Khi đó ai có khóa công khai của web cũng đọc và xóa được dữ liệu.

Supabase gồm những gì?
Supabase là một bộ dịch vụ ghép quanh Postgres, danh sách container của bản tự host cho thấy rõ:
Thành phần | Image | Làm gì |
|---|---|---|
db | supabase/postgres 17.6 | Cơ sở dữ liệu, mọi thứ nằm ở đây |
rest | PostgREST v14.17 | Biến bảng thành REST API |
auth | GoTrue v2.196.0 | Đăng ký, đăng nhập, JWT |
storage + imgproxy | storage-api v1.74.0 | Lưu file, cắt ảnh |
realtime | realtime v2.134.10 | Đẩy thay đổi qua websocket |
functions | edge-runtime v1.76.2 | Edge function chạy Deno |
studio, meta, pooler, envoy | Giao diện quản trị, pool kết nối, API gateway |
Từ bản này, gateway mặc định là Envoy, Kong chỉ còn là tùy chọn. Code nằm trong repo supabase/supabase (111 nghìn sao, giấy phép Apache-2.0).
Supabase Cloud hay tự host?
Bản cloud có gói Free 0 USD: 500MB database, 50.000 người dùng hoạt động mỗi tháng, 1GB lưu file, nhưng project bị tạm dừng sau 1 tuần không hoạt động và tối đa 2 project. Gói Pro từ 25 USD/tháng (theo trang giá Supabase ngày 09/10/2026).
Tự host thì không giới hạn kiểu đó, nhưng tài liệu của Supabase ghi rõ những gì bạn mất:
Chỉ một project, Studio không có nhiều tổ chức hay nhiều project.
Không có branching, sao lưu tự động và PITR, metrics nâng cao, Management API.
Bạn tự lo bảo mật, cập nhật, sao lưu, giám sát. Hỗ trợ chỉ từ cộng đồng.
Điểm cộng ít người để ý: bản tự host không gửi telemetry về Supabase.
Tự host Supabase bằng Docker thế nào?
Yêu cầu tối thiểu theo tài liệu là 4GB RAM, 2 nhân, 40GB SSD. Trên Linux, một lệnh làm hết: cài Docker nếu thiếu, tải thư mục docker/ của repo, sinh mật khẩu, khóa ký JWT, khóa API, rồi kéo image. Thêm -y để không bị hỏi:
curl -fsSL https://supabase.link/setup.sh | sh -s -- -y
cd supabase-project
sh run.sh start

Trên máy của mình, bước cài mất 70 giây kể cả kéo image. Một điểm cần biết: script in toàn bộ mật khẩu và khóa ra màn hình. Nếu bạn quay video hay chia sẻ màn hình lúc cài, coi như các khóa đó đã lộ. Xem lại sau bằng sh run.sh secrets.
sh run.sh start dựng 11 container. 20 giây sau, 10 container báo healthy, riêng edge-functions khởi động lại liên tục (lỗi ở mục dưới).

Studio và API dùng chung cổng 8000, có đăng nhập Basic Auth (vào không có mật khẩu bị trả 401). Tài khoản xem bằng sh run.sh secrets, mục DASHBOARD_USERNAME và DASHBOARD_PASSWORD.
Supabase tốn bao nhiêu RAM khi chạy?
Mình đo bằng docker stats lúc chưa có tải:

Postgres chỉ chiếm 104MB. Phần nặng là các dịch vụ phụ: pooler, storage, studio, realtime mỗi cái khoảng 200MB. Không dùng realtime hay storage thì xóa khỏi docker-compose.yml để tiết kiệm, tài liệu cho phép việc này.
Thử tải nhẹ: 2.000 lệnh GET vào rest/v1 qua Envoy, 50 lệnh song song, cả 2.000 đều trả 200, khoảng 1.110 lệnh mỗi giây. Đây là cận dưới vì mỗi lệnh tốn một tiến trình curl, chưa phải giới hạn của Supabase.
Bẫy RLS: bảng không bật RLS bị đọc và xóa tự do
Đây là thứ nên đọc kỹ nhất. Supabase cấp cho web hai khóa: publishable (nhúng thẳng trong code web, ai mở trang cũng thấy) và secret (chỉ để ở server). Khóa publishable an toàn được là nhờ RLS (Row Level Security): policy trong Postgres quyết định ai đọc, ghi được dòng nào.
Mình tạo bảng don_hang bằng SQL, thêm 2 đơn có số điện thoại, rồi gọi API bằng khóa publishable:
create table public.don_hang (id bigint generated always as identity primary key, khach text, tong int, so_dien_thoai text);
insert into public.don_hang (khach, tong, so_dien_thoai) values ('Chị Lan', 118800, '0901xxx111'), ('Anh Minh', 162000, '0912xxx222');

Bảng tạo bằng SQL thì RLS tắt: khóa publishable đọc được cả số điện thoại và xóa được đơn của Anh Minh. Bật RLS mà chưa có policy thì API trả mảng rỗng. Thêm policy cho phép đọc thì đọc được nhưng vẫn không xóa được:
alter table public.don_hang enable row level security;
create policy "ai cung doc" on public.don_hang for select to anon using (true);
Tạo bảng trong Studio thì an toàn hơn: hộp "New table" tick sẵn Enable Row Level Security (RLS), gắn nhãn RECOMMENDED. Nếu quên, mục Security Advisor báo lỗi "RLS Disabled in Public" ngay:

Còn đây là hộp tạo bảng trong Studio, ô RLS được tick sẵn:

Nếu bạn nhờ AI viết SQL migration cho app, kiểm tra từng lệnh create table có đi kèm enable row level security không: thiếu dòng đó app vẫn chạy bình thường, chẳng có gì báo là dữ liệu đang mở.
Những lỗi mình gặp khi cài Supabase
Lỗi | Nguyên nhân | Cách sửa |
|---|---|---|
edge-functions khởi động lại liên tục | jsr.io (Cloudflare) trả | Đổi import |
| Gói npm không có file khai báo kiểu đó | Bỏ dòng import kiểu (chỉ dùng cho editor) |
| Cấu hình mẫu trỏ SMTP vào | Cấu hình SMTP thật, hoặc tạm bật |
| PostgREST chưa nạp bảng mới |
|
Lỗi đầu tiên, nguyên văn trong log:
worker boot error: failed to bootstrap runtime: failed to create the graph: JSR package manifest for '@panva/jose' failed to load. Import 'https://jsr.io/@panva/jose/meta.json' failed: 403 Forbidden
at file:///home/deno/functions/main/index.ts:1:23

Từ máy Mac của mình, jsr.io trả 200; từ máy chủ thì 403, còn registry npm vẫn 200. Vậy lỗi nằm ở việc jsr.io chặn dải IP đó, không phải do Supabase. Mình sửa dòng 1 của volumes/functions/main/index.ts thành import * as jose from 'npm:jose@6', đổi @supabase/functions-js trong deno.jsonc sang npm:, bỏ dòng import "@supabase/functions-js/edge-runtime.d.ts" trong function mẫu hello. Sau đó function trả lời sau 368ms lần đầu, các lần sau khoảng 5ms.
Lỗi thứ ba, khi gọi auth/v1/signup:
{"code":500,"error_code":"unexpected_failure","msg":"Error sending confirmation email"}
"error":"dial tcp: lookup supabase-mail on 127.0.0.11:53: server misbehaving"

Bật tự xác nhận email trong .env rồi khởi động lại riêng container auth là đăng ký được ngay:
sed -i 's/^ENABLE_EMAIL_AUTOCONFIRM=false/ENABLE_EMAIL_AUTOCONFIRM=true/' .env
docker compose up -d auth
Lệnh signup sau đó trả 200, tài khoản được xác nhận ngay và có access token. Chỉ nên làm vậy khi thử nghiệm; chạy thật thì điền SMTP thật để người dùng phải xác nhận email.
Cổng nào phải chặn khi đưa Supabase lên VPS?
Bản mặc định mở ra mọi địa chỉ (0.0.0.0) ba cổng: 8000 (API và Studio), 5432 và 6543 (Postgres qua pooler). Trên VPS có IP public, hai cổng Postgres phải chặn bằng firewall, chỉ để 8000 sau reverse proxy có HTTPS. Mình làm trên máy không có IP public nên không bị lộ, nhưng đem nguyên cấu hình này lên VPS là mở database ra Internet.
Khi nào không nên tự host Supabase?
Project nhỏ, ít người dùng: gói Free của Supabase Cloud đủ dùng, chỉ cần có truy cập đều để khỏi bị tạm dừng.
Không ai trong nhóm sao lưu và cập nhật được Postgres. Bản tự host không có sao lưu tự động.
Cần nhiều project hoặc branching cho từng tính năng: bản tự host chỉ có một project.
Câu hỏi thường gặp
Supabase có miễn phí không?
Mã nguồn miễn phí theo Apache-2.0, tự host Supabase không mất phí bản quyền, chỉ tốn tiền máy chủ. Bản cloud có gói Free, project bị tạm dừng sau một tuần không hoạt động.
Supabase khác Firebase thế nào?
Supabase dùng Postgres (SQL, có bảng, khóa ngoại, join), còn cơ sở dữ liệu chính của Firebase là Firestore, lưu dạng tài liệu (document). Supabase tự host được toàn bộ, Firebase chỉ chạy trên hạ tầng Google.
Tự host Supabase cần VPS cấu hình bao nhiêu?
Tài liệu ghi tối thiểu 4GB RAM, 2 nhân, 40GB SSD. Mình đo lúc rảnh hết 1,15GB RAM và khoảng 9,1GB image, nên 4GB RAM là vừa đủ cho thử nghiệm.
Supabase CLI có dùng để tự host được không?
Không. Tài liệu Supabase nói stack chạy bằng CLI chỉ để phát triển trên máy, chưa được gia cố bảo mật và không được mở ra Internet. Tự host thì dùng Docker như trong bài.
Đọc tiếp
Tự host n8n bằng Docker: khóa cổng, HTTPS khi không có IP tĩnh, sao lưu.
n8n là gì: workflow đầu tiên và trợ lý AI tự chạy.
n8n MCP: cho Claude Code chạy và dựng workflow.
Cần máy chủ để thử Supabase tự host mà chưa muốn thuê VPS dài hạn, AIDev Cloud cho thuê máy theo giờ; máy CPU 16 nhân 32GB dùng trong bài có giá 3.000 đồng/giờ ngày 09/10/2026.
Thử ngày 09/10/2026 trên máy CPU Standard (16 nhân, 32GB RAM, Ubuntu 24.04, không IP public) của AIDev Cloud: Supabase self-hosted v0.8.2, Docker 29.6.1, Docker Compose 5.3.0.
Chuyên mục
AI AutomationVề tác giả
Founder AIDev
Thạc sĩ AI MSE, tốt nghiệp thủ khoa với điểm 9,4/10. Đồng sáng lập, CTO E-University, SVOnline: số hóa 10+ đại học, 40.000+ sinh viên. Sáng lập AIDev và VietPlatform, xây hệ thống AI cho doanh nghiệp. Anh trực tiếp biên soạn và giảng dạy toàn bộ lộ trình AI Engineer.


