SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

Supabase چیست؟ اجزای آن و تفاوت نسخه ابری با خودمیزبان

Supabase یک PostgreSQL است با API خودکار، ورود کاربران، Realtime، فضای فایل و Edge Functions. اینجا ببینید نسخه ابری آن با نسخه روی VPS خودتان چه فرقی دارد.

Supabase چیست؟ پاسخ کوتاه

Supabase یک پایگاه داده PostgreSQL است که چند سرویس آماده دور آن ساخته شده است. این سرویس‌ها عبارت‌اند از یک API خودکار، سیستم ورود کاربران (Auth)، پیام‌رسانی زنده (Realtime)، فضای نگهداری فایل (Storage)، توابع سمت سرور (Edge Functions) و یک داشبورد به نام Studio. به همین دلیل خیلی‌ها به آن «Firebase متن‌باز» می‌گویند. کد همه این اجزا روی GitHub باز است. پس همین مجموعه را به دو شکل می‌شود اجرا کرد: روی سرویس ابری خود شرکت Supabase، یا با Docker Compose روی سروری که خودتان مدیریت می‌کنید.

فرض کنید یک اپ موبایل یا یک فروشگاه اینترنتی می‌سازید و نمی‌خواهید برای ثبت‌نام، جدول‌ها و آپلود عکس محصول از صفر بک‌اند بنویسید. Supabase برای همین کار ساخته شده است. ادامه این راهنما هر بخش را جدا معرفی می‌کند و می‌گوید پشت آن کدام پروژه متن‌باز است. این اطلاعات تا مهر ۱۴۰۵ (اکتبر ۲۰۲۶) با مخزن supabase/supabase و مستندات رسمی تطبیق داده شده است.

چرا به Supabase می‌گویند «Firebase متن‌باز»؟

این اسم فقط نیمی از ماجرا را می‌گوید. Firebase مجموعه‌ای از سرویس‌های گوگل است: پایگاه داده، ورود کاربران، فضای فایل و توابع ابری. Supabase هم همین بخش‌ها را دارد. برای همین کسی که با Firebase کار کرده، با آن احساس آشنایی می‌کند.

فرق اصلی در مدل داده است. Firestore در Firebase سند (document) نگه می‌دارد و یک پایگاه داده NoSQL است. Supabase داده را در جدول‌های یک پایگاه داده رابطه‌ای نگه می‌دارد. در نتیجه SQL، کلید خارجی (foreign key)، JOIN و تراکنش در اختیار شماست. مهاجرت از Firebase به Supabase یعنی طراحی دوباره داده‌ها و با کپی کردن ساده انجام نمی‌شود. اگر هنوز بین گزینه‌ها مردد هستید، مقایسه جایگزین‌های خودمیزبان Firebase Supabase را کنار رقبایش می‌گذارد.

هسته Supabase: یک پایگاه داده PostgreSQL کامل

هر پروژه Supabase یک پایگاه داده PostgreSQL واقعی است و لایه‌ای که فقط شبیه آن باشد نیست. می‌توانید با psql یا هر ابزار دیگری مستقیم به آن وصل شوید. افزونه‌هایی مثل pgvector را هم می‌توانید برای جست‌وجوی برداری (embedding) فعال کنید.

نکته مهم این است که بقیه اجزا هم داده‌شان را در همین پایگاه داده نگه می‌دارند. حساب‌های کاربری در اسکیمای auth هستند و اطلاعات فایل‌ها در اسکیمای storage. یعنی نسخه پشتیبان PostgreSQL بیشتر وضعیت پروژه را در بر می‌گیرد. فایل‌های آپلودشده جای دیگری ذخیره می‌شوند و باید جداگانه از آن‌ها پشتیبان گرفت.

یک مفهوم را از همین‌جا باید بشناسید: RLS (Row Level Security، امنیت در سطح سطر). RLS قابلیتی از خود PostgreSQL است. با آن برای هر جدول قانون می‌نویسید که هر کاربر کدام سطرها را ببیند یا تغییر دهد. در Supabase این قانون‌ها خط اصلی دفاع هستند، چون مرورگر کاربر مستقیم با API پایگاه داده حرف می‌زند.

API خودکار Supabase چطور ساخته می‌شود؟

دو پروژه متن‌باز این کار را انجام می‌دهند. PostgREST یک وب‌سرور است که ساختار پایگاه داده را می‌خواند و برای هر جدول یک API از نوع REST می‌سازد. pg_graphql یک افزونه PostgreSQL است که همان داده را با GraphQL در اختیار می‌گذارد. برای این API کدی نمی‌نویسید. جدول orders را که بسازید، آدرس /rest/v1/orders آماده است.

curl 'https://<project-ref>.supabase.co/rest/v1/orders?select=*' \
  -H "apikey: <publishable-or-anon-key>"

در اپ جاوااسکریپت معمولاً از کتابخانه رسمی استفاده می‌کنید:

npm install @supabase/supabase-js
import { createClient } from '@supabase/supabase-js'

const supabase = createClient('https://<project-ref>.supabase.co', '<publishable-or-anon-key>')
const { data, error } = await supabase.from('orders').select('*')

کلیدی که در این کد می‌بینید عمومی است و داخل اپ کاربر قرار می‌گیرد. پس چه چیزی جلوی خواندن داده‌های دیگران را می‌گیرد؟ پاسخ RLS است. درخواستی که از کاربرِ واردنشده می‌آید با نقش anon اجرا می‌شود. بعد از ورود، اپ یک JWT (JSON Web Token، توکن امضاشده‌ای که شناسه کاربر را با خود دارد) می‌فرستد و درخواست با نقش authenticated اجرا می‌شود. PostgREST پیش از اجرای کوئری به همین نقش سوییچ می‌کند. بنابراین تصمیم نهایی را قانون‌های RLS در خود PostgreSQL می‌گیرند.

دو خطای رایج از همین سازوکار ناشی می‌شوند. اگر RLS روی جدول روشن باشد ولی هیچ policy (قانون دسترسی) برایش ننوشته باشید، پاسخ API یک آرایه خالی [] با کد 200 است و پیام خطایی نمی‌بینید. دلیلش این است که RLS بدون policy همه سطرها را پنهان می‌کند. حالت بدتر برعکس آن است: اگر RLS روی جدولی در اسکیمای public خاموش باشد، هر کسی که کلید عمومی را دارد کل جدول را می‌خواند. Studio کنار چنین جدولی برچسب هشدار نشان می‌دهد. آن را نادیده نگیرید.

ورود کاربران در Supabase با چه چیزی کار می‌کند؟

سرویس Auth یک سرور مدیریت کاربر است که با زبان Go نوشته شده و کدش در مخزن supabase/auth قرار دارد. این پروژه در اصل بر پایه GoTrue از شرکت Netlify شروع شد و حالا مسیر جداگانه‌ای را طی کرده است. ثبت‌نام با ایمیل و رمز عبور، لینک ورود ایمیلی (magic link)، ورود با حساب گوگل یا GitHub و کد یک‌بارمصرف پیامکی را پشتیبانی می‌کند. خروجی هر ورود موفق همان JWT است که RLS از آن استفاده می‌کند.

کاربران در جدول auth.users در همان پایگاه داده ذخیره می‌شوند. پس جدول profiles شما می‌تواند با کلید خارجی به آن اشاره کند و اطلاعات کاربر کنار داده‌های اپ می‌ماند. برای ارسال ایمیل واقعی به کاربران، یک سرور SMTP (پروتکل ارسال ایمیل) متعلق به خودتان را تنظیم کنید. اگر سرویس‌دهنده پیامکی که می‌خواهید در فهرست آماده نیست، قابلیت Send SMS Hook اجازه می‌دهد ارسال پیامک را به کد خودتان بسپارید.

Realtime در Supabase چه کاری انجام می‌دهد؟

Realtime یک سرور است که با زبان Elixir نوشته شده است. کار اصلی‌اش این است که تغییرات جدول‌ها (درج، ویرایش و حذف سطر) را از PostgreSQL بگیرد و از طریق WebSocket به اپ‌های متصل بفرستد. مثلاً وقتی وضعیت یک سفارش عوض می‌شود، صفحه پیگیری سفارش مشتری بدون رفرش به‌روز می‌شود. این سرویس دو حالت دیگر هم دارد: Broadcast برای فرستادن پیام بین کاربران، و Presence برای نشان دادن اینکه چه کسی آنلاین است.

رایج‌ترین مشکل این است که اپ به کانال وصل می‌شود ولی هیچ رویدادی دریافت نمی‌کند. معمولاً دلیلش این است که جدول در publication به نام supabase_realtime نیست. publication فهرست جدول‌هایی است که PostgreSQL تغییراتشان را منتشر می‌کند، و Realtime فقط تغییرات جدول‌های همین فهرست را می‌بیند:

alter publication supabase_realtime add table public.orders;

RLS اینجا هم اعمال می‌شود. کاربر فقط تغییرات سطرهایی را دریافت می‌کند که اجازه خواندنشان را دارد. پس اگر جدول در publication هست و باز هم رویدادی نمی‌رسد، policy خواندن را بررسی کنید.

فضای فایل Supabase کجا ذخیره می‌شود؟

سرویس Storage یک API از نوع REST برای مدیریت فایل است. خود فایل‌ها در یک فضای سازگار با S3 نگه داشته می‌شوند و اطلاعات و مجوزهایشان در جدول storage.objects در PostgreSQL. یعنی دسترسی به فایل‌ها هم با همان policyهای RLS کنترل می‌شود که برای جدول‌ها می‌نویسید. در نسخه خودمیزبان می‌توانید فایل‌ها را روی دیسک همان سرور نگه دارید یا به یک سرویس سازگار با S3 بفرستید.

کنار Storage یک سرور imgproxy کار می‌کند. imgproxy اندازه عکس‌ها را در لحظه درخواست تغییر می‌دهد. پس لازم نیست از هر عکس محصول چند نسخه کوچک و بزرگ آپلود کنید.

Edge Functions برای چه کدی مناسب است؟

Edge Functions توابع کوچکی به زبان TypeScript هستند که روی Edge Runtime اجرا می‌شوند. Edge Runtime یک محیط اجرای مبتنی بر Deno است و کدش در مخزن supabase/edge-runtime قرار دارد. هر کدی که به کلید محرمانه نیاز دارد باید اینجا باشد، نه داخل اپ کاربر. مثال آشنا: آدرس بازگشت (callback) درگاه پرداخت که باید تراکنش را با کلید مخفی فروشگاه تأیید کند.

در نسخه ابری این توابع روی شبکه توزیع‌شده خود Supabase اجرا می‌شوند. در نسخه خودمیزبان روی یک کانتینر در همان سرور شما. این توابع برای منطق کوتاه مناسب‌اند. کارهای سنگین و طولانی را به یک سرویس جدا بسپارید.

Studio و اجزایی که مستقیم نمی‌بینید

Studio داشبورد وب Supabase است: ویرایشگر جدول، ویرایشگر SQL، مدیریت کاربران و تنظیمات Storage. Studio برای کار با پایگاه داده از postgres-meta کمک می‌گیرد. postgres-meta یک API از نوع REST برای مدیریت PostgreSQL است که با آن جدول‌ها را می‌خوانید، نقش می‌سازید و کوئری اجرا می‌کنید.

چند جزء دیگر هم پشت صحنه کار می‌کنند. یک API gateway (دروازه API) همه درخواست‌ها را روی یک آدرس می‌گیرد و هر مسیر را به سرویس خودش می‌فرستد: /rest/v1 به PostgREST، /auth/v1 به Auth، /storage/v1 به Storage، /realtime/v1 به Realtime و /functions/v1 به Edge Functions. در راهنمای Docker نسخه خودمیزبان، این دروازه Envoy است و Kong یک گزینه اختیاری است. Supavisor یک connection pooler است. یعنی تعداد زیادی اتصال کوتاه از سمت اپ را روی تعداد کمی اتصال واقعی به PostgreSQL پخش می‌کند. این کار لازم است، چون هر اتصال PostgreSQL حافظه جداگانه‌ای مصرف می‌کند. Logflare و Vector هم برای جمع‌آوری لاگ هستند و در نسخه خودمیزبان به‌طور پیش‌فرض خاموش‌اند.

Supabase Cloud یا Supabase خودمیزبان روی VPS؟

کد هر دو یکی است. فرق در این است که چه کسی آن را اجرا و نگهداری می‌کند.

در Supabase Cloud در سایت supabase.com ثبت‌نام می‌کنید و چند دقیقه بعد پروژه‌ای با آدرس https://<project-ref>.supabase.co دارید. پشتیبان‌گیری، به‌روزرسانی و مقیاس‌پذیری بر عهده شرکت Supabase است. صورت‌حساب به دلار آمریکا صادر می‌شود. قیمت‌ها و محدودیت‌های پلن رایگان مرتب تغییر می‌کنند. برای همین آن‌ها را در مقایسه پلن رایگان Supabase Cloud با نسخه خودمیزبان ببینید. معادل تومانی آن‌ها را هم اینجا نمی‌نویسیم، چون با نرخ ارز چند هفته بعد دیگر درست نیست.

در نسخه خودمیزبان همان سرویس‌ها با Docker Compose روی سرور شما بالا می‌آیند. مستندات رسمی (تا مهر ۱۴۰۵) صریحاً می‌گوید این قابلیت‌ها در نسخه خودمیزبان وجود ندارند: branching (شاخه‌های جدا از پایگاه داده برای تست)، متریک‌های پیشرفته فراتر از لاگ، پشتیبان‌گیری مدیریت‌شده و PITR (بازگرداندن داده به یک لحظه مشخص در گذشته)، analytics bucket و vector bucket، ETL و Management API. در این حالت Studio فقط یک پروژه را نشان می‌دهد و از چند سازمان یا چند پروژه پشتیبانی نمی‌کند. طبق مستندات، ایمیج‌های Docker با هم تست می‌شوند و برای همین ممکن است از آخرین نسخه‌های موجود در Docker Hub عقب‌تر باشند.

نیاز سخت‌افزاری طبق همان مستندات حداقل ۴ گیگابایت RAM، ۲ هسته CPU و ۴۰ گیگابایت SSD است. مقدار پیشنهادی ۸ گیگابایت RAM یا بیشتر، ۴ هسته و ۸۰ گیگابایت SSD است. دلیل این عدد ساده است: حدود ده کانتینر جدا اجرا می‌شود و PostgreSQL هم برای کش به حافظه نیاز دارد. وقتی حافظه تمام شود، هسته لینوکس یک پروسه را متوقف می‌کند و پیام Out of memory: Killed process در خروجی sudo dmesg ظاهر می‌شود.

در نسخه خودمیزبان پشتیبان‌گیری کار خود شماست و در داشبورد گزینه‌ای برایش نیست. پشتیبان‌گیری و ارتقای یک استک Docker Compose همین روند را توضیح می‌دهد. مراحل کامل نصب، از فایل .env تا TLS، در راهنمای نصب Supabase خودمیزبان روی VPS آمده است.

آیا Supabase Cloud از ایران قابل استفاده است؟

این را باید خودتان بررسی کنید و نباید فرضش کنید. اینجا دو سؤال جدا وجود دارد.

سؤال اول مربوط به شبکه است. آیا صفحه ثبت‌نام supabase.com و آدرس API پروژه روی *.supabase.co از شبکه‌های داخل ایران باز می‌شود؟ ما برای این راهنما از داخل ایران تست نکرده‌ایم. پاسخ هم ممکن است بین اپراتورها فرق کند و با گذشت زمان تغییر کند. Supabase در فروردین ۱۴۰۵ (مارس ۲۰۲۶) مطلبی با عنوان Navigating Regional Network Blocks منتشر کرد که مسدودسازی در امارات، یمن و هند را بررسی می‌کند. نامی از ایران در آن مطلب نیامده است. پس آن مطلب درباره ایران پاسخ مثبت یا منفی نمی‌دهد.

از همان شبکه‌ای تست کنید که کاربرانتان از آن استفاده می‌کنند. دلیلش این است که اپ روی گوشی کاربر مستقیم به *.supabase.co وصل می‌شود و از سرور شما عبور نمی‌کند:

curl -sSL -o /dev/null -w '%{http_code}\n' https://supabase.com
curl -sS -o /dev/null -w '%{http_code}\n' https://<project-ref>.supabase.co/rest/v1/

هر کد HTTP، مثلاً 200 برای سایت یا 401 برای API بدون کلید، یعنی اتصال برقرار شده و سرور پاسخ داده است. پیام Could not resolve host یا تمام شدن زمان انتظار (timeout) یعنی مسیر در آن شبکه باز نیست. دستور دوم را جداگانه اجرا کنید، چون دامنه API با دامنه سایت یکی نیست.

سؤال دوم حقوقی است. Supabase یک شرکت آمریکایی است. بند Export Regulation در شرایط استفاده آن (supabase.com/terms) از مشتری می‌خواهد که سرویس را در هیچ کشوری که قانون صادرات آمریکا منع کرده در دسترس قرار ندهد. ایران زیر تحریم‌های آمریکاست. این بند را خودتان بخوانید و درباره حساب و پروژه‌تان تصمیم بگیرید. این سؤال فنی نیست و هیچ تنظیمی آن را حل نمی‌کند.

نسخه خودمیزبان به پاسخ هیچ‌کدام از این دو سؤال وابسته نیست. اپ شما با دامنه سرور خودتان حرف می‌زند و هنگام کار هیچ درخواستی به *.supabase.co نمی‌فرستد. اینکه کاربران به سرور شما دسترسی دارند یا نه، به شبکه همان سرور برمی‌گردد و سؤال جداگانه‌ای است.

چه زمانی Supabase ابزار اشتباهی است؟

Supabase برای اپی مناسب است که ورود کاربر، API و فایل را یک‌جا و آماده لازم دارد. در این حالت‌ها انتخاب بهتری وجود دارد:

  • فقط پایگاه داده لازم دارید. اگر بک‌اند شما خودش با پایگاه داده کار می‌کند، ده کانتینر اضافه فقط حافظه مصرف می‌کند. یک PostgreSQL ساده کافی است و مقایسه PostgreSQL مدیریت‌شده با PostgreSQL روی VPS خودتان کمک می‌کند بین این دو انتخاب کنید.
  • بک‌اند کامل دارید. پروژه‌ای که با Laravel یا Django نوشته شده، سیستم ورود و API خودش را دارد. اضافه کردن Supabase یعنی دو سیستم ورود کاربر که باید با هم هماهنگ بمانند.
  • سرور شما کمتر از ۴ گیگابایت RAM دارد. نسخه خودمیزبان روی چنین سروری به دلیل کمبود حافظه مدام از کار می‌افتد.
  • تیم شما نمی‌خواهد policy بنویسد. امنیت داده در Supabase به RLS بستگی دارد. جدولی که RLS ندارد، با کلید عمومی برای همه باز است.

اگر تصمیم دارید پایگاه داده را جدا نگه دارید، بحث بعدی شما اجرای پایگاه داده داخل Docker یا مستقیم روی سرور است.

FAQ

آیا Supabase رایگان است؟

کد Supabase متن‌باز است و اجرای نسخه خودمیزبان روی سرور خودتان هزینه نرم‌افزاری ندارد. فقط هزینه سرور را می‌پردازید. Supabase Cloud یک پلن رایگان با محدودیت دارد و پلن‌های پولی آن به دلار آمریکا محاسبه می‌شوند. این محدودیت‌ها و قیمت‌ها تغییر می‌کنند. برای همین عدد دقیق را از صفحه قیمت‌گذاری یا یک مقایسه تاریخ‌دار بخوانید.

فرق Supabase با Firebase چیست؟

هر دو پایگاه داده، ورود کاربر، فضای فایل و توابع سمت سرور دارند. Firebase یک سرویس بسته گوگل با پایگاه داده سندمحور (NoSQL) است. Supabase روی PostgreSQL ساخته شده است. یعنی با جدول و SQL کار می‌کنید. کد Supabase هم متن‌باز است، پس می‌توانید آن را روی سرور خودتان اجرا کنید.

نسخه خودمیزبان Supabase چقدر RAM لازم دارد؟

مستندات رسمی Supabase (تا مهر ۱۴۰۵) حداقل ۴ گیگابایت RAM، ۲ هسته CPU و ۴۰ گیگابایت SSD را ذکر می‌کند و ۸ گیگابایت RAM با ۴ هسته را پیشنهاد می‌دهد. دلیلش این است که حدود ده سرویس جدا در کانتینرهای Docker اجرا می‌شوند. لاگ و آنالیتیکس در تنظیم پیش‌فرض خاموش‌اند تا حافظه کمتری مصرف شود.

آیا Supabase Cloud از داخل ایران کار می‌کند؟

پاسخ قطعی و ثابتی وجود ندارد و باید از شبکه کاربرانتان تست کنید. یک بار https://supabase.com و یک بار آدرس API پروژه روی supabase.co را با curl بررسی کنید. جدا از شبکه، بند Export Regulation در شرایط استفاده Supabase را هم بخوانید، چون Supabase یک شرکت آمریکایی است و ایران زیر تحریم آمریکاست. نسخه خودمیزبان روی سرور خودتان به هیچ‌کدام از این دو موضوع وابسته نیست.

آیا API خودکار Supabase امن است؟

امنیت آن به RLS بستگی دارد. کلیدی که در اپ قرار می‌گیرد عمومی است و درخواست‌ها با نقش anon یا authenticated اجرا می‌شوند. PostgreSQL با قانون‌های RLS تصمیم می‌گیرد هر نقش کدام سطرها را ببیند. جدولی در اسکیمای public که RLS آن خاموش است، برای هر کسی که کلید عمومی را دارد قابل خواندن است. پس RLS را برای هر جدول روشن کنید و برایش policy بنویسید.

#supabase#postgresql#backend-as-a-service#firebase-alternative#self-hosting